• BZOJ2159 Crash的文明世界(树形dp+斯特林数)


      根据组合意义,有nk=ΣC(n,i)*i!*S(k,i) (i=0~k),即将k个有标号球放进n个有标号盒子的方案数=在n个盒子中选i个将k个有标号球放入并且每个盒子至少有一个球。

      回到本题,可以令f[i][j]表示ΣC(dis(i,k),j) (k为i子树中节点),通过C(i,j)=C(i-1,j)+C(i-1,j-1)转移。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define N 50010
    #define K 155
    #define P 10007
    int n,m,l,now,A,B,Q,tmp,p[N],t=0;
    int f[N][K],S[K][K],fac[K],ans[N];
    struct data{int to,nxt;
    }edge[N<<1];
    void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
    void dfs(int k,int from)
    {
        f[k][0]=1;
        for (int i=p[k];i;i=edge[i].nxt)
        if (edge[i].to!=from)
        {
            dfs(edge[i].to,k);
            f[k][0]=(f[k][0]+f[edge[i].to][0])%P;
            for (int j=1;j<=m;j++)
            f[k][j]=(f[k][j]+f[edge[i].to][j]+f[edge[i].to][j-1])%P;
        }
    }
    void getans(int k,int from)
    {
        for (int j=0;j<=m;j++)
        ans[k]=(ans[k]+f[k][j]*fac[j]%P*S[m][j])%P;
        for (int i=p[k];i;i=edge[i].nxt)
        if (edge[i].to!=from)
        {
            for (int j=m;j>=2;j--)
            f[edge[i].to][j]=((f[k][j]-f[edge[i].to][j-1]+f[k][j-1]-f[edge[i].to][j-1]-f[edge[i].to][j-2])%P+P)%P;
            f[edge[i].to][1]=((f[k][1]-f[edge[i].to][0]+f[k][0]-f[edge[i].to][0])%P+P)%P;
            f[edge[i].to][0]=n;
            getans(edge[i].to,k);
        }
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj2159.in","r",stdin);
        freopen("bzoj2159.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        n=read(),m=read(),l=read(),now=read(),A=read(),B=read(),Q=read();
        for (int i=1;i<n;i++)
        {
            now=(now*A+B)%Q;
            tmp=(i<l)?i:l;
            int x=i-now%tmp,y=i+1;
            addedge(x,y),addedge(y,x);
        }
        dfs(1,1);
        fac[0]=1;for (int i=1;i<=m;i++) fac[i]=fac[i-1]*i%P;
        S[0][0]=1;
        for (int i=1;i<=m;i++)
            for (int j=1;j<=i;j++)
            S[i][j]=(S[i-1][j-1]+S[i-1][j]*j)%P;
        getans(1,1);
        for (int i=1;i<=n;i++) printf("%d
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    jquery实现选项卡(两句即可实现)
    常用特效积累
    jquery学习笔记
    idong常用js总结
    织梦添加幻灯片的方法
    LeetCode "Copy List with Random Pointer"
    LeetCode "Remove Nth Node From End of List"
    LeetCode "Sqrt(x)"
    LeetCode "Construct Binary Tree from Inorder and Postorder Traversal"
    LeetCode "Construct Binary Tree from Preorder and Inorder Traversal"
  • 原文地址:https://www.cnblogs.com/Gloid/p/9553291.html
Copyright © 2020-2023  润新知