闲得没事整理了一下,应该没什么大问题。

namespace Poly {
  il int Pow(int a,int b=p-2){
    int res=1;
    for(;b;a=(LL)a*a%p,b>>=1)if(b&1)res=(LL)res*a%p;
    return res;
  }
  int len,w[N];
  il void Init(int n){
    len=1;while(len<=n)len<<=1;
    for(int i=2;i<=len;i<<=1){
      int wn=Pow(g,(p-1)/i),m=i>>1;w[m]=1;
      for(int j=m+1;j<i;j++)w[j]=(LL)w[j-1]*wn%p;
    }
  }
  il void DFT(int *f,int len){
    for(int i=len;i>=2;i>>=1){
      int m=i>>1;
      for(int j=0;j<len;j+=i){
        for(int k=j,pw=m;k<j+m;k++,pw++){
          int x=f[k],y=f[k+m];
          f[k]=(x+y)%p,f[k+m]=(LL)w[pw]*(x-y+p)%p;
        }
      }
    }
  }
  il void IDFT(int *f,int len){
    for(int i=2;i<=len;i<<=1){
      int m=i>>1;
      for(int j=0;j<len;j+=i){
        for(int k=j,pw=m;k<j+m;k++,pw++){
          int x=f[k],y=(LL)w[pw]*f[k+m]%p;
          f[k]=(x+y)%p,f[k+m]=(x-y+p)%p;
        }
      }
    }
    reverse(f+1,f+len);int inv=Pow(len);
    for(int i=0;i<len;i++)f[i]=(LL)f[i]*inv%p;
  }
  int Tf[N],Tg[N];
  il void Mul(int *f,int *g,int *h,int n,int m){
    memset(Tf,0,sizeof Tf),memset(Tg,0,sizeof Tg);
    for(int i=0;i<=n;i++)Tf[i]=f[i];
    for(int i=0;i<=m;i++)Tg[i]=g[i];
    Init(n+m),DFT(Tf,len),DFT(Tg,len);
    for(int i=0;i<len;i++)Tf[i]=(LL)Tf[i]*Tg[i]%p;
    IDFT(Tf,len),memset(h,0,sizeof h);
    for(int i=0;i<=n+m;i++)h[i]=Tf[i];
  }
  int Ta[N],Tb[N];
  void Inv(int *f,int *g,int n){
    if(!n)return (void)(g[0]=Pow(f[0]));
    Inv(f,g,n>>1),Init(n+n);
    for(int i=0;i<=n;i++)Ta[i]=f[i],Tb[i]=g[i];
    for(int i=n+1;i<len;i++)Ta[i]=0,Tb[i]=0;
    DFT(Ta,len),DFT(Tb,len);
    for(int i=0;i<len;i++){
      g[i]=(LL)Tb[i]*(2-(LL)Ta[i]*Tb[i]%p+p)%p;
    }
    IDFT(g,len);for(int i=n+1;i<len;i++)g[i]=0;
  }
  il void Der(int *f,int *g,int n){
    memset(g,0,sizeof g);
    for(int i=1;i<=n;i++)g[i-1]=(LL)i*f[i]%p;
  }
  il void Int(int *f,int *g,int n){
    memset(g,0,sizeof g);
    for(int i=1;i<=n;i++)g[i]=(LL)f[i-1]*Pow(i)%p;
  }
  int Tc[N],Td[N],Te[N];
  void Ln(int *f,int *g,int n){
    Der(f,Tc,n),Inv(f,Td,n),Mul(Tc,Td,Te,n,n),Int(Te,g,n);
  }
  int Th[N],Ti[N],Tj[N];
  void Exp(int *f,int *g,int n){
    if(!n)return (void)(g[0]=1);
    Exp(f,g,n>>1),Ln(g,Tj,n),Init(n+n);
    for(int i=0;i<=n;i++)Th[i]=f[i],Ti[i]=g[i];
    DFT(Th,len),DFT(Ti,len),DFT(Tj,len);
    for(int i=0;i<len;i++){
      Ti[i]=(LL)Ti[i]*(1-Tj[i]+Th[i]+p)%p;
    }
    IDFT(Ti,len);for(int i=0;i<=n;i++)g[i]=Ti[i];
    for(int i=n+1;i<len;i++)g[i]=0;
  }
  int Fr[N],Gr[N],GrInv[N],Tk[N];
  void Divide(int *f,int *g,int n,int m,int *q,int *r){
    for(int i=0;i<=n;i++)Fr[n-i]=f[i];
    for(int i=0;i<=m;i++)Gr[m-i]=g[i];
    for(int i=n-m+1;i<=m;i++)Gr[i]=0;
    Inv(Gr,GrInv,n-m),Mul(Fr,GrInv,Fr,n,n-m);
    for(int i=0;i<=n-m;i++)q[i]=Fr[n-m-i];
    reverse(Fr,Fr+1+n-m),Mul(Fr,g,Fr,n-m,m);
    for(int i=0;i<m;i++)r[i]=(f[i]-Fr[i]+p)%p;
  }
}

相关文章: