[整理]多项式板子
闲得没事整理了一下,应该没什么大问题。
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;
}
}
内容来自_ajthreac_的博客(https://www.cnblogs.com/juruoajh/),未经允许,不得转载。