bzoj 2159 Crash的文明世界

题目大意:

对每个点$x$ 求$\sum\limits_{i=1}^{n} {dis(i,j)}^k$

思路:

首先可以把式子展开得到$dis(i,j)^k=\sum\limits_{t=1}^k \binom{dis(i,j)}{t} S2(k,t)* t!$ ,$S2$为第二类斯特林数

因此对每个点 我们只需要求出$\sum\limits_{t=1}^k \sum\limits_{i=1}^n C_{dis(x,i)}^t $

而组合数有一个很好的性质$C(n,m)=C(n-1,m)+C(n-1,m-1)$

这样我们$dp$,$f(x,j)$表示子树内的$\sum C_{dis(x,v)}^j$按照组合数的性质很容易合并

然后我们再从上面继承其父亲子树外的点的与子树一样,考虑与它同级的其他点,用父亲的$f$减去之前用自己转移出的$fa$即可

即$g(x,i)+=f(fa,i)+f(fa,i-1)-f(x,i)-f(x,i-1)-f(x,i-1)-f(x,i-2)$

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<vector>
 9 #include<map>
10 #include<set>
11 #define ll long long
12 #define db double
13 #define inf 2139062143
14 #define MAXN 50100
15 #define MOD 10007
16 #define rep(i,s,t) for(register int i=(s),i##__end=(t);i<=i##__end;++i)
17 #define dwn(i,s,t) for(register int i=(s),i##__end=(t);i>=i##__end;--i)
18 #define ren for(register int i=fst[x];i;i=nxt[i])
19 #define pb(i,x) vec[i].push_back(x)
20 #define pls(a,b) (a+b)%MOD
21 #define mns(a,b) ((a-(b))%MOD+MOD)%MOD
22 #define mul(a,b) (1LL*(a)*(b))%MOD
23 using namespace std;
24 inline int read()
25 {
26     int x=0,f=1;char ch=getchar();
27     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
28     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
29     return x*f;
30 }
31 int n,m,L,las,A,B,Q,nxt[MAXN<<1],to[MAXN<<1],fst[MAXN],cnt;
32 int s[155][155],fac[155],f[MAXN][155],g[MAXN][155];
33 void add(int u,int v){nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
34 void dfs(int x,int pa)
35 {
36     f[x][0]=1;ren if(to[i]^pa) {dfs(to[i],x);
37         rep(j,0,m) f[x][j]=pls(f[x][j],f[to[i]][j]+(j?f[to[i]][j-1]:0));}
38 }
39 void Dfs(int x,int pa)
40 {
41     g[x][0]=n-f[x][0];rep(i,1,m) g[x][i]=mns(g[pa][i]+g[pa][i-1]+f[pa][i]+f[pa][i-1],
42         f[x][i]+f[x][i-1]*2+(i>1?f[x][i-2]:0));
43     ren if(to[i]^pa) Dfs(to[i],x);
44 }
45 int main()
46 {
47     n=read(),m=read(),L=read(),las=read(),A=read(),B=read(),Q=read();int a,b,x;
48     rep(i,2,n) las=(las*A+B)%Q,a=i-1-las%min(i-1,L),b=i,add(a,b),add(b,a);
49     s[1][1]=fac[1]=1;dfs(1,0);x=1;ren Dfs(to[i],x);int ans=0;
50     rep(i,2,m) {rep(j,1,i) s[i][j]=pls(s[i-1][j-1],j*s[i-1][j]);fac[i]=mul(fac[i-1],i);}
51     rep(i,1,n)
52     {
53         ans=0;rep(j,1,m) ans=pls(ans,mul(mul(fac[j],s[m][j]),f[i][j]+g[i][j]));
54         printf("%d\n",ans);
55     }
56 }
View Code

猜你喜欢

转载自www.cnblogs.com/yyc-jack-0920/p/10648478.html