多项式模板
多项式模板
多项式大全,支持\(NTT\)模数(模数不是mod,是yl(听说%神仙涨RP))。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int _=4e5+20,yl=998244353;
ll r[_],inv[_]={1,1};
ll POW(ll x,ll y){
ll s=1;
while(y){
if(y&1)s=s*x%yl;
x=x*x%yl;y>>=1;
}
return s;
}
void NTT(ll *p,int opt,int len){
for(int i=0,l=log2(len);i<len;++i){
r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
if(i<r[i])swap(p[i],p[r[i]]);
}
for(int i=1;i<len;i<<=1){
ll W=POW(3,(yl-1)/(i<<1));
if(opt==-1)W=POW(W,yl-2);
for(int j=0,s=i<<1;j<len;j+=s){
ll w=1;
for(int k=0;k<i;++k,w=w*W%yl){
ll X=p[j+k],Y=w*p[i+j+k]%yl;
p[j+k]=X+Y>=yl?X+Y-yl:X+Y;
p[i+j+k]=X>=Y?X-Y:X-Y+yl;
}
}
}
if(opt==-1){
ll inv=POW(len,yl-2);
for(int i=0;i<len;++i)p[i]=p[i]*inv%yl;
}
}
void Get_Mul(ll *a,ll *b,ll *c,int len){
static ll A[_],B[_];
memcpy(A,a,len<<3);memcpy(B,b,len<<3);
for(int i=len;i<len<<1;++i)A[i]=B[i]=0;
NTT(A,1,len<<1);NTT(B,1,len<<1);
for(int i=0;i<len<<1;++i)c[i]=A[i]*B[i]%yl;
NTT(c,-1,len<<1);
}
void Get_Inv(ll *a,ll *b,int len){
static ll A[_];
if(len==1)return b[0]=POW(a[0],yl-2),void();
Get_Inv(a,b,len>>1);
for(int i=0;i<len;++i)A[i]=a[i];
for(int i=len;i<(len<<1);++i)A[i]=0;
for(int i=len>>1;i<(len<<1);++i)b[i]=0;
NTT(A,1,len<<1);NTT(b,1,len<<1);
for(int i=0;i<(len<<1);++i)b[i]=(b[i]*2-A[i]*b[i]%yl*b[i]%yl+yl)%yl;
NTT(b,-1,len<<1);
}
void Get_Ln(ll *a,ll *b,int len){
static ll A[_];
for(int i=0;i<len;++i)A[i]=a[i+1]*(i+1)%yl;
Get_Inv(a,b,len);Get_Mul(A,b,b,len);
if(!inv[2])for(int i=2;i<_;++i)inv[i]=(yl-yl/i)*inv[yl%i]%yl;
for(int i=len-1;i;--i)b[i]=b[i-1]*inv[i]%yl;
b[0]=0;
}
void Get_Exp(ll *a,ll *b,int len){
static ll A[_];
if(len==1)return b[0]=1,void();
Get_Exp(a,b,len>>1);Get_Ln(b,A,len);
for(int i=0;i<len;++i)A[i]=(a[i]-A[i]+yl)%yl;
A[0]++;Get_Mul(A,b,b,len);
}
void Get_Sqrt(ll *a,ll *b,int len){
static ll A[_],B[_];
if(len==1)return b[0]=1,void();
Get_Sqrt(a,b,len>>1);Get_Inv(b,A,len);
for(int i=0;i<len;++i)B[i]=a[i];
Get_Mul(B,A,A,len);
if(!inv[2])for(int i=2;i<_;++i)inv[i]=(yl-yl/i)*inv[yl%i]%yl;
for(int i=0;i<len;++i)b[i]=(b[i]+A[i])*inv[2]%yl;
}
void Get_Mod(ll *a,ll *b,ll *c,int n,int m){
static ll A[_],B[_],C[_];
int len=1;while(len<=n)len<<=1;
reverse(a,a+n+1);reverse(b,b+m+1);
memcpy(A,a,len<<3);memcpy(B,b,len<<3);
Get_Inv(B,C,len);Get_Mul(A,C,C,len);
reverse(a,a+n+1);reverse(b,b+m+1);reverse(C,C+n-m+1);
for(int i=n-m+1;i<len;++i)C[i]=0;
memcpy(A,b,len<<3); Get_Mul(A,C,C,len);
for(int i=0;i<m;++i)c[i]=(a[i]-C[i]+yl)%yl;
}
int main(){
return 0;
}