結果
| 問題 |
No.1103 Directed Length Sum
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2020-07-04 06:33:25 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 1,728 ms / 3,000 ms |
| コード長 | 5,397 bytes |
| コンパイル時間 | 3,105 ms |
| コンパイル使用メモリ | 203,856 KB |
| 最終ジャッジ日時 | 2025-01-11 15:25:00 |
|
ジャッジサーバーID (参考情報) |
judge3 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 22 |
ソースコード
#include <bits/stdc++.h>
#ifdef DEBUG
#include <Mylib/Debug/debug.cpp>
#else
#define dump(...)
#endif
/**
* @title Modint
* @docs mint.md
*/
template <uint32_t M> class ModInt{
public:
constexpr static uint32_t MOD = M;
uint64_t val;
constexpr ModInt(): val(0){}
constexpr ModInt(int64_t n){
if(n >= M) val = n % M;
else if(n < 0) val = n % M + M;
else val = n;
}
inline constexpr auto operator+(const ModInt &a) const {return ModInt(val + a.val);}
inline constexpr auto operator-(const ModInt &a) const {return ModInt(val - a.val);}
inline constexpr auto operator*(const ModInt &a) const {return ModInt(val * a.val);}
inline constexpr auto operator/(const ModInt &a) const {return ModInt(val * a.inv().val);}
inline constexpr auto& operator=(const ModInt &a){val = a.val; return *this;}
inline constexpr auto& operator+=(const ModInt &a){if((val += a.val) >= M) val -= M; return *this;}
inline constexpr auto& operator-=(const ModInt &a){if(val < a.val) val += M; val -= a.val; return *this;}
inline constexpr auto& operator*=(const ModInt &a){(val *= a.val) %= M; return *this;}
inline constexpr auto& operator/=(const ModInt &a){(val *= a.inv().val) %= M; return *this;}
inline constexpr bool operator==(const ModInt &a) const {return val == a.val;}
inline constexpr bool operator!=(const ModInt &a) const {return val != a.val;}
inline constexpr auto& operator++(){*this += 1; return *this;}
inline constexpr auto& operator--(){*this -= 1; return *this;}
inline constexpr auto operator++(int){auto t = *this; *this += 1; return t;}
inline constexpr auto operator--(int){auto t = *this; *this -= 1; return t;}
inline constexpr static ModInt power(int64_t n, int64_t p){
if(p < 0) return power(n, -p).inv();
int64_t ret = 1, e = n % M;
for(; p; (e *= e) %= M, p >>= 1) if(p & 1) (ret *= e) %= M;
return ret;
}
inline constexpr static ModInt inv(int64_t a){
int64_t b = M, u = 1, v = 0;
while(b){
int64_t t = a / b;
a -= t * b; std::swap(a,b);
u -= t * v; std::swap(u,v);
}
u %= M;
if(u < 0) u += M;
return u;
}
inline constexpr static auto frac(int64_t a, int64_t b){return ModInt(a) / ModInt(b);}
inline constexpr auto power(int64_t p) const {return power(val, p);}
inline constexpr auto inv() const {return inv(val);}
friend inline constexpr auto operator-(const ModInt &a){return ModInt(-a.val);}
friend inline constexpr auto operator+(int64_t a, const ModInt &b){return ModInt(a) + b;}
friend inline constexpr auto operator-(int64_t a, const ModInt &b){return ModInt(a) - b;}
friend inline constexpr auto operator*(int64_t a, const ModInt &b){return ModInt(a) * b;}
friend inline constexpr auto operator/(int64_t a, const ModInt &b){return ModInt(a) / b;}
friend std::istream& operator>>(std::istream &s, ModInt<M> &a){s >> a.val; return s;}
friend std::ostream& operator<<(std::ostream &s, const ModInt<M> &a){s << a.val; return s;}
template <int N>
inline static auto div(){
static auto value = inv(N);
return value;
}
explicit operator int32_t() const noexcept {return val;}
explicit operator int64_t() const noexcept {return val;}
};
using mint = ModInt<1000000007>;
/**
* @title Graph template
* @docs graph_template.md
*/
template <typename Cost = int> class Edge{
public:
int from,to;
Cost cost;
Edge() {}
Edge(int to, Cost cost): to(to), cost(cost){}
Edge(int from, int to, Cost cost): from(from), to(to), cost(cost){}
};
template <typename T> using Graph = std::vector<std::vector<Edge<T>>>;
template <typename T> using Tree = std::vector<std::vector<Edge<T>>>;
template <typename T, typename C> void add_edge(C &g, int from, int to, T w = 1){
g[from].emplace_back(from, to, w);
}
template <typename T, typename C> void add_undirected(C &g, int a, int b, T w = 1){
add_edge<T, C>(g, a, b, w);
add_edge<T, C>(g, b, a, w);
}
/**
* @title Fixed point combinator
* @docs fix_point.md
*/
template <typename F>
struct FixPoint : F{
explicit constexpr FixPoint(F &&f) noexcept : F(std::forward<F>(f)){}
template <typename... Args>
constexpr auto operator()(Args &&... args) const {
return F::operator()(*this, std::forward<Args>(args)...);
}
};
template <typename F>
inline constexpr auto make_fix_point(F &&f){
return FixPoint<F>(std::forward<F>(f));
}
template <typename F>
inline constexpr auto make_fix_point(F &f){
return FixPoint<F>(std::forward<F>(f));
}
int main(){
int N;
while(std::cin >> N){
Tree<int> tree(N);
std::vector<int> indeg(N);
for(int i = 0; i < N-1; ++i){
int a, b; std::cin >> a >> b;
--a, --b;
add_edge(tree, a, b, 1);
indeg[b] += 1;
}
int root = std::find(indeg.begin(), indeg.end(), 0) - indeg.begin();
std::vector<mint> sum(N);
std::vector<int> sub(N);
auto f =
make_fix_point(
[&](auto &&f, int cur) -> mint{
mint ret = 0;
sub[cur] = 1;
for(auto &e : tree[cur]){
ret += f(e.to);
sub[cur] += sub[e.to];
}
ret += sub[cur] - 1;
return sum[cur] = ret;
}
);
f(root);
auto ans = std::accumulate(sum.begin(), sum.end(), mint(0));
dump(sub, sum);
std::cout << ans << "\n";
}
return 0;
}