题意:如其名……

思路:

多项式的关键在于:用模的次数降次。
它的复杂度跟模数的次幂有关。
所以可以考虑对模数分治参考
若多项式F只有一项,直接求常数项的逆元(这也是判别多想式是否存在逆元的条件)。
设已知 F(x)H(x)1(modxn2)
F(x)G(x)1(modxn2)
所以G(x)H(x)0(modxn2)
两边平方得:G(x)2+H(x)22G(x)H(x)0(modxn)
因为把平方看成两个多项式相乘 j=0i(G(x)H(x))j(G(x)H(x))ij
G(x)H(x)xn20,即它的最小系数非负次数为n2
当然分成的jij必有一个小于n2
因此两边同乘F(x),根据F(x)G(x)1(modxn)得:
G(x)2H(x)F(x)H(x)2(modxn)

code:

ouo
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5;
const ll mod=998244353;
ll ksm(ll a,ll b) {ll res=1;for(;b;b>>=1,a=a*a%mod)if(b&1)res=res*a%mod;return res;}
//ll ksm(ll x,ll y) {ll res=1;for(;y;y>>=1,x=x*x%mod)if(y&1)res=res*x%mod;return res;}
ll f[N],a[N],c[N],inv3,gen[2][N];
int up,l,rev[N],n;
void NTT(ll *a,int op) {
	for(int i=0;i<up;i++) {
		if(rev[i]>i)swap(a[i],a[rev[i]]);
	}
	for(int mid=1;mid<up;mid<<=1) {
		int len=mid<<1;ll w1=gen[op][len];
//		printf("!(%d,%d) %lld (%lld,%lld)\n",op,len,(w1+mod)%mod,ksm(3,(mod-1)/len),ksm(inv3,(mod-1)/len));
 		for(int l=0;l<up;l+=len) {
 			ll W=1;
			for(int i=0;i<mid;i++,W=W*w1%mod) {
				int p=l+i,q=p+mid;
				ll x=a[p],y=W*a[q];
				a[p]=(x+y)%mod;a[q]=(x-y)%mod;
			}
		}
	}
}

void gt_up(int len) {
	up=1,l=0;
	while(up<len) {up<<=1,l++;}
	for(int i=1;i<up;i++) {rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1));}
}
ll ans[N];
void solve(int dep,ll *b) {	//b为该层(%x^{dep})得到的结果 
	if(dep==1) {b[0]=ksm(f[0],mod-2);return;}
	solve((dep+1)>>1,b);
	gt_up(dep<<1);
//	printf("dep=%d up=%d~~\n",dep,up);
	for(int i=0;i<dep;i++)a[i]=f[i];for(int i=dep;i<up;i++)a[i]=0;
	NTT(b,0);NTT(a,0);
//	printf("A:\n");for(int i=0;i<up;i++)printf("%d ",(a[i]%mod+mod)%mod);puts("");
//	printf("B:\n");for(int i=0;i<up;i++)printf("%d ",(b[i]%mod+mod)%mod);puts("");
	for(int i=0;i<up;i++) {c[i]=(2-a[i]*b[i]%mod)*b[i]%mod;}
	NTT(c,1);
	ll i_up=ksm(up,mod-2);
	for(int i=0;i<dep;i++) {b[i]=c[i]*i_up%mod;} for(int i=dep;i<up;i++)b[i]=0;
//	printf("S:\n");for(int i=0;i<up;i++)printf("%d ",(b[i]%mod+mod)%mod);puts("");
}
void gt_gen() {
	inv3=ksm(3,mod-2);
	gt_up(n<<1);
//	printf("!%d\n",up);
	gen[0][up]=ksm(3,(mod-1)/up);gen[1][up]=ksm(inv3,(mod-1)/up);
	for(int i=up;i;i>>=1) {
//		printf("i=%d %lld(%lld),%lld(%lld)\n",i,gen[0][i],ksm(3,(mod-1)/i),gen[1][i],ksm(inv3,(mod-1)/i));
		gen[0][i>>1]=gen[0][i]*gen[0][i]%mod;
		gen[1][i>>1]=gen[1][i]*gen[1][i]%mod;
	}
}
int main() {
	scanf("%d",&n);
	gt_gen();
	for(int i=0;i<n;i++) {scanf("%lld",&f[i]);}
	solve(n,ans);
	for(int i=0;i<n;i++) {printf("%lld ",(ans[i]+mod)%mod);}
	return 0;
}

ps.还有柯爱的
code:板套板,不会mtt,注意拆的系数最好p,我随便用的114514它精度就G了。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double db;
const db pi=acos(-1.0);
const int N=1e6+5;
const ll mod=1e9+7;

