P4827 [国家集训队] Crash 的文明世界

传送门:洛谷

题目大意:设$$S(i)=\sum_{j=1}^ndis(i,j)^k$$,求$S(1),S(2),\ldots,S(n)$。

数据范围:$n\leq 50000,k\leq 150$


这道题,看见$k$次方和就直接上斯特林数。

$$S(x)=\sum_{i=0}^ki!S(k,i)\sum_{y=1}^nC_{dis(x,y)}^i$$

然后我们考虑求最后一项。

设$$up_{x,t}=\sum_{y\notin x}C_{dis(x,y)}^t,dn_{x,t}=\sum_{y\in x}C_{dis(x,y)}^t$$

我们先考虑$dn$。

$$dn_{x,t}=\sum_{(x,v)}\sum_{y\in v}C_{dis(v,y)+1}^t$$

$$=\sum_{(x,v)}\sum_{y\in v}(C_{dis(v,y)}^t+C_{dis(v,y)}^{t-1})$$

$$=\sum_{(x,v)}(dn_{v,t}+dn_{v,t-1})$$

然后考虑$up$

$$up_{x,t}=\sum_{v\notin fa}C_{dis(v,fa)+1}^t+\sum_{v\in fa}C_{dis(v,fa)+1}^t-\sum_{v\in x}C_{dis(v,x)+2}^t$$

$$=up_{fa,t}+up_{fa,t-1}+dn_{fa,t}+dn_{fa,t-1}-dn_{x,t}-2dn_{x,t-1}-dn_{x,t-2}$$

其中$up_{1,t}=0$

然后把式子直接输进去就可以了。

 1 #include<cstdio>
 2 #define Rint register int
 3 using namespace std;
 4 const int N = 50003, K = 153, mod = 10007;
 5 int n, k, head[N], to[N << 1], nxt[N << 1], S[K][K], fac[K];
 6 inline void add(int a, int b){
 7     static int cnt = 0;
 8     to[++ cnt] = b; nxt[cnt] = head[a]; head[a] = cnt;
 9 }
10 int dn[N][K], up[N][K];
11 inline void dfs1(int x, int f){
12     dn[x][0] = 1;
13     for(Rint i = head[x];i;i = nxt[i])
14         if(to[i] != f){
15             dfs1(to[i], x);
16             dn[x][0] = (dn[x][0] + dn[to[i]][0]) % mod;
17             for(Rint t = 1;t <= k;t ++)
18                 dn[x][t] = (dn[to[i]][t] + dn[to[i]][t - 1] + dn[x][t]) % mod;
19         }
20 }
21 inline void dfs2(int x, int f){
22     for(Rint i = head[x];i;i = nxt[i])
23         if(to[i] != f){
24             up[to[i]][0] = (up[x][0] + dn[x][0] - dn[to[i]][0] + mod) % mod;
25             up[to[i]][1] = (up[x][0] + up[x][1] + dn[x][0] + dn[x][1] - dn[to[i]][1] - 2 * dn[to[i]][0] + 3 * mod) % mod;
26             for(Rint t = 2;t <= k;t ++)
27                 up[to[i]][t] = (up[x][t] + up[x][t - 1] + dn[x][t] + dn[x][t - 1] - dn[to[i]][t] - 2 * dn[to[i]][t - 1] - dn[to[i]][t - 2] + 4 * mod) % mod;
28             dfs2(to[i], x);
29         }
30 }
31 int main(){
32     scanf("%d%d", &n, &k);
33     S[0][0] = 1;
34     for(Rint i = 1;i <= k;i ++)
35         for(Rint j = 1;j <= k;j ++)
36             S[i][j] = (S[i - 1][j - 1] + S[i - 1][j] * j) % mod;
37     fac[0] = 1;
38     for(Rint i = 1;i <= k;i ++) fac[i] = i * fac[i - 1] % mod;
39     for(Rint i = 1;i < n;i ++){
40         int a, b;
41         scanf("%d%d", &a, &b);
42         add(a, b); add(b, a);
43     }
44     dfs1(1, 0); dfs2(1, 0);
45     for(Rint x = 1;x <= n;x ++){
46         int ans = 0;
47         for(Rint i = 0;i <= k;i ++)
48             ans = (ans + fac[i] * S[k][i] % mod * (up[x][i] + dn[x][i]) % mod) % mod;
49         printf("%d\n", ans);
50     }
51 }

 

posted @ 2019-03-07 21:43  mizu164  阅读(199)  评论(0编辑  收藏  举报