萌新已经自闭了,不知道错在哪里。。。
NTT 是已经确认正确了的(是 he 到多项式乘法里面检查过的,如果你找出问题了当然可以说),应该就是求逆的问题。
目前有一个比较奇怪的点就是加注释的这一行更改 n<<1 的值变成 n<<2 和 n<<3 时的答案都不一样,其中 n<<2 可以拿到 5pts 。。。
代码是根据自己理解写的,但是对过了一两篇题解,好像没有什么问题,所以在这里求助一下。
#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;
}