萌新刚学多项式,样例没过
查看原帖
萌新刚学多项式,样例没过
732229
GoldSilk楼主2022/8/15 19:32
#include<bits/stdc++.h>
#define int long long
using namespace std;
int const mod=998244353,G=3,Gi=332748118,inv2=499122177,M=1<<20;
int i,n,lim,a[M],b[M],c[M],d[M],e[M],rev[M];
int read(){
	int x=0;char ch=getchar();
	while (ch<'0'||ch>'9') ch=getchar();
	while (ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
	return x;
}
int Pow(int x,int n){
	int s=1;
	while (n){
		if (n&1) s=s*x%mod;
		x=x*x%mod;n>>=1;
	}
	return s;
}
void NTT(int *a,int n,int type){
	for (int i=0;i<n;i++)
		if (rev[i]>i) swap(a[i],a[rev[i]]);
	for (int i=1;i<n;i<<=1){	
		int x,y,Wn=Pow(type?G:Gi,(mod-1)/(i<<1));
		for (int j=0;j<n;j+=(i<<1))
			for (int w=1,k=0;k<i;w=w*Wn%mod,k++)
				x=a[j+k],y=w*a[i+j+k]%mod,
				a[j+k]=(x+y)%mod,a[i+j+k]=(x-y+mod)%mod;
	}
	return ;
}
void times(int *a,int *b,int n){
	for (int i=0;i<n;i++) rev[i]=(rev[i>>1]>>1)|((i&1)*(n>>1));
	NTT(a,n,1);NTT(b,n,1);
	for (int i=0;i<n;i++) a[i]=a[i]*b[i]%mod;
	NTT(a,n,0);int inv=Pow(n,mod-2);
	for (int i=0;i<n;i++) a[i]=a[i]*inv%mod;
	return ;
}
void Inv(int *a,int *b,int n){
	if (n==1) {b[0]=Pow(a[0],mod-2);return ;}
	Inv(a,b,n>>1);int lim=n<<1;
	for (int i=0;i<lim;i++) rev[i]=(rev[i>>1]>>1)|((i&1)*n);
	for (int i=0;i<n;i++) e[i]=a[i];
	for (int i=n;i<lim;i++) e[i]=0;
	NTT(b,lim,1);NTT(e,lim,1);
	for (int i=0;i<lim;i++) b[i]=(2-b[i]*e[i]%mod+mod)%mod*b[i]%mod;
	NTT(b,lim,0);int inv=Pow(lim,mod-2);
	for (int i=0;i<n;i++) b[i]=b[i]*inv%mod;
	for (int i=n;i<lim;i++) b[i]=0;
	return ;
}
void Sqrt(int *a,int *b,int n){
	if (n==1) {b[0]=1;return ;}
	Sqrt(a,b,n>>1);int lim=n<<1; Inv(b,c,lim);
	for (int i=0;i<n;i++) d[i]=a[i];
	for (int i=n;i<lim;i++) d[i]=0;
	times(c,d,lim); 
	for (int i=0;i<n;i++) b[i]=(b[i]+c[i])*inv2%mod;
	for (int i=n;i<lim;i++) b[i]=0;
	return ;
}
signed main(){
	n=read()-1;lim=1; 
	for (i=0;i<=n;i++) a[i]=read();
	while (lim<=n) lim<<=1;	Sqrt(a,b,lim);
	for (i=0;i<=n;i++) printf("%lld ",b[i]);
	return 0;
}

PS:函数 NTT,times,Inv都测过了,没问题

2022/8/15 19:32
加载中...