第二类斯特林数·行

推式子


那么就转化为一个卷积形式 。那么 。用 优化一下,就变为 了。

代码

#include<bits/stdc++.h>
using namespace std;
const int N = 8e5 + 100,mod = 167772161;
int read() {int x;scanf("%d",&x);return x;}
int ksm(int a,int b) {
    int x = 1;for(;b;b>>=1,a=a*1ll*a%mod){
        if(b&1) x=x*1ll*a%mod;
    }return x;
} 
int f[N],g[N],r[N],fac[N],ifac[N],L,limit = 1;
void NTT(int *a,int type) {
    for(int i = 0;i < limit;i++)if(r[i]>i)swap(a[i],a[r[i]]);
    for(int mid = 1;mid < limit;mid <<= 1) {
        int wn = ksm(3,(mod - 1)/(mid << 1));
        for(int i = 0;i < limit;i += (mid<<1)) {                
            for(int j = 0,w = 1;j < mid;j++,w = w*1ll*wn%mod) {
//                cout << a[i + j] <<" " <<a[i + j + mid] << endl;
                int x = a[i + j],y = 1ll * w * a[i + j + mid] % mod;
                a[i + j] = (x + y) % mod;a[i + j + mid] = (x - y + mod) % mod;
            }
        }
    }if(type == -1) {
        reverse(a + 1,a + limit);int Inv = ksm(limit,mod - 2);
        for(int i = 0;i < limit;i++) a[i] = a[i] * 1ll * Inv % mod;
    }
}
int main() {
    int n = read();fac[0] = 1;
    for(int i = 1;i <= n;i++) fac[i] = fac[i - 1] * 1ll * i % mod;
    ifac[n] = ksm(fac[n],mod - 2);
    for(int i = n - 1;i >= 0;i--) ifac[i] = ifac[i + 1] * 1ll * (i + 1) % mod;
    for(int i = 0;i <= n;i++) {
        if(i & 1) f[i] = (-1ll * ifac[i] + mod) % mod;else f[i] = ifac[i];
        g[i] = ksm(i,n) * 1ll * ifac[i] % mod;
    }
    while(limit <= n + n) limit <<= 1,L++;
    for(int i = 0;i < limit;i++) r[i] = (r[i>>1]>>1)|((i&1)<<L-1);
    NTT(f,1);NTT(g,1);for(int i = 0;i < limit;i++) f[i] = f[i] * 1ll * g[i] % mod;
    NTT(f,-1);for(int i = 0;i <= n;i++) printf("%d ",f[i]);printf("\n");return 0;
}
数学 文章被收录于专栏

关于多项式

全部评论

相关推荐

点赞 评论 收藏
分享
4 收藏 评论
分享
牛客网
牛客企业服务