封装NTT

typedef long long ll;
const int MAXN=10000086;
namespace Poly{
	const int Gi=332748118,P=998244353,G=3;
	const double PI=acos(-1);
	int limit=1,rev[MAXN];
	ll quick_pow(ll x,ll k){
		ll base=1;
		while(k){
			if(k&1) base=(x*base)%P;
			x=(x*x)%P;
			k>>=1;
		}
		return base%P;
	}
	void NTT(ll *y,int type){
		for(int i=0;i<limit;++i) if(rev[i]>i) swap(y[i],y[rev[i]]);
		for(int len=1;len<limit;len<<=1){
			ll Wn=quick_pow((type==1)?G:Gi,(P-1)/(len<<1));
			for(int block=len<<1,j=0;j<limit;j+=block){
				ll w=1;
				for(int i=j;i<j+len;++i){
					ll t=w*y[i+len]%P;
					y[i+len]=(y[i]-t+P)%P;
					y[i]=(y[i]+t)%P;
					w=w*Wn%P;
				}
			}
		}
	}
	void times(int n,int m,ll *a,ll *b,ll *c){
		int L=0;
		while(limit<=n+m) limit<<=1,++L;
		for(int i=0;i<limit;++i) rev[i]=(rev[i>>1]>>1)|((i&1)*(1<<L-1));
		NTT(a,1);NTT(b,1);
		for(int i=0;i<=limit;++i) c[i]=a[i]*b[i]%P;
		NTT(c,-1);
		ll inv=quick_pow(limit,P-2);
		for(int i=0;i<=n+m;++i) c[i]=(c[i]*inv)%P;
		return;
	}
}
posted @ 2022-05-28 15:10  Mercury_City  阅读(50)  评论(0编辑  收藏  举报