社区讨论

萌新求助多项式乘法

灌水区参与者 11已保存回复 44

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
44 条
当前快照
1 份
快照标识符
@lo8pzvfk
此快照首次捕获于
2023/10/27 22:40
2 年前
此快照最后确认于
2023/10/27 22:40
2 年前
查看原帖
萌新刚学 NTT,写了个 NTT 想过 P3803 怎么 TLE 了
同学看我 TLE 让我写 lambda 表达式,说这样写会快一些,但是我还是连样例都过不去!
CPP
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
template<typename T>inline void ckmax(T &x,T y){x=x<y?y:x;}
template<typename T>inline void ckmin(T &x,T y){x=x>y?y:x;}
template<typename T=int>inline T read(){
	T res=0,f=1; char k;
	while(!isdigit(k=getchar())) if(k=='-') f=-1;
	while(isdigit(k)) res=res*10+k-'0',k=getchar();
	return res*f;
}
template<typename T>inline void print(T x,bool fl=1){
	if(x<0) putchar('-'),x=-x; 
	if(x>=10) print(x/10,0);
	putchar(x%10+'0');
	if(fl) putchar(' ');
}
const int mod=998244353;
inline int add(int x,int y){return x+y>=mod?x+y-mod:x+y;}
inline int del(int x,int y){return x-y<0?x-y+mod:x-y;}
inline int mul(int x,int y){return x*y-x*y/mod*mod;}
inline void ckadd(int &x,int y){x=x+y>=mod?x+y-mod:x+y;}
inline void ckdel(int &x,int y){x=x-y<0?x-y+mod:x-y;}
inline void ckmul(int &x,int y){x=x*y-x*y/mod*mod;}
inline int ksm(int x,int y){int res=1; for(;y;y--) ckmul(res,x); return res;}
int main(){
	int n=read(),m=read();	
	vector<int> a,b;
	a.resize(n+1);
	b.resize(m+1);
	for(int i=0;i<=n;++i) a[i]=read();
	for(int i=1;i<=m;++i) b[i]=read();
	auto NTT=[&](vector<int> &f,int lim,int opt){
		f.resize(lim);
		vector<int> r(lim);
		for(int i=0;i<lim;++i){
			r[i]=r[i>>1]>>1|((i&1)?(lim>>1):0);
			if(i<r[i]) swap(f[i],f[r[i]]);
		}
		for(int p=2;p<=lim;p<<=1){
			int len=p>>1; 
			vector<int> W(len);
			W[0]=1; 
			if(len>1){
				W[1]=ksm(3,(mod-1)/p);
				if(opt==-1) W[1]=ksm(W[1],mod-2);
			}
			for(int j=2;j<len;++j) W[j]=mul(W[j-1],W[1]);
			for(int k=0;k<lim;k+=p){
				for(int l=k;l<k+len;++l){
					int tt=mul(f[l+len],W[l-k]);
					f[l+len]=del(f[l],tt);
					ckadd(f[l],tt);
				}
			}
		}
		if(opt==-1) for(int i=0,tmp=ksm(lim,mod-2);i<lim;++i) ckmul(f[i],tmp);
		return ;
			
	};
	int lim=1;
	while(lim<=n+m) lim<<=1;
	NTT(a,lim,1); NTT(b,lim,1);
	rep(i,0,lim-1) a[i]=mul(a[i],b[i]);
	NTT(a,lim,1);
	for(int i=0;i<=n+m;++i) print(a[i]); putchar('\n');
	return 0;
}

回复

44 条回复,欢迎继续交流。

正在加载回复...