题解 P5007 【DDOSvoid 的疑惑】
Solution:
subtask 1:
直接
subtask 2:
定义
考虑如果
这个非常显然。考虑如果有多个儿子,我们定义
subtask 3:
其实跟点权为 1 的情况类似
定义
时间复杂度依然是
别忘了模数是 1e8 + 7
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cctype>
#include<cstring>
#define maxn 1000010
#define ll long long
#define gc getchar
using namespace std;
int n, m, T;
int w[maxn];
const int p = 100000007;
int read(){
int x = 0; char c = gc();
while(!isdigit(c)) c = gc();
while(isdigit(c)){x = x * 10 + c - '0'; c = gc();}
return x;
}
struct Edge{
int to, next;
}e[maxn * 2]; int c1, head[maxn];
inline void add_edge(int u, int v){
e[c1].to = v; e[c1].next = head[u]; head[u] = c1++;
}
ll f[maxn], g[maxn];
void dfs(int u, int fa){
for(int i = head[u]; ~i; i = e[i].next){
int v = e[i].to; if(v == fa) continue;
dfs(v, u);
f[u] = (f[u] * g[v] + f[v] * g[u] + f[u] + f[v]) % p;
g[u] = (g[u] * g[v] + g[u] + g[v]) % p;
}
f[u] = (f[u] + w[u]) % p; ++g[u];
}
int main(){
memset(head, -1, sizeof head);
n = read(); T = read();
for(int i = 1; i <= n; ++i) w[i] = T ? i : 1;
for(int i = 1; i < n; ++i){
int x = read(), y = read();
add_edge(x, y); add_edge(y, x);
}
dfs(1, 0); cout << f[1] << endl;
return 0;
}