zoukankan      html  css  js  c++  java
  • HDU4625 JZPTREE

    Description

    给定一棵 (n) 点树,边权为 (1)

    对于每个点 (x) ,求出

    [sum_{i=1}^n dis(x,i)^k ]

    [nle 50000,kle 500 ]

    Solution

    [n^k =sum_{i=0}^k inom n i imes S(k,i) imes i! ]

    所以答案推一步就成了

    [sum _ {i=1} ^n sum _ {j=0} ^k inom {dis(x,i)} j imes S(k,j) imes j! ]

    [sum_{j=0}^k S(k,j) imes j! sum_{i=1}^n inom {dis(x,i)} j ]

    所以我们要求啥?

    [sum _ {j=0}^ksum _ {i=1}^n inom {dis(x,i)} j ]

    这里组合数很难处理……如果转成距离统计空间会挂掉

    这里有个 (trick) :杨辉三角

    具体可以被写成:

    [f[x][i]=f[t][i]+f[t][i-1] ]

    Code

    #include<bits/stdc++.h>
    using namespace std;
    namespace yspm{
    	inline int read()
    	{
    		int res=0,f=1; char k;
    		while(!isdigit(k=getchar())) if(k=='-') f=-1;
    		while(isdigit(k)) res=res*10+k-'0',k=getchar();
    		return res*f;
    	}
    	const int N=50010,mod=10007;
    	struct node{
    		int to,nxt;
    	}e[N<<1];
    	int head[N],cnt,n,k;
    	inline void adde(int u,int v)
    	{
    		e[++cnt].to=v; e[cnt].nxt=head[u];
    		return head[u]=cnt,void();
    	}
    	inline int add(int x,int y){return x+y>=mod?x+y-mod:x+y;}
    	inline int del(int x,int y){return x-y>=0?x-y:x-y+mod;}
    	int f[N][510],s[510][510],fac[510];
    	inline void dfs1(int x,int fat)
    	{
    		for(int i=head[x];i;i=e[i].nxt)
    		{
    			int t=e[i].to; if(t==fat) continue; dfs1(t,x); 
    			f[x][0]=add(f[x][0],f[t][0]);
    			for(int j=1;j<=k;++j) f[x][j]=add(f[x][j],add(f[t][j],f[t][j-1]));
    		} ++f[x][0]; 
    		return ;
    	}
    	inline void dfs2(int x,int fa)
    	{
    		for(int i=head[x];i;i=e[i].nxt)
    		{
    			int t=e[i].to; if(t==fa) continue;
    			for(int j=k;j>=1;--j)
    			{
    				int r1=del(f[x][j],add(f[t][j],f[t][j-1]));
    				int r2=del(f[x][j-1],add(f[t][j-1],j>=2?f[t][j-2]:0));
    				f[t][j]=add(f[t][j],add(r1,r2));
    			} 
    			f[t][0]=add(f[t][0],del(f[x][0],f[t][0]));
    			dfs2(t,x);
    		} return ;
    	}
    	inline void work()
    	{
    		memset(e,0,sizeof(e)); memset(f,0,sizeof(f)); memset(head,0,sizeof(head)); cnt=0;
    		n=read(); k=read();
    		for(int i=1,u,v;i<n;++i) u=read(),v=read(),adde(u,v),adde(v,u);
    		dfs1(1,0); dfs2(1,0);
    		for(int i=1;i<=n;++i)
    		{
    			int ans=0;
    			for(int j=0;j<=k;++j) ans=add(ans,f[i][j]*fac[j]%mod*s[k][j]%mod);
    			cout<<ans<<endl;
    		} return ;
    	}
    	signed main()
    	{
    		s[1][1]=fac[0]=fac[1]=1; for(int i=1;i<=500;++i) s[i][1]=1,fac[i]=fac[i-1]*i%mod;  
    		for(int i=2;i<=500;++i)
    		{
    			for(int j=2;j<=i;++j) s[i][j]=add(s[i-1][j-1],s[i-1][j]*j%mod);
    		}
    		int T=read(); while(T--) work();
    		return 0;
    	}
    }
    signed main(){return yspm::main();}
    
  • 相关阅读:
    博客园设置简约主题
    day25-48
    day1-10
    drf app
    flask 框架 练习
    vue入门 显示数据 操作属性 操作样式 条件渲染
    flask 配置文件 路由 视图 模板 中间件
    flask 使用数据库连接池
    Android 工程中添加依赖
    apk反编译
  • 原文地址:https://www.cnblogs.com/yspm/p/13387603.html
Copyright © 2011-2022 走看看