NTT求大佬优化
查看原帖
NTT求大佬优化
19607
ACAね楼主2020/5/30 11:53
/*
@Date    : 2020-05-29 22:24:25
@Author  : Adscn (adscn@qq.com)
@Link    : https://www.cnblogs.com/LLCSBlog
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define IL inline
#define RG register
#define gi geti<int>()
#define gl geti<ll>()
#define gc getchar()
#define File(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
template<typename T>IL bool chkmax(T &x,const T &y){return x<y?x=y,1:0;}
template<typename T>IL bool chkmin(T &x,const T &y){return x>y?x=y,1:0;}
template<typename T>
IL T geti()
{
	RG T xi=0;
	RG char ch=gc;
	bool f=0;
	while(!isdigit(ch))ch=='-'?f=1:f,ch=gc;
	while(isdigit(ch))xi=xi*10+ch-48,ch=gc;
	return f?-xi:xi;
}
template<typename T>
IL void pi(T k,char ch=0)
{
	if(k<0)k=-k,putchar('-');
	if(k>=10)pi(k/10);
	putchar(k%10+'0');
	if(ch)putchar(ch);
}
const int P=998244353,G=3,Gi=(P+1)/G;
inline void add(int &x,int y){x+=y;if(x>=P)x-=P;}
inline int add(int x){return x>=P?x-P:x;}
inline void sub(int &x,int y){x-=y;if(x<0)x+=P;}
inline int sub(int x){return x<0?x+P:x;}
inline ll fpow(ll a,int b,ll c=1){
	for(;b;b>>=1,a=a*a%P)if(b&1)c=c*a%P;
	return c;
}
inline int inv(int x){return fpow(x,P-2);}
inline int extend(int x){
	int n=1;
	while(n<x)n<<=1;
	return n;
}
typedef vector<int> Vec;
typedef unsigned long long ull;
inline void NTT(Vec &a,int opt){
	int n=a.size();
	Vec R(n);
	for(int i=0;i<n;++i)R[i]=R[i>>1]>>1|(i&1)*(n>>1);
	ll O=fpow(opt==1?G:Gi,(P-1)/n);
	for(int len=n>>1;len;len>>=1,O=O*O%P)
		for(int i=0;i<n;i+=(len<<1)){
			ll o=1;
			for(int j=0;j<len;++j,o=o*O%P){
				int Nx=a[i+j+len];
				a[i+j+len]=sub(a[i+j]-Nx)*o%P;
				add(a[i+j],Nx);
			}
		}
	for(int i=0;i<n;++i)if(i<R[i])swap(a[i],a[R[i]]);
}
inline void DFT(Vec &a){NTT(a,1);}
inline void IDFT(Vec &a){
	NTT(a,-1);
	int Inv=inv(a.size());
	for(auto &i:a)i=1ll*i*Inv%P;
}
Vec mul(Vec a,Vec b){
	int n=a.size()+b.size()-1,N=extend(n);
	a.resize(N),b.resize(N);
	DFT(a),DFT(b);
	for(int i=0;i<N;++i)a[i]=1ll*a[i]*b[i]%P;
	IDFT(a);
	return a.resize(n),a;
}
Vec operator * (Vec a,Vec b){return mul(a,b);}
Vec a,b;
int main(void)
{
	#ifndef ONLINE_JUDGE
//	File("");
	#endif	
	int n=gi,m=gi;
	a.resize(n+1),b.resize(m+1);
	for(int i=0;i<=n;++i)a[i]=gi;
	for(int i=0;i<=m;++i)b[i]=gi;
	a=a*b;
	for(auto i:a)pi(i,' ');
	return 0;
}
2020/5/30 11:53
加载中...