ll ksm(ll a,ll b) {ll res=1;for(;b;b>>=1,a=a*a%mod)if(b&1)res=res*a%mod;return res;}
ll f[N],a[N],c[N],bas=sqrt(mod);
int up,l,rev[N],n;

struct cop {
	db img,rl;
	friend inline cop operator*(cop u,cop v) {return (cop){u.rl*v.img+u.img*v.rl,u.rl*v.rl-u.img*v.img};} 
	friend inline cop operator+(cop u,cop v) {return (cop){u.img+v.img,u.rl+v.rl};}
	friend inline cop operator-(cop u,cop v) {return (cop){u.img-v.img,u.rl-v.rl};}
}A[N],B[N],C[N],D[N],AC[N],BD[N],ABC[N];

void FFT(cop *a,int op) {
	for(int i=0;i<up;i++)if(rev[i]>i)swap(a[i],a[rev[i]]);
	for(int mid=1;mid<up;mid<<=1) {
		cop w1=(cop){op*sin(pi/mid),cos(pi/mid)};
		for(int len=mid<<1,l=0;l<up;l+=len) {
			cop W=(cop){0,1};
			for(int i=0;i<mid;i++,W=W*w1) {
				int p=l+i,q=p+mid;
				cop x=a[p],y=W*a[q];
				a[p]=x+y;a[q]=x-y;
			}
		}
	}
}

void gt_up(int len) {
	up=1,l=0;
	while(up<len) {up<<=1,l++;}
	for(int i=1;i<up;i++) {rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1));}
}
ll ans[N];

void Mul(ll *f,ll *g) {
	for(int i=0;i<up;i++) {
		A[i]=(cop){0,f[i]/bas};B[i]=(cop){0,f[i]%bas};
		C[i]=(cop){0,g[i]/bas};D[i]=(cop){0,g[i]%bas};
	}
	FFT(A,-1),FFT(B,-1),FFT(C,-1),FFT(D,-1);
	for(int i=0;i<up;i++) {
		AC[i]=A[i]*C[i],ABC[i]=A[i]*D[i]+B[i]*C[i],BD[i]=B[i]*D[i];
	}
	FFT(AC,1),FFT(ABC,1),FFT(BD,1);
	for(int i=0;i<up;i++) {
		ll ac=(ll)round(AC[i].rl/up)%mod,abc=(ll)round(ABC[i].rl/up)%mod,bd=(ll)round(BD[i].rl/up)%mod;
		f[i]=(ac*bas%mod*bas+abc*bas+bd)%mod;
	}
}
void pw_Mul(ll *f) {
	for(int i=0;i<up;i++) {
		A[i]=(cop){0,f[i]/bas};B[i]=(cop){0,f[i]%bas};
	}
	FFT(A,-1),FFT(B,-1);
	for(int i=0;i<up;i++) {
		AC[i]=A[i]*A[i];ABC[i]=A[i]*B[i];BD[i]=B[i]*B[i];
	}
	FFT(AC,1),FFT(ABC,1),FFT(BD,1);
	for(int i=0;i<up;i++) {
		ll ac=(ll)round(AC[i].rl/up)%mod,abc=(ll)round(ABC[i].rl/up)%mod,bd=(ll)round(BD[i].rl/up)%mod;
		f[i]=(ac*bas%mod*bas+2*abc*bas%mod+bd)%mod;
//		printf("%lld ",(f[i]%mod+mod)%mod);
	}
//	puts(""); 
}

void solve(int dep,ll *b) {	 //b为该层(%x^{dep})得到的结果 
	if(dep==1) {b[0]=ksm(f[0],mod-2);return;}
	solve((dep+1)>>1,b);
	gt_up(dep<<1);
	for(int i=0;i<up;i++)c[i]=b[i],a[i]=(i<dep)?f[i]:0;
	pw_Mul(c);
	for(int i=dep;i<up;i++)c[i]=0;
	Mul(a,c);
	for(int i=0;i<dep;i++) {
		b[i]=(2*b[i]-a[i])%mod;
		if(b[i]<mod)b[i]+=mod;
	}
//	printf("S:\n");
//	for(int i=0;i<up;i++)printf("%lld ",(b[i]+mod)%mod);puts("");
}

int main() {
//	freopen("P4239_16.in","r",stdin);
//	freopen("ans.out","w",stdout);
	scanf("%d",&n);
	for(int i=0;i<n;i++) {scanf("%lld",&f[i]);}
	solve(n,ans);
	for(int i=0;i<n;i++) {printf("%lld ",(ans[i]+mod)%mod);}
	return 0;
}

注意
%.0lf以及浮点型转整形,是保留整数;除法不是下取整是向〇取整;四舍五入直接用round,负数就不能+0.5要-0.5转整型。