这个博客已经更新:新的文章
前言
今天在复习初赛。。
复习排列组合。。
发现斯特林数没学过TAT
于是就去学了一发。。
教程我就不写了。。
于是就来做题了。。
题意
你就看题面那张图就可以了
题解
对于要输出n个数的题我都不是很会做。。
于是就%题解了
真的牛逼。。我觉得他已经讲得很清楚了
至于那个用下降幂表示通常幂,具体数学那本书的斯特林数上面有证明。。
一开始我还不知道在证明什么东西,做了这题才知道
证明斯特林数就是他的系数。。
然后转换一下,就可以变成C了。。
差不多搬运了个代码:
#include<cstdio>
#include<cstring>
const int N=50005*2;
const int K=155;
const int MOD=10007;
int n,k;
struct qq
{
int x,y,last;
}e[N];int num,last[N];
void init (int x,int y)
{
num++;
e[num].x=x;e[num].y=y;
e[num].last=last[x];
last[x]=num;
}
int fac[K];//阶乘?
int S[K][K];//斯特林数
int f[N][K];
void DP (int x,int ff)
{
f[x][0]=1;
for (int u=last[x];u!=-1;u=e[u].last)
{
int y=e[u].y;
if (y==ff) continue;
DP(y,x);
f[x][0]=(f[x][0]+f[y][0])%MOD;
for (int i=1;i<=k;i++)
f[x][i]=(f[x][i]+(f[y][i]+f[y][i-1])%MOD)%MOD;
}
}
int ans[N];
int g[K],h[K];
int jian (int x,int y)
{
return ((x-y)%MOD+MOD)%MOD;
}
void calc (int x,int ff)
{
for (int u=last[x];u!=-1;u=e[u].last)
{
int y=e[u].y;
if (y==ff) continue;
g[0]=f[x][0];
g[0]=jian(g[0],f[y][0]);
h[0]=n;
for (int i=1;i<=k;i++)
{
g[i]=f[x][i];
g[i]=jian(g[i],f[y][i]+f[y][i-1]);
h[i]=(f[y][i]+g[i]+g[i-1])%MOD;
}
for (int i=0;i<=k;i++)
f[y][i]=h[i];
for (int i=1;i<=k;i++)
ans[y]=(ans[y]+S[k][i]*fac[i]%MOD*h[i]%MOD)%MOD;
calc(y,x);
}
}
int main()
{
int tL, tNOW, tA, tB, tC;
num=0;memset(last,-1,sizeof(last));
scanf("%d%d",&n,&k);
scanf("%d%d%d%d%d",&tL,&tNOW,&tA,&tB,&tC);
for (int u=1;u<n;u++)
{
int x,y;
//scanf("%d%d",&x,&y);
tNOW=(tNOW*tA+tB)%tC;
x=u-tNOW%(u<tL?u:tL), y=u+1;
init(x,y);init(y,x);
}
fac[0]=1;
for (int u=1;u<=k;u++)
fac[u]=(fac[u-1]*u)%MOD;
S[0][0]=1;
for (int u=1;u<=k;u++)
for (int i=1;i<=u;i++)
S[u][i]=(S[u-1][i-1]+S[u-1][i]*i%MOD)%MOD;
DP(1,0);
for (int u=1;u<=k;u++)
ans[1]=(ans[1]+S[k][u]*fac[u]%MOD*f[1][u]%MOD)%MOD;
calc(1,0);
for (int u=1;u<=n;u++) printf("%d\n",ans[u]);
return 0;
}