1. 程式人生 > >【多項式】CQBZOJ 3773 多項式計算五合一

【多項式】CQBZOJ 3773 多項式計算五合一

題意:

在這裡插入圖片描述


分析:

紅紅火火恍恍惚惚

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define SF scanf
#define PF printf
#define MAXN 800010
#define MOD 998244353
using namespace std;
int W1[40],W0[40];
int fsp(int x,int y){
	int res=1;
	while
(y){ if(y&1) res=1ll*res*x%MOD; x=1ll*x*x%MOD; y>>=1; } return res; } void ntt(int A[],int N,int flag){ for(int i=1,j=0;i<N;i++){ for(int d=N;j^=d>>=1,~j&d;); if(i<j) swap(A[i],A[j]); } for(int i=1,id=0;i<N;i<<=1,id++){ int wn; if(flag) wn=W1[
id]; else wn=W0[id]; for(int j=0;j<N;j+=i<<1) for(int k=0,w=1;k<i;k++,w=1ll*w*wn%MOD){ int x=A[j+k],y=1ll*w*A[i+j+k]%MOD; A[j+k]=(x+y)%MOD; A[i+j+k]=(x-y+MOD)%MOD; } } if(flag){ int invN=fsp(N,MOD-2); for(int i=0;i<N;i++) A[i]=1ll*A[i]*invN%MOD; } } void mul
(int A[],int N,int B[],int M,int res[]){ static int tmp1[MAXN],tmp2[MAXN]; for(int i=0;i<N;i++) tmp1[i]=A[i]; for(int i=0;i<N;i++) tmp2[i]=B[i]; int p=1;while(p<N+M) p<<=1; ntt(tmp1,p,0); ntt(tmp2,p,0); for(int i=0;i<p;i++) tmp1[i]=1ll*tmp1[i]*tmp2[i]%MOD; ntt(tmp1,p,1); for(int i=0;i<N+M;i++) res[i]=tmp1[i]; for(int i=0;i<p;i++) tmp1[i]=tmp2[i]=0; } void inv(int A[],int N,int B[]){ if(N==1){ B[0]=fsp(A[0],MOD-2); return ; } inv(A,(N+1)>>1,B); static int tmp1[MAXN],tmp2[MAXN]; int p=1; while(p<N<<1) p<<=1; for(int i=0;i<N;i++) tmp1[i]=A[i]; for(int i=0;i<(N+1)>>1;i++) tmp2[i]=B[i]; ntt(tmp1,p,0); ntt(tmp2,p,0); for(int i=0;i<p;i++) tmp2[i]=1ll*tmp2[i]*((2ll-1ll*tmp1[i]*tmp2[i]%MOD+MOD)%MOD)%MOD; ntt(tmp2,p,1); for(int i=0;i<N;i++) B[i]=tmp2[i]; for(int i=0;i<p;i++) tmp1[i]=tmp2[i]=0; } const int inv2=499122177; void Sqrt(int A[],int N,int B[]){ if(N==1){ B[0]=sqrt(A[0]); return ; } Sqrt(A,(N+1)>>1,B); static int tmp1[MAXN],tmp2[MAXN],tmp3[MAXN]; int p=1; while(p<N<<1) p<<=1; for(int i=0;i<N;i++) tmp1[i]=A[i]; for(int i=0;i<(N+1)>>1;i++) tmp2[i]=B[i]; inv(B,N,tmp3); for(int i=0;i<N;i++) tmp3[i]=1ll*tmp3[i]*inv2%MOD; ntt(tmp1,p,0),ntt(tmp2,p,0),ntt(tmp3,p,0); for(int i=0;i<p;i++) tmp2[i]=1ll*(tmp1[i]+1ll*tmp2[i]*tmp2[i]%MOD)%MOD*tmp3[i]%MOD; ntt(tmp2,p,1); for(int i=0;i<N;i++) B[i]=tmp2[i]; for(int i=0;i<p;i++) tmp1[i]=tmp2[i]=tmp3[i]=0; } void integral(int A[],int N){ for(int i=N;i>0;i--) A[i]=1ll*A[i-1]*fsp(i,MOD-2)%MOD; A[0]=0; } void Der(int A[],int N){ for(int i=0;i<N;i++) A[i]=1ll*A[i+1]*(i+1)%MOD; A[N-1]=0; } void logar(int A[],int N,int B[]){ static int tmp1[MAXN],tmp2[MAXN]; for(int i=0;i<N;i++) tmp1[i]=A[i]; Der(tmp1,N); inv(A,N,tmp2); mul(tmp1,N-1,tmp2,N,tmp1); integral(tmp1,N-1); for(int i=0;i<N;i++) B[i]=tmp1[i]; for(int i=0;i<4*N;i++) tmp1[i]=tmp2[i]=0; } void Polyexp(int A[],int N,int B[]){ if(N==1){ B[0]=1; return ; } Polyexp(A,(N+1)>>1,B); static int tmp1[MAXN]; logar(B,N,tmp1); for(int i=0;i<N;i++) tmp1[i]=(A[i]-tmp1[i]+MOD)%MOD; tmp1[0]++; mul(B,N,tmp1,N,tmp1); for(int i=0;i<N;i++) B[i]=tmp1[i]; for(int i=0;i<4*N;i++) tmp1[i]=0; } void Polyfsp(int A[],int N,int t,int B[]){ static int tmp[MAXN]; logar(A,N,tmp); for(int i=0;i<N;i++) tmp[i]=1ll*tmp[i]*t%MOD; Polyexp(tmp,N,B); } const int G=3; void prepare(){ for(int i=0;i<20;i++) W1[i]=fsp(G,(MOD-1)/(1<<(i+1))); for(int i=0;i<20;i++) W0[i]=fsp(W1[i],MOD-2); } int a[MAXN],tmpx[MAXN]; int main(){ prepare(); int n,t; SF("%d%d",&n,&t); for(int i=0;i<n;i++) SF("%d",&a[i]); Sqrt(a,n,tmpx); for(int i=0;i<n;i++) a[i]=tmpx[i]; inv(a,n,tmpx); for(int i=0;i<n;i++) a[i]=tmpx[i]; integral(a,n); Polyexp(a,n,tmpx); for(int i=0;i<n;i++) a[i]=tmpx[i]; // for(int i=0;i<n;i++) // PF("%d ",a[i]); // PF("\n"); inv(a,n,tmpx); for(int i=0;i<n;i++) a[i]=tmpx[i]; a[0]++; logar(a,n,tmpx); for(int i=0;i<n;i++) a[i]=tmpx[i]; a[0]++; Polyfsp(a,n,t,tmpx); for(int i=0;i<n;i++) a[i]=tmpx[i]; Der(a,n); for(int i=0;i<n;i++){ PF("%d",a[i]); if(i!=n-1) PF(" "); } }