zoukankan      html  css  js  c++  java
  • [国家集训队] Crash 的文明世界(第二类斯特林数)

    题目

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

    前置

    斯特林数(Longrightarrow)斯特林数及反演总结

    做法

    [egin{aligned} ans_x&=sumlimits_{i=1}^ndis(i,x)^k\ &=sumlimits_{i=1}^nsumlimits_{j=0}^kegin{Bmatrix}k\jend{Bmatrix}C_{dis(i,x)}^jj!\ &=sumlimits_{j=0}^kegin{Bmatrix}k\jend{Bmatrix}j!sumlimits_{i=1}^nC_{dis(i,x)}^j\ &=sumlimits_{j=0}^kegin{Bmatrix}k\jend{Bmatrix}j!sumlimits_{i=1}^n(C_{dis(i,x)-1}^j+C_{dis(i,x)-1}^{j-1}) end{aligned}]

    (f[x][j])表示(x)子树内,关于(x)(C_{dis(i,x)}^j)的答案

    显然有(f[x][j]=sumlimits_{son}f[son][j]+f[son][j-1])

    当这仅仅对于根有效,所以再做一遍换根(dp)

    Code

    #include<bits/stdc++.h>
    typedef int LL;
    const LL maxn=5e4+9,mod=10007,maxm=209;
    inline LL Read(){
        LL 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<<3)+(x<<1)+c-'0'; c=getchar();
        }
        return x*f;
    }
    struct node{
    	LL to,nxt;
    }dis[maxn<<1];
    LL n,num,K;
    LL head[maxn],dp1[maxn][maxm],dp2[maxn][maxm],strl[maxm][maxm],tmp[maxm],fac[maxm];
    inline void Add(LL u,LL v){
    	dis[++num]=(node){v,head[u]}; head[u]=num;
    }
    void Dfs1(LL u,LL f){
    	dp1[u][0]=1;
    	for(LL i=head[u];i;i=dis[i].nxt){
    		LL v(dis[i].to);
    		if(v==f) continue;
    		Dfs1(v,u);
    		for(LL j=1;j<=K;++j) dp1[u][j]=(dp1[u][j]+dp1[v][j]+dp1[v][j-1])%mod;
    		dp1[u][0]=(dp1[u][0]+dp1[v][0])%mod;
    	}
    }
    void Dfs2(LL u,LL f){
    	for(LL i=0;i<=K;++i) dp2[u][i]=dp1[u][i];
    	if(f){
    		for(LL i=1;i<=K;++i) tmp[i]=(dp2[f][i]-dp1[u][i]+mod-dp1[u][i-1]+mod)%mod;
    		tmp[0]=(dp2[f][0]-dp1[u][0]+mod)%mod;
    		for(LL i=1;i<=K;++i) dp2[u][i]=(dp2[u][i]+tmp[i]+tmp[i-1])%mod;
    		dp2[u][0]=(dp2[u][0]+tmp[0])%mod;
    	}
    	for(LL i=head[u];i;i=dis[i].nxt){
    		LL v(dis[i].to);
    		if(v==f) continue;
    		Dfs2(v,u);
    	}
    }
    int main(){
    	n=Read(); K=Read();
    	strl[0][0]=strl[1][1]=1;
    	for(LL i=2;i<=K;++i)
    	    for(LL j=1;j<=i;++j)
    	        strl[i][j]=(strl[i-1][j-1]+j*strl[i-1][j])%mod;
    	fac[0]=fac[1]=1;
    	for(LL i=2;i<=K;++i) fac[i]=fac[i-1]*i%mod;
    	for(LL i=1;i<n;++i){
    		LL u(Read()),v(Read());
    		Add(u,v); Add(v,u);
    	}
    	Dfs1(1,0); Dfs2(1,0);
    	for(LL i=1;i<=n;++i){
    		LL ret(0);
    		for(LL j=0;j<=K;++j) ret=(ret+1ll*strl[K][j]*fac[j]*dp2[i][j])%mod;
    		printf("%d
    ",ret);
    	}
    	return 0;
    }
    
  • 相关阅读:
    sharepoint更新
    生成Log日志文件.NET
    sharepoint绑定
    sharepoint多表查询
    数据库导入
    sharepoint插入数据
    协方差矩阵求解算法分析
    .NET提供的加密算法概述
    掩耳盗铃之使用WebBrowser封装网页
    C#委托BeginInvoke返回值乱序问题
  • 原文地址:https://www.cnblogs.com/y2823774827y/p/10712732.html
Copyright © 2011-2022 走看看