多项式模板

多项式模板

多项式大全,支持\(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;
}

posted @ 2019-01-10 21:27  the_Despair  阅读(291)  评论(0编辑  收藏  举报