第二类斯特林数小结

前言

csdn又更新了,然后版面还不好看

第二类斯特林数

根据我个人的经验,我觉得第一类斯特林数暂时没什么用
所以这里只讨论第二类斯特林数
先是一般的递推式
S ( n , k ) = S ( n 1 , k 1 ) + S ( n 1 , k ) k
然后也有单个求的
S ( n , k ) = 1 k ! i = 0 k ( 1 ) i C k i ( m k ) n
然后一个比较常用的套路
因为我不会打下降幂,所以写成 f ( x )
x n = k = 0 n S ( n , k ) x f ( k )
然后还有一个技巧
就是
C ( x , k ) = x f ( k ) k !

一个题目

2159: Crash 的文明世界
就是用上面的式子展开一下就可以了。。
都是套路而已
如果实在不行,推荐一篇博客
但应该也是可以自己推出来的吧。。
CODE:

#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 JC[N];
int s[K][K];
int f[N][K];
void DP (int x,int fa)
{
    f[x][0]=1;
    for (int u=last[x];u!=-1;u=e[u].last)
    {
        int y=e[u].y;
        if (y==fa) 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 calc (int x,int y){return ((x-y)%MOD+MOD)%MOD;}
int g[K];
void dfs (int x,int fa)
{
    for (int u=last[x];u!=-1;u=e[u].last)
    {
        int y=e[u].y;
        if (y==fa) continue;
        g[0]=calc(f[x][0],f[y][0]);
        for (int i=1;i<=k;i++)
            g[i]=calc(f[x][i],f[y][i]+f[y][i-1]);
        f[y][0]=f[y][0]+g[0];
        for (int i=1;i<=k;i++)
            f[y][i]=(f[y][i]+g[i]+g[i-1])%MOD;
        for (int i=1;i<=k;i++)  ans[y]=(ans[y]+s[k][i]*JC[i]%MOD*f[y][i]%MOD)%MOD;
        dfs(y,x);
    }
}
int main()
{
    num=0;memset(last,-1,sizeof(last));
    int tL, tNOW, tA, tB, tC;
    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);
    }
    JC[0]=1;for (int u=1;u<=k;u++) JC[u]=JC[u-1]*u%MOD;
    s[0][0]=1;
    for (int u=1;u<=k;u++)
        for (int i=1;i<=k;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]*JC[u]%MOD*f[1][u]%MOD)%MOD;
    dfs(1,0);
    for (int u=1;u<=n;u++) printf("%d\n",ans[u]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_36797743/article/details/80100151