记录编号 370214 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [国家集训队 2011] Crash的文明世界 最终得分 100
用户昵称 Gravatar哒哒哒哒哒! 是否通过 通过
代码语言 C++ 运行时间 52.836 s
提交时间 2017-02-13 06:25:19 内存使用 32.18 MiB
显示代码纯文本
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <queue>
#include <ctime>
using namespace std;
#define ll long long 
int read(){
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
	return x*f;
}
const int maxn=50100;
const int mod=10007;
struct edge{int to,next;}e[maxn*2];
int tot,head[maxn];
void add(int u,int v){
	e[++tot]=(edge){v,head[u]};head[u]=tot;
}
int f[maxn],size[maxn],root,cnt,n,k;
bool vis[maxn];
#define to e[i].to
int pow[maxn][155],ans[maxn],C[155][155];
int dis[maxn],q[maxn],res,qq[maxn];
void get_root(int u,int fa){
	f[u]=0,size[u]=1;
	for(int i=head[u];i;i=e[i].next){
		if(vis[to]||to==fa)continue;
		get_root(to,u);
		size[u]+=size[to];
		f[u]=max(f[u],size[to]);
	}
	f[u]=max(f[u],cnt-size[u]);
	if(!root||f[u]<f[root]) root=u;
}
void get_dis(int u,int fa){
	q[++res]=dis[u],qq[res]=u;
	for(int i=head[u];i;i=e[i].next){
		if(vis[to]||to==fa)continue;
		dis[to]=dis[u]+1,get_dis(to,u);
	}
}
void calc(int u,int d,int flag){
	//if(u==2)printf("%d :: \n",u);
	dis[u]=d;res=0;get_dis(u,0);
	for(int j=0;j<=k;j++){
		int x=0;
		for(int i=1;i<=res;i++) x+=pow[q[i]][j]*C[k][j]%mod,x%=mod;
		for(int i=1;i<=res;i++){
			int y=(x-pow[q[i]][j]*C[k][j]%mod+mod)%mod;
			ans[qq[i]]=(ans[qq[i]]+flag*y*pow[q[i]][k-j]%mod+mod)%mod;
		}
	}
}
void dfs(int u){
	vis[u]=1;calc(u,0,1);
	for(int i=head[u];i;i=e[i].next){
		if(vis[to])continue;
		calc(to,1,-1);
		cnt=size[to],root=0;
		get_root(to,0),dfs(root);
	}
}
int main(){
	freopen("civilization.in","r",stdin);freopen("civilization.out","w",stdout);
	cnt=n=read(),k=read();
	int L=read(),now=read(),A=read(),B=read(),Q=read(),tmp;
	for(int i=1;i<n;i++){
		now=(now*A+B)%Q;
		tmp=(i<L)?i:L;
		int a=i-now %tmp,b=i+1;
		add(a,b);add(b,a);
	}

	if(k==0){
		for(int i=1;i<=n;i++)printf("%d\n",n-1);
		return 0;
	}
	pow[0][0]=1;
	for(int i=1;i<=n;i++){
		pow[i][0]=1;
		for(int j=1;j<=k;j++)
			pow[i][j]=(pow[i][j-1]*(i%mod))%mod;
	}
	C[1][0]=C[1][1]=1;
	for(int i=2;i<=k;i++){
		for(int j=0;j<=i;j++){
			if(j)C[i][j]+=C[i-1][j-1];
			C[i][j]+=C[i-1][j];
			C[i][j]%=mod;
		}
	}
	get_root(1,0);dfs(root);
	for(int i=1;i<=n;i++) printf("%d\n",ans[i]);
	fclose(stdin);fclose(stdout);
	return 0;
}