zoukankan      html  css  js  c++  java
  • 日常小测3.14

    题意难以描述,且需要授权,故不在此赘述。
    有一个很有趣的事情:怎么在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 }
  • 相关阅读:
    那些离不开的 Chrome 扩展插件
    Spring Boot 实战 —— 入门
    Maven 学习笔记
    Linux lvm 分区知识笔记
    Linux 双向 SSH 免密登录
    CentOS Yum 源搭建
    Ubuntu 系统学习
    iOS 测试三方 KIF 的那些事
    Swift 网络请求数据与解析
    iOS Plist 文件的 增 删 改
  • 原文地址:https://www.cnblogs.com/enigma-aw/p/6551341.html
Copyright © 2011-2022 走看看