题意难以描述,且需要授权,故不在此赘述。
有一个很有趣的事情:怎么在nlogn的时间内算出某一行的第二类斯特林数(即N确定求所有S(N,M))。
我们知道,第二类斯特林数的公式为:$ left{ egin{array}{l}{
m{n}}\mend{array}
ight} = frac{1}{{m!}}sumlimits_{k = 0}^m {{{( - 1)}^k}left( egin{array}{l}m\kend{array}
ight){{(m - k)}^n}} $
如果我们把阶乘给丢进去,会有:$ left{ egin{array}{l}{
m{n}}\mend{array}
ight} = sumlimits_{k = 0}^m {{{( - 1)}^k}frac{1}{{k!(m - k)!}}{{(m - k)}^n}} $
令$ f(k) = {( - 1)^k}frac{1}{{k!}}$ $ g(k) = frac{{{k^n}}}{{k!}} $
那么式子可以写成 $ sumlimits_{k = 0}^m {f(k)g(m - k)} $
那么就是一个卷积啦!NTT搞一发。
终于自己把NTT写了,以前一直没有写。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 #define N 400000 5 #define NN 200000 6 #define mod 786433 7 #define G 10 8 9 10 inline LL read(){ 11 LL x=0,f=1; char a=getchar(); 12 while(a<'0' || a>'9') {if(a=='-') f=-1; a=getchar();} 13 while(a>='0' && a<='9') x=x*10+a-'0',a=getchar(); 14 return x*f; 15 } 16 17 int T,n1,n2,m,q,fac[N],nfac[N],stir[N]; 18 int A[N],B[N],ans[N],pri[N]; 19 bool notpri[N]; 20 21 inline int fpow(int x,int k){ 22 int ret=1; 23 while(k){ 24 if(k&1) ret=1LL*ret*x%mod; 25 k>>=1; x=1LL*x*x%mod; 26 } 27 return ret; 28 } 29 30 inline void init(){ 31 fac[0]=1; for(int i=1;i<=NN;i++) fac[i]=1LL*fac[i-1]*i%mod; 32 nfac[NN]=fpow(fac[NN],mod-2); 33 for(int i=NN-1;i+1;i--) nfac[i]=1LL*nfac[i+1]*(i+1)%mod; 34 notpri[1]=1; 35 for(int i=2;i<=NN;i++){ 36 if(!notpri[i]) pri[++pri[0]]=i; 37 for(int j=1;j<=pri[0] && i*pri[j]<=NN;j++){ 38 notpri[i*pri[j]]=1; 39 if((i%pri[j])==0) break; 40 } 41 } 42 } 43 44 namespace NTT{ 45 int rev[N],wn[30]; 46 47 inline void getwn(){for(int t=1,i=2;t<21;i<<=1,t++) wn[t]=fpow(G,(mod-1)/i);} 48 49 inline void ntt(int* x,int len,int f){ 50 for(int i=1;i<=len;i++) if(i<rev[i]) swap(x[i],x[rev[i]]); 51 for(int lnow=2,t=1;lnow<=len;lnow<<=1,t++){ 52 for(int i=0;i<len;i+=lnow){ 53 int w=1; 54 for(int j=i;j<i+lnow/2;j++,w=1LL*w*wn[t]%mod){ 55 int u=x[j],v=1LL*w*x[j+lnow/2]%mod; 56 x[j]=u+v%mod; 57 x[j+lnow/2]=(u-v+mod)%mod; 58 } 59 } 60 } 61 if(f==-1){ 62 int inv=fpow(len,mod-2); 63 for(int i=len/2;i;i--) swap(x[i],x[len-i]); 64 for(int i=0;i<=len;i++) x[i]=1LL*x[i]*inv%mod; 65 } 66 } 67 68 inline void work(int* a,int* b,int l1,int l2,int* s){ 69 int len,t; 70 for(len=1,t=0;len<=(l1+l2+1);len<<=1,t++); t=1<<(t-1); 71 for(int i=1;i<=len;i++) rev[i]=rev[i>>1]>>1|(i&1?t:0); 72 ntt(a,len,1); ntt(b,len,1); 73 for(int i=0;i<=len;i++) a[i]=1LL*a[i]*b[i]%mod; 74 ntt(a,len,-1); 75 for(int i=0;i<=l1+l2;i++) s[i]=a[i]; 76 } 77 } 78 79 inline void prework(){ 80 memset(stir,0,sizeof(stir)); memset(A,0,sizeof(A)); 81 memset(ans,0,sizeof(ans)); memset(B,0,sizeof(B)); 82 for(int i=0;i<=n1;i++) A[i]=1LL*fpow(i,n1)*nfac[i]%mod; 83 for(int i=0;i<=n1;i++) B[i]=1LL*nfac[i]*(i&1?-1:1)%mod; 84 NTT::work(A,B,n1,n1,stir); 85 memset(A,0,sizeof(B)); memset(B,0,sizeof(B)); 86 for(int i=1;i<n1;i++) 87 A[i]=!notpri[i]?stir[i]:1LL*fac[n1]*nfac[n1-i+1]%mod*nfac[i-1]%mod; A[n1]=1; 88 for(int i=1;i<=min(n2,m);i++) 89 B[i]=1LL*fac[m]*nfac[m-i]%mod*nfac[i]%mod*fac[n2-1]%mod*nfac[i-1]%mod*nfac[n2-i]%mod; 90 NTT::work(A,B,n1,n2,ans); 91 } 92 93 int main(){ 94 init(); NTT::getwn(); 95 T=read(); 96 while(T--){ 97 n1=read(); n2=read(); m=read(); q=read(); 98 prework(); 99 while(q--) printf("%d ",(ans[read()]%mod+mod)%mod); 100 } 101 return 0; 102 }