奇怪的NTT
  • 板块学术版
  • 楼主嘉年华
  • 当前回复4
  • 已保存回复4
  • 发布时间2022/7/21 15:40
  • 上次更新2023/10/27 19:05:51
查看原帖
奇怪的NTT
85994
嘉年华楼主2022/7/21 15:40
#define mod 998244353
inline int add(int x,int y)
{
	int z=x+y;
	return z>=mod?z-mod:z;
}
inline int ast(int x,int y)
{
	ll z=1ll*x*y;
	return z>=mod?z%mod:z;
}
inline int pow(int a,int k)
{
	int as=1;
	while(k)
	{
		if(k&1) as=ast(as,a);
		a=ast(a,a);
		k>>=1;
	}
	return as;
}
int g=3,gi=332748118;
int r[maxn];
inline int mod_int(int x)
{
	if(x<0) return x+mod;
	if(x>=mod) return x-mod;
	return x;
}

inline void reverse(int lim,int l)
{
	static int his=-1;
	if(his==lim) return;
	for(int i=0;i<lim;++i) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
	his=lim;
}

inline void NTT(int *a,int lim,int op)
{
	for(int i=0;i<lim;++i) if(i<r[i]) swap(a[i],a[r[i]]);
	for(int mid=1,wn;mid<lim;mid<<=1)
	{
		wn=pow(op==1?g:gi,(mod-1)/(mid<<1));
		for(int j=0,w;j<lim;j+=(mid<<1))
		{
			w=1;
			for(int k=0,x,y;k<mid;++k,w=ast(w,wn))
				x=a[j+k],
				y=ast(w,a[j+k+mid]),
				a[j+k]=add(x,y),
				a[j+k+mid]=add(x,mod-y);
		}
			
	}	
}

inline void mul(int *a,int *b,int n,int m)
{
	int lim,l;
	for(lim=1,l=0;lim<=n+m;++l,lim<<=1);
	reverse(lim,l);
	NTT(a,lim,1),NTT(b,lim,1);
	for(int i=0;i<lim;++i) a[i]=ast(a[i],b[i]);
	NTT(a,lim,-1),NTT(b,lim,-1);
}

这个NTT算多项式相乘的答案会比正确的多出 2x2^x 倍,求dalao看看

比如输入

2 2
1 2 1
1 2 1

算出来是

8 32 48 32 8
2022/7/21 15:40
加载中...