萌新求助
查看原帖
萌新求助
72468
「 」楼主2021/2/5 20:20

萌新已经自闭了,不知道错在哪里。。。

NTTNTT 是已经确认正确了的(是 he 到多项式乘法里面检查过的,如果你找出问题了当然可以说),应该就是求逆的问题。

目前有一个比较奇怪的点就是加注释的这一行更改 n<<1 的值变成 n<<2n<<3 时的答案都不一样,其中 n<<2 可以拿到 5pts5pts 。。。

代码是根据自己理解写的,但是对过了一两篇题解,好像没有什么问题,所以在这里求助一下。

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=6e5+5;
const int MOD=998244353;
int ksm(int x,int k){
	int res=1;
	for(;k;k>>=1,x=x*x%MOD)
	if(k&1) res=res*x%MOD;
	return res;
}
struct Polynomial{
	int n,a[N],rev[N];
	int &operator [] (const int &id){return a[id];}
	Polynomial(){n=0,memset(a,0,sizeof(a)),memset(rev,0,sizeof(rev));}
	void NTT(int n,bool inv){
		int lg=0;while((1<<lg)<n) lg++;
		for(int i=0;i<n;++i) rev[i]=((rev[i>>1]>>1)|((i&1)<<(lg-1)));
		for(int i=0;i<n;++i) if(i<rev[i]) swap(a[i],a[rev[i]]);
		for(int len=2;len<=n;len<<=1){
			int m=(len>>1),g=ksm(3,(MOD-1)/len);
			if(inv) g=ksm(g,MOD-2);
			for(int *b=a;b!=a+n;b+=len){
				for(int i=0,G=1;i<m;++i,G=G*g%MOD){
					int tmp=G*b[i+m]%MOD;
					b[i+m]=(b[i]-tmp+MOD)%MOD;
					b[i]=(b[i]+tmp)%MOD;
				}
			}
		}
		if(!inv) return ;
		int tmp=ksm(n,MOD-2);
		for(int i=0;i<n;++i) a[i]=a[i]*tmp%MOD;
	}
}f,g;
void inv(int n,Polynomial &f,Polynomial &g){
	if(n==1){g.n=1,g[0]=ksm(f[0],MOD-2);return ;}
	inv((n+1)>>1,f,g);int m=1;
	while(m<(n<<1)) m<<=1;////////////////////////////////////////
	// printf("%lld %lld\n",n,m);
	static Polynomial h=f;h.n=n;
	for(int i=h.n;i<m;++i) h[i]=0;
	h.NTT(m,false),g.NTT(m,false);
	for(int i=0;i<m;++i){
		g[i]=(2*g[i]%MOD-h[i]*g[i]%MOD*g[i]%MOD+MOD)%MOD;
	}
	g.NTT(m,true),g.n=n;
	for(int i=g.n;i<m;i++) g[i]=0;
	// for(int i=0;i<g.n;++i) printf("%lld ",g[i]);
	// printf("\n");
}
signed main(){
	cin>>f.n;
	for(int i=0;i<f.n;++i) scanf("%lld",&f[i]);
	inv(f.n,f,g);
	for(int i=0;i<g.n;++i) printf("%lld ",g[i]);
	printf("\n");
	return 0;
}
2021/2/5 20:20
加载中...