[整理]多项式板子

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

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;
      rep(j, m+1, i-1)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);
    rep(i, 0, len-1)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);
    rep(i, 0, n)Tf[i]=f[i];
    rep(i, 0, m)Tg[i]=g[i];
    Init(n+m), DFT(Tf, len), DFT(Tg, len);
    rep(i, 0, len-1)Tf[i]=(LL)Tf[i]*Tg[i]%p;
    IDFT(Tf,len), memset(h,0,sizeof h);
    rep(i, 0, n+m)h[i]=Tf[i];
  }
  int Ta[N], Tb[N];
  void Inv(int *f, int *g, int n){
    if(!n)return g[0]=Pow(f[0]), void();
    Inv(f, g, n>>1), Init(n+n);
    rep(i, 0, n)Ta[i]=f[i], Tb[i]=g[i];
    rep(i, n+1, len-1)Ta[i]=Tb[i]=0;
    DFT(Ta, len), DFT(Tb, len);
    rep(i, 0, len-1){
      g[i]=(LL)Tb[i]*(2-(LL)Ta[i]*Tb[i]%p+p)%p;
    }
    IDFT(g, len); rep(i, n+1, len-1)g[i]=0;
  }
  il void Der(int *f, int *g, int n){
    memset(g, 0, sizeof g);
    rep(i, 1, n)g[i-1]=(LL)i*f[i]%p;
  }
  il void Int(int *f, int *g, int n){
    memset(g, 0, sizeof g);
    rep(i, 1, n)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 g[0]=1, void();
    Exp(f, g, n>>1), Ln(g, Tj, n), Init(n+n);
    rep(i, 0, n)Th[i]=f[i], Ti[i]=g[i];
    DFT(Th, len), DFT(Ti, len), DFT(Tj, len);
    rep(i, 0, len-1){
      Ti[i]=(LL)Ti[i]*(1-Tj[i]+Th[i]+p)%p;
    }
    IDFT(Ti, len); rep(i, 0, n)g[i]=Ti[i];
    rep(i, n+1, len-1)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){
    rep(i, 0, n)Fr[n-i]=f[i];
    rep(i, 0, m)Gr[m-i]=g[i];
    rep(i, n-m+1, m)Gr[i]=0;
    Inv(Gr, GrInv, n-m), Mul(Fr, GrInv, Fr, n, n-m);
    rep(i, 0, n-m)q[i]=Fr[n-m-i];
    reverse(Fr, Fr+1+n-m), Mul(Fr, g, Fr, n-m, m);
    rep(i, 0, m-1)r[i]=(f[i]-Fr[i]+p)%p;
  }
}
posted @ 2021-12-14 17:24  ajthreac  阅读(52)  评论(0编辑  收藏  举报