bzoj2159: Crash 的文明世界

首先先来画一下这个柿子

as(i)=sigema(1~n)j dis(i,j)^k

=sigema(1^n)j sigema(1~k)d S(k,d)*d!*C(dis(i,j),d)

=sigema(1~k)d S(k,d)*d! *sigema(1^n)j C(dis(i,j),d)

需要用脑子的就是sigema(1^n)j C(dis(i,j),d)了

设f[x][d]表示在x的子树内所有点到x的贡献

考虑从x的一个孩子y转移到x,所有的dis都加了1

有C(dis(x,j),d)=C(dis(y,j)+1,d)=C(dis(y,j),d)+C(dis(y,j),d-1)

所以f[x][d]+=f[y][d]+f[y][d-1]

然后二次扫描+换根即可

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
const int _=100;
const int maxn=5*1e4+_;
const int maxp=2*1e2+_;
const int mod=1e4+7;

int S[maxp][maxp],C[maxp][maxp],fac[maxp];
void yu()
{
    fac[0]=1;
    for(int i=1;i<maxp;i++)fac[i]=fac[i-1]*i%mod;
    
    S[0][0]=C[0][0]=1;
    for(int i=1;i<maxp;i++)
    {
        C[i][0]=1;
        for(int j=1;j<maxp;j++)
            S[i][j]=(S[i-1][j-1]+j*S[i-1][j])%mod,
            C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
    }
}

int n,p;
struct node
{
    int x,y,next;
}a[maxn*2];int len,last[maxn];
void ins(int x,int y)
{
    len++;
    a[len].x=x;a[len].y=y;
    a[len].next=last[x];last[x]=len;
}
int f[maxn][maxp];
void dfs(int x,int fr)
{
    f[x][0]=1;
    for(int k=last[x];k;k=a[k].next)
    {
        int y=a[k].y;
        if(y!=fr)
        {
            dfs(y,x);
            f[x][0]+=f[y][0];
            for(int i=1;i<=p;i++)
                f[x][i]=(f[x][i]+f[y][i]+f[y][i-1])%mod;
        }
    }
}
int as[maxn];
void changert(int x,int fr)
{
    for(int i=1;i<=p;i++)
        as[x]=(as[x]+S[p][i]*fac[i]%mod*f[x][i])%mod;
    
    for(int k=last[x];k;k=a[k].next)
    {
        int y=a[k].y;
        if(y!=fr)
        {
            f[x][0]-=f[y][0];
            for(int i=1;i<=p;i++)
                f[x][i]=((f[x][i]-f[y][i]-f[y][i-1])%mod+mod)%mod;
            f[y][0]+=f[x][0];
            for(int i=1;i<=p;i++)
                f[y][i]=(f[y][i]+f[x][i]+f[x][i-1])%mod;
                
            changert(y,x);
            
            f[y][0]-=f[x][0];
            for(int i=1;i<=p;i++)
                f[y][i]=((f[y][i]-f[x][i]-f[x][i-1])%mod+mod)%mod;
            f[x][0]+=f[y][0];
            for(int i=1;i<=p;i++)
                f[x][i]=(f[x][i]+f[y][i]+f[y][i-1])%mod;
        }
    }
}

int main()
{
     int L,now,A,B,C;
     int x,y;
    scanf("%d%d",&n,&p); len=1;
    scanf("%d%d%d%d%d",&L,&now,&A,&B,&C);
    for(int i=1;i<n;i++)
    {
        //scanf("%d%d",&x,&y);
        now=(now*A+B)%C;
        x=i-now%(i<L?i:L),y=i+1;
        ins(x,y);ins(y,x);
    }
    yu();
    dfs(1,0);
    changert(1,0);
    for(int i=1;i<=n;i++)printf("%d\n",as[i]);
    
    return 0;
}

 

posted @ 2019-01-28 15:30  AKCqhzdy  阅读(211)  评论(0编辑  收藏  举报