萌新求助多项式
  • 板块学术版
  • 楼主ReqCxmChtChr
  • 当前回复2
  • 已保存回复2
  • 发布时间2022/12/29 19:02
  • 上次更新2023/10/24 06:11:59
查看原帖
萌新求助多项式
421451
ReqCxmChtChr楼主2022/12/29 19:02

P5205,实际上过了,但是必须要开O2才能过,希望有大佬可以指出哪里可以优化。

代码:

#include<bits/stdc++.h>
using namespace std;
#define MAXN 600001
#define MAXM 1
#define ll long long
#define big __int128
#define type_ int
#define htype_ big
#define re register
#define G 3
inline void qr(type_ &res) {re type_ fh=1;res=0;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')fh=-1;for(;isdigit(ch);ch=getchar())res=(res<<3)+(res<<1)+(ch^'0');res=res*fh;}
inline type_ qp(type_ a,type_ b,type_ mod){
	type_ ans=1;
	while(b){if(b&1){ans=((ll)ans*a)%mod;}a=(ll)a*a%mod;b>>=1;}
	return ans;
}
int rev[MAXN];
ostream &operator<<(ostream &os,big x){
	int sta[100];int cnt=0;
	do{sta[cnt++]=x%10;x/=10;}while(x);
	while(cnt){putchar(sta[--cnt]+'0');}
	return os;
}
void ms(type_ *a,type_ rep,int en){for(re int i=0;i<en;i++){a[i]=rep;}}
void exgcd(htype_ a,htype_ b,htype_ &x,htype_ &y){if(!b){x=1,y=0;return;}exgcd(b,a%b,x,y);re int t=x;x=y;y=t-(a/b)*y;}
inline int add(int x,int y,int mod){if(x+y>=mod){return x+y-mod;}return x+y;}
inline int sub(int x,int y,int mod){if(x-y<0){return x-y+mod;}return x-y;}
struct poly{
	int len;
	type_ p[3];
	type_ a[MAXN][MAXM];
	type_ value(int x,type_ mod,int chose=0){re type_ xn=1,ans=0;for(re int i=0;i<len;i++){ans=(ans+(ll)xn*a[i][chose]%mod)%mod;xn=(ll)xn*x%mod;}return ans;}
	type_* operator[](int index){return a[index];}
	void operator=(const poly &b){for(re int i=0;i<len;i++){for(re int j=0;j<MAXM;j++){a[i][j]=b.a[i][j];}}}
	void print(int chose=0){for(re int i=0;i<len;i++){printf("%d ",a[i][chose]);}cout<<endl;}
	int initrev(int n){int l=0,len=1;while(len<n){l++;len<<=1;}for(re int i=0;i<len;i++){rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1));}return len;}
	void G3NTT(int len,int type,int mod,int chose){
		re int Gi=qp(G,mod-2,mod);
		for(re int i=0;i<len;i++){if(i<rev[i]){swap(a[i][chose],a[rev[i]][chose]);}}
		for(re int step=1;step<len;step<<=1){
			re type_ Wn=qp(type==1?G:Gi,(mod-1)/(step<<1),mod);
			for(re int st=0;st<len;st+=(step<<1)){re type_ W=1;
				for(re int k=0;k<step;k++,W=((ll)W*Wn)%mod){
					re int x=a[st+k][chose],y=(ll)W*a[st+k+step][chose]%mod;
					a[st+k][chose]=add(x,y,mod);a[st+k+step][chose]=sub(x,y,mod);
				} 
			}
		}
		if(type==-1){type_ inv=qp(len,mod-2,mod);for(re int i=0;i<len;i++){a[i][chose]=(ll)a[i][chose]*inv%mod;}}
	} 
	void clear(int en=MAXN){len=0;for(re int i=0;i<MAXM;i++){ms(a[i],0,en);}}
	poly(){p[0]=998244353,p[1]=1004535809,p[2]=469762049;}
	poly(int n){p[0]=998244353,p[1]=1004535809,p[2]=469762049;len=n;for(re int i=0;i<MAXM;i++){ms(a[i],0,n);}}
};
ll sqrt1(ll a,ll p){
	if(a==1){return 1;}
	return 0;
}
void multiply(poly &a,poly &b,type_ mod){
	int n=a.len+b.len-1;int bn=b.len;int len=a.initrev(n);
	for(re int i=n;i<len;i++){a[i][0]=b[i][0]=a[i][1]=b[i][1]=a[i][2]=b[i][2]=0;}a.len=b.len=len;
	for(re int j=0;j<MAXM;j++){
		a.G3NTT(len,1,a.p[j],j);b.G3NTT(len,1,b.p[j],j);
		for(re int i=0;i<len;i++){a[i][j]=(ll)a[i][j]*b[i][j]%a.p[j];}
		a.G3NTT(len,-1,a.p[j],j);
	}
	for(re int i=0;i<len;i++){
		htype_ n=1,ans=0;
		for(re int j=0;j<MAXM;j++){n=n*a.p[j];}
		for(re int j=0;j<MAXM;j++){
			htype_ m=n/a.p[j],b,y;
			exgcd(m,a.p[j],b,y);
			b=(b+a.p[j])%a.p[j];
			ans=(ans+(ll)a[i][j]*m%n*b%n)%n;
		}
		ans=(ans+n)%n;a[i][0]=ans%mod;
	}
	for(re int i=n;i<len;i++){a[i][0]=a[i][1]=a[i][2]=0;}
	for(re int i=bn;i<len;i++){b[i][0]=b[i][1]=b[i][2]=0;}
	a.len=n;b.len=bn;
}
poly A,B,A_1,C_1;
inline void inv(poly a,int n,poly &ans,type_ mod){
	ans[0][0]=qp(a[0][0],mod-2,mod);ans.len=n;
	for(re int N=1;N<(n<<1);N<<=1){
		int Nn=N+N;int len=a.initrev(Nn);
		for(re int i=0;i<N;i++){A[i][0]=a[i][0];B[i][0]=ans[i][0];}
		for(re int i=N;i<n*2;i++){A[i][0]=B[i][0]=0;}
		A.G3NTT(len,1,mod,0);B.G3NTT(len,1,mod,0);
		for(re int i=0;i<len;i++){ans[i][0]=(ll)B[i][0]*(sub(2ll,(ll)A[i][0]*B[i][0]%mod,mod))%mod;}
		ans.G3NTT(len,-1,mod,0);
		for(re int i=N;i<len;i++){ans[i][0]=0;}
	}
	int len=a.initrev(n*2);
	for(int i=n;i<len;i++){ans[i][0]=0;}
}
inline void sqrt(poly a,int n,poly &ans,type_ mod){
	ans[0][0]=sqrt1(a[0][0],mod);ans.len=n;
	for(re int N=1;N<(n<<1);N<<=1){
		int Nn=N+N;int len=a.initrev(Nn);
		for(re int i=0;i<N;i++){A_1[i][0]=a[i][0];C_1[i][0]=0;}
		for(re int i=N;i<len;i++){A_1[i][0]=C_1[i][0]=0;}
		inv(ans,N,C_1,mod);
		A_1.G3NTT(len,1,mod,0);ans.G3NTT(len,1,mod,0);C_1.G3NTT(len,1,mod,0);
		int inv2=qp(2,mod-2,mod);
		for(re int i=0;i<len;i++){ans[i][0]=(ll)inv2*(add((ll)ans[i][0],(ll)C_1[i][0]*A_1[i][0]%mod,mod))%mod;}
		ans.G3NTT(len,-1,mod,0);for(re int i=n;i<len;i++){ans[i][0]=0;}
	}
}
poly a,b;
int main(){
	int n;
	cin>>n;
	a.len=n;
	for(re int i=0;i<n;i++){qr(a[i][0]);}
	sqrt(a,n,b,998244353);
	b.print();
} 
2022/12/29 19:02
加载中...