結果

問題 No.1075 木の上の山
ユーザー QCFiumQCFium
提出日時 2020-06-05 21:42:39
言語 C++14
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 65 ms / 2,000 ms
コード長 4,073 bytes
コンパイル時間 2,418 ms
コンパイル使用メモリ 183,024 KB
実行使用メモリ 23,424 KB
最終ジャッジ日時 2024-12-17 13:57:48
合計ジャッジ時間 4,094 ms
ジャッジサーバーID
(参考情報)
judge1 / judge5
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 2
other AC * 30
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

#include <bits/stdc++.h>
int ri() {
int n;
scanf("%d", &n);
return n;
}
#define MOD 1000000007
template<int mod>
struct ModInt{
int x;
ModInt():x(0){}
ModInt(long long y):x(y>=0?y%mod:(mod-(-y)%mod)%mod){}
ModInt &operator+=(const ModInt &p){
if((x+=p.x)>=mod)x-=mod;
return *this;
}
ModInt &operator-=(const ModInt &p){
if((x+=mod-p.x)>=mod)x-=mod;
return *this;
}
ModInt &operator*=(const ModInt &p){
x=(int)(1LL*x*p.x%mod);
return *this;
}
ModInt &operator/=(const ModInt &p){
*this*=p.inverse();
return *this;
}
ModInt &operator^=(long long p){
ModInt res = 1;
for (; p; p >>= 1) {
if (p & 1) res *= *this;
*this *= *this;
}
return *this = res;
}
ModInt operator-()const{return ModInt(-x);}
ModInt operator+(const ModInt &p)const{return ModInt(*this)+=p;}
ModInt operator-(const ModInt &p)const{return ModInt(*this)-=p;}
ModInt operator*(const ModInt &p)const{return ModInt(*this)*=p;}
ModInt operator/(const ModInt &p)const{return ModInt(*this)/=p;}
ModInt operator^(long long p)const{return ModInt(*this)^=p;}
bool operator==(const ModInt &p)const{return x==p.x;}
bool operator!=(const ModInt &p)const{return x!=p.x;}
explicit operator int() const { return x; } // added by QCFium
ModInt operator=(const int p) {x = p; return ModInt(*this);} // added by QCFium
ModInt inverse()const{
int a=x,b=mod,u=1,v=0,t;
while(b>0){
t=a/b;
a-=t*b;
std::swap(a,b);
u-=t*v;
std::swap(u,v);
}
return ModInt(u);
}
friend std::ostream &operator<<(std::ostream &os,const ModInt<mod> &p){
return os<<p.x;
}
friend std::istream &operator>>(std::istream &is,ModInt<mod> &a){
long long x;
is>>x;
a=ModInt<mod>(x);
return (is);
}
};
typedef ModInt<MOD> mint;
struct MComb {
std::vector<mint> fact;
std::vector<mint> inv;
MComb (int n) { // O(n + log(mod))
fact = std::vector<mint>(n + 1, 1);
for (int i = 1; i <= n; i++) fact[i] = fact[i - 1] * mint(i);
inv.resize(n + 1);
inv[n] = fact[n] ^ (MOD - 2);
for (int i = n; i--; ) inv[i] = inv[i + 1] * mint(i + 1);
}
mint ncr(int n, int r) {
return fact[n] * inv[r] * inv[n - r];
}
mint npr(int n, int r) {
return fact[n] * inv[n - r];
}
mint nhr(int n, int r) {
assert(n + r - 1 < (int) fact.size());
return ncr(n + r - 1, r);
}
};
std::vector<std::vector<int> > hen;
int k;
std::vector<mint> merge(const std::vector<mint> &l, const std::vector<mint> &r) {
int n = l.size();
std::vector<mint> res(n);
mint suml = 0, sumr = 0;
for (int i = 0; i < k; i++) {
suml += l[i];
sumr += r[i];
res[i] += suml * r[i];
res[i] += sumr * l[i];
res[i] -= l[i] * r[i];
}
return res;
}
mint res;
std::vector<std::vector<mint> > subtree;
void dfs0(int i, int prev) {
if (prev != -1) hen[i].erase(std::find(hen[i].begin(), hen[i].end(), prev));
subtree[i].resize(k);
subtree[i][0] = 1;
for (auto j : hen[i]) {
dfs0(j, i);
subtree[i] = merge(subtree[i], subtree[j]);
}
for (int j = 0; j + 1 < k; j++) subtree[i][j + 1] += subtree[i][j];
}
void dfs1(int i, int prev, const std::vector<mint> &par_dp) {
int m = hen[i].size();
mint sumed = 0;
for (int j = 0; j < k; j++) {
res += subtree[i][j] * (prev == -1 ? 1 : sumed);
if (prev != -1) sumed += par_dp[j];
}
if (m) {
std::vector<std::vector<mint> > left(m);
std::vector<std::vector<mint> > right(m);
std::vector<mint> tmp(k);
tmp[0] = 1;
left.front() = right.back() = tmp;
for (int j = 0; j + 1 < m; j++) left[j + 1] = merge(left[j], subtree[hen[i][j]]);
for (int j = m; --j; ) right[j - 1] = merge(right[j], subtree[hen[i][j]]);
for (int j = 0; j < m; j++) {
auto tmp = merge(merge(left[j], right[j]), par_dp);
for (int l = 0; l + 1 < k; l++) tmp[l + 1] += tmp[l];
dfs1(hen[i][j], i, tmp);
}
}
}
int main() {
int n = ri();
k = ri();
hen.resize(n);
for (int i = 1; i < n; i++) {
int a = ri() - 1;
int b = ri() - 1;
hen[a].push_back(b);
hen[b].push_back(a);
}
subtree.resize(n);
dfs0(0, -1);
std::vector<mint> tmp(k);
tmp[0] = 1;
dfs1(0, -1, tmp);
std::cout << res << std::endl;
return 0;
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0