NTT模板

多项式乘法

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mod=998244353;
const int maxn=1e5+10;
const int g=3;
int n,m,x,limit=1,rev[maxn<<2];
int A[maxn<<2],B[maxn<<2],C[maxn<<2];
inline int dec(int x,int y){return x-y<0?x-y+mod:x-y;}
inline int add(int x,int y){return x+y>=mod?x+y-mod:x+y;}
inline int mul(int x,int y){return (ll)x*y%mod;}
inline int quickpow(int a,int b,int ret=1){for(;b;b>>=1,a=mul(a,a)) if(b&1) ret=mul(ret,a);return ret;}
inline int read(){
	int x=0;char ch=getchar();
	while(!isdigit(ch)) ch=getchar();
	while(isdigit(ch)) x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
	return x;
}
inline void init(int lim){for(int i=0;i<lim;++i) rev[i]=(rev[i>>1]>>1)|((i&1)*(lim>>1));}
inline void NTT(int f[],int lim,int kd){
	for(int i=0;i<lim;++i) if(rev[i]>i) swap(f[i],f[rev[i]]);
	for(int mid=1;mid<lim;mid<<=1){
		int now=quickpow(g,(mod-1)/(mid<<1));
		for(int i=0;i<lim;i+=(mid<<1)){
			int w=1;
			for(int j=0;j<mid;++j,w=mul(w,now)){
				int p0=f[i+j],p1=mul(w,f[i+j+mid]);
				f[i+j]=add(p0,p1),f[i+j+mid]=dec(p0,p1);
			}
		}
	}
	if(kd==-1&&(reverse(f+1,f+lim),1))
		for(int i=0,inv=quickpow(lim,mod-2);i<lim;++i)
			f[i]=mul(f[i],inv);
}
int main(){
	n=read(),m=read();
	while(limit<=(n+m)) limit<<=1;init(limit);
	for(int i=0;i<=n;++i) A[i]=read();
	for(int i=0;i<=m;++i) B[i]=read();
	NTT(A,limit,1),NTT(B,limit,1);
	for(int i=0;i<limit;++i) C[i]=mul(A[i],B[i]);
	NTT(C,limit,-1); for(int i=0;i<=n+m;++i) printf("%d ",C[i]);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值