zoukankan      html  css  js  c++  java
  • 多项式模板集合

    博主太菜惹。。。只放模板。。。

    (FFT)

    #include<bits/stdc++.h>
    #define IL inline
    #define LF double
    using namespace std;
    const int N=4e6+3;
    const LF Pi=acos(-1.0);
    int n,m,lim=1,cnt,r[N],tp;
    struct comp{
    	LF x,y;
    	comp(LF xx=0,LF yy=0){x=xx,y=yy;}
    	IL comp operator+(const comp &a) const{return comp(x+a.x,y+a.y);}
    	IL comp operator-(const comp &a) const{return comp(x-a.x,y-a.y);}
    	IL comp operator*(const comp &a) const{return comp(x*a.x-y*a.y,x*a.y+y*a.x);}
    }a[N],b[N];
    IL int in(){
    	char c;int f=1;
    	while((c=getchar())<'0'||c>'9')
    	  if(c=='-') f-1;
    	int x=c-'0';
    	while((c=getchar())>='0'&&c<='9')
    	  x=x*10+c-'0';
    	return x*f;
    }
    void FFT(comp *a,int op){
      for(int i=0;i<lim;++i) if(i<r[i]) swap(a[i],a[r[i]]);
      for(int i=1;i<lim;i<<=1){
      	comp wn(cos(Pi/i),op*sin(Pi/i));
      	for(int j=0;j<lim;j+=i<<1){
      		comp w(1,0);
      		for(int k=0;k<i;++k,w=w*wn){
      			comp x=a[j+k],y=w*a[j+i+k];
      			a[j+k]=x+y,a[j+i+k]=x-y;
    			}
    		}
    	}
    	if(op==-1) for(int i=0;i<lim;++i) a[i].x=a[i].x/lim;
    }
    int main()
    {
    	n=in()+1,m=in()+1;
    	while(lim<n+m) lim<<=1,++cnt;
    	for(int i=0;i<lim;++i) r[i]=(r[i>>1]>>1)|((i&1)<<cnt-1);
    	for(int i=0;i<n;++i) a[i].x=in();
    	for(int i=0;i<m;++i) b[i].x=in();
    	FFT(a,1),FFT(b,1);
    	for(int i=0;i<lim;++i) a[i]=a[i]*b[i];
    	FFT(a,-1);
    	for(int i=0;i<n+m-1;++i) printf("%d ",(int)(a[i].x/lim+0.5));
    	return 0;
    }
    

    (NTT)

    #include<bits/stdc++.h>
    #define IL inline
    #define LL long long
    using namespace std;
    const int N=4e6+3,p=998244353,G=3,Gi=332748118;
    int n,m,a[N],b[N],r[N],lim=1,cnt,inv;
    IL int in(){
    	char c;int f=1;
    	while((c=getchar())<'0'||c>'9')
    	  if(c=='-') f=-1;
    	int x=c-'0';
    	while((c=getchar())>='0'&&c<='9')
    	  x=x*10+c-'0';
    	return x*f;
    }
    IL int ksm(int a,int b){
    	int c=1;
    	while(b){
    		if(b&1) c=1ll*c*a%p;
    		a=1ll*a*a%p,b>>=1;
    	}
    	return c;
    }
    void NTT(int *a,int op){
    	for(int i=0;i<lim;++i) if(i<r[i]) swap(a[i],a[r[i]]);
    	for(int i=1;i<lim;i<<=1){
    		int wn=ksm(op?G:Gi,(p-1)/(i<<1));
    		for(int j=0;j<lim;j+=(i<<1)){
    			int w=1;
    			for(int k=0;k<i;++k,w=1ll*w*wn%p){
    				int x=a[j+k],y=1ll*w*a[j+i+k]%p;
    				a[j+k]=(x+y)%p,a[j+i+k]=(x-y+p)%p;
    			}
    		}
    	}
    }
    int main()
    {
    	n=in()+1,m=in()+1;
    	for(int i=0;i<n;++i) a[i]=in();
    	for(int i=0;i<m;++i) b[i]=in();
    	while(lim<n+m) lim<<=1,++cnt;
    	for(int i=0;i<lim;++i) r[i]=(r[i>>1]>>1)|((i&1)<<cnt-1);
    	NTT(a,1),NTT(b,1);
    	for(int i=0;i<lim;++i) a[i]=1ll*a[i]*b[i]%p;
    	NTT(a,0),inv=ksm(lim,p-2);
    	for(int i=0;i<n+m-1;++i) printf("%lld ",1ll*a[i]*inv%p);
    	return 0;
    }
    

    多项式求逆

    #include<bits/stdc++.h>
    #define IL inline
    #define LL long long
    #define re register
    using namespace std;
    const int N=4e5+3,p=998244353,G=3,Gi=332748118;
    int n,r[N],lim=1,op,cnt,bas;
    LL a[N],b[N],c[N],d[N];
    IL int in(){
    	char c;int f=1;
    	while((c=getchar())<'0'||c>'9')
    	  if(c=='-') f=-1;
    	re int x=c-'0';
    	while((c=getchar())>='0'&&c<='9')
    	  x=x*10+c-'0';
    	return x*f;
    }
    IL LL ksm(re LL a,re LL b){
    	re LL c=1;
    	while(b){
    		if(b&1) c=c*a%p;
    		a=a*a%p,b>>=1;
    	}
    	return c;
    }
    IL LL mod(LL x){return x>=p?x-p:x;}
    IL void calc(int lim){
      for(re int i=0;i<lim;++i) r[i]=(r[i>>1]>>1)|((i&1)*(lim>>1));
    }
    IL void NTT(LL *a,int op){
    	for(re int i=0;i<lim;++i) if(i<r[i]) swap(a[i],a[r[i]]);
    	for(re int i=1;i<lim;i<<=1){
    		LL wn=ksm(~op?G:Gi,(p-1)/(i<<1));
    		for(re int j=0;j<lim;j+=(i<<1)){
    			LL w=1;
    			for(re int k=0;k<i;++k,w=w*wn%p){
    				LL x=a[j+k],y=w*a[j+i+k]%p;
    				a[j+k]=mod(x+y),a[j+i+k]=mod(x-y+p);
    			}
    		}
    	}
    	if(op==-1){
    		LL inv=ksm(lim,p-2);
    		for(re int i=0;i<lim;++i) a[i]=a[i]*inv%p;
    	}
    }
    void solve(LL *a,LL *b,int n){
    	if(n==1){b[0]=ksm(a[0],p-2);return;}
    	solve(a,b,n+1>>1);lim=1;
    	while(lim<(n<<1)) lim<<=1;calc(lim);
    	memcpy(c,a,8*n),memset(c+n,0,8*(lim-n));
    	NTT(c,1),NTT(b,1);
    	for(re int i=0;i<lim;++i) b[i]=mod(2+p-b[i]*c[i]%p)*b[i]%p;
    	NTT(b,-1),memset(b+n,0,8*(lim-n));
    }
    int main()
    {
    	n=in();
    	for(re int i=0;i<n;++i) a[i]=in();
    	solve(a,b,n);
    	for(re int i=0;i<n;++i) printf("%lld ",b[i]);
    	return 0;
    }
    
    

    多项式除法

    #include<bits/stdc++.h>
    #define IL inline
    #define LL long long
    #define re register
    using namespace std;
    const int N=4e5+3,p=998244353,G=3,Gi=332748118;
    int n,m,K,lim,r[N];
    LL f[N],fr[N],g[N],gr[N],gv[N],q[N],R[N],a[N],b[N],c[N];
    IL int in(){
    	char c;int f=1;
    	while((c=getchar())<'0'||c>'9')
    	  if(c=='-') f=-1;
    	re int x=c-'0';
    	while((c=getchar())>='0'&&c<='9')
    	  x=x*10+c-'0';
    	return x*f;
    }
    IL LL ksm(re LL a,re LL b){
    	re LL c=1;
    	while(b){
    		if(b&1) c=c*a%p;
    		a=a*a%p,b>>=1;
    	}
    	return c;
    }
    IL LL mod(LL x){return x>=p?x-p:x;}
    IL void calcrev(int lim){
    	for(re int i=0;i<lim;++i) r[i]=(r[i>>1]>>1)|((i&1)*(lim>>1));
    }
    void init(){
    	n=in()+1,m=in()+1,K=n-m+1;
    	for(re int i=0;i<n;++i) f[i]=fr[i]=in();
    	for(re int i=0;i<m;++i) g[i]=gr[i]=in();
    	reverse(fr,fr+n),reverse(gr,gr+m);
    }
    IL void NTT(LL *a,int lim,int op){
    	for(re int i=0;i<lim;++i) if(i<r[i]) swap(a[i],a[r[i]]);
    	for(re int i=1;i<lim;i<<=1){
    		re LL wn=ksm(~op?G:Gi,(p-1)/(i<<1));
    		for(re int j=0;j<lim;j+=(i<<1)){
    			re LL w=1;
    			for(re int k=0;k<i;++k,w=w*wn%p){
    				LL x=a[j+k],y=w*a[j+i+k]%p;
    				a[j+k]=mod(x+y),a[j+i+k]=mod(x-y+p);
    			}
    		}
    	}
    	if(op==-1){
    		LL inv=ksm(lim,p-2);
    		for(re int i=0;i<lim;++i) a[i]=a[i]*inv%p;
    	}
    }
    void get_inv(LL *a,LL *b,int n){
    	if(n==1){b[0]=ksm(a[0],p-2);return;}
    	get_inv(a,b,n+1>>1);
    	lim=1;while(lim<(n<<1)) lim<<=1;calcrev(lim);
    	memcpy(c,a,8*n),memset(c+n,0,8*(lim-n));
    	NTT(c,lim,1),NTT(b,lim,1);
    	for(re int i=0;i<lim;++i) b[i]=mod(2-b[i]*c[i]%p+p)*b[i]%p;
    	NTT(b,lim,-1),memset(b+n,0,8*(lim-n));
    }
    IL void mul(LL *a,LL *b,int n,int m){
    	lim=1;while(lim<n+m) lim<<=1;calcrev(lim);
    	memcpy(c,b,8*m),memset(c+m,0,8*(lim-m)),memset(a+n,0,8*(lim-n));
    	NTT(a,lim,1),NTT(c,lim,1);
    	for(int i=0;i<lim;++i) a[i]=c[i]*a[i]%p;
    	NTT(a,lim,-1);
    }
    void divid(){
    	get_inv(gr,gv,K);
    	memcpy(q,fr,8*n);
    	mul(q,gv,n,K);
    	reverse(q,q+K);
    	mul(g,q,m,K);
    	for(re int i=0;i<m-1;++i) R[i]=mod(f[i]-g[i]+p);
    	for(re int i=0;i<K;++i) printf("%lld ",q[i]);printf("
    ");
    	for(re int i=0;i<m-1;++i) printf("%lld ",R[i]);
    }
    int main()
    {
    	init();
    	divid();
    	return 0;
    }
    

    多项式对数函数

    #include<bits/stdc++.h>
    #define IL inline
    #define LL long long
    using namespace std;
    const int N=4e5+3,p=998244353,G=3,Gi=332748118;
    int n,lim=1,r[N];
    LL a[N],b[N],c[N],f[N],g[N];
    IL int in(){
    	char c;int f=1;
    	while((c=getchar())<'0'||c>'9')
    	  if(c=='-') f-1;
    	int x=c-'0';
    	while((c=getchar())>='0'&&c<='9')
    	  x=x*10+c-'0';
    	return x*f;
    }
    IL LL mod(LL x){return x>=p?x-p:x;}
    IL LL ksm(LL a,LL b){
    	LL c=1;
    	while(b){
    		if(b&1) c=c*a%p;
    		a=a*a%p,b>>=1;
    	}
    	return c;
    }
    IL void calc(int lim){
    	for(int i=0;i<lim;++i) r[i]=(r[i>>1]>>1)|((i&1)*(lim>>1));
    }
    void NTT(LL *a,int lim,int op){
    	for(int i=0;i<lim;++i) if(i<r[i]) swap(a[i],a[r[i]]);
    	for(int i=1;i<lim;i<<=1){
    		LL wn=ksm(~op?G:Gi,(p-1)/(i<<1));
    		for(int j=0;j<lim;j+=i<<1){
    			LL w=1;
    			for(int k=0;k<i;++k,w=w*wn%p){
    				LL x=a[j+k],y=w*a[j+i+k]%p;
    				a[j+k]=mod(x+y),a[j+i+k]=mod(x-y+p);
    			}
    		}
    	}
    	if(op==-1){
    		LL inv=ksm(lim,p-2);
    		for(int i=0;i<lim;++i) a[i]=a[i]*inv%p;
    	}
    }
    void get_inv(LL *a,LL *b,int n){
    	if(n==1){b[0]=ksm(a[0],p-2);return;}
    	get_inv(a,b,n+1>>1);
    	lim=1;while(lim<2*n) lim<<=1;calc(lim);
    	memcpy(c,a,8*n),memset(c+n,0,8*(lim-n));
    	NTT(c,lim,1),NTT(b,lim,1);
    	for(int i=0;i<lim;++i) b[i]=mod(2-c[i]*b[i]%p+p)*b[i]%p;
    	NTT(b,lim,-1),memset(b+n,0,8*(lim-n));
    }
    IL void get_dao(LL *a,LL *b,int n){for(int i=0;i<n-1;++i) b[i]=(i+1)*a[i+1]%p;b[n-1]=0;}
    IL void jifen(LL *a,LL *b,int n){for(int i=1;i<n;++i) b[i]=a[i-1]*ksm(i,p-2)%p;b[0]=0;}
    IL void get_ln(LL *f,LL *g,int n){
    	get_dao(f,a,n),get_inv(f,b,n);
    	lim=1;while(lim<2*n) lim<<=1;calc(lim);
    	NTT(a,lim,1),NTT(b,lim,1);
    	for(int i=0;i<lim;++i) a[i]=a[i]*b[i]%p;
    	NTT(a,lim,-1),jifen(a,g,n);
    }
    int main()
    {
    	n=in();
    	for(int i=0;i<n;++i) f[i]=in();
    	get_ln(f,g,n);
    	for(int i=0;i<n;++i) printf("%lld ",g[i]);
    	return 0;
    }
    

    多项式 (exp)

    #include<bits/stdc++.h>
    #define IL inline
    using namespace std;
    const int N=4e5+3,p=998244353,G=3,Gi=332748118;
    int n,m,a[N],b[N],r[N],inv[N];
    IL int in(){
    	char c;int f=1;
    	while((c=getchar())<'0'||c>'9')
    	  if(c=='-') f=-1;
    	int x=c-'0';
    	while((c=getchar())>='0'&&c<='9')
    	  x=x*10+c-'0';
    	return x*f;
    }
    IL int mod(int x){return x>=p?x-p:x;}
    IL void calc(int lim){
    	for(int i=0;i<lim;++i) r[i]=(r[i>>1]>>1)|((i&1)*(lim>>1));
    }
    IL int ksm(int a,int b){
    	int c=1;
    	while(b){
    		if(b&1) c=1ll*c*a%p;
    		b>>=1,a=1ll*a*a%p;
    	}
    	return c;
    }
    void NTT(int *a,int lim,int op){
    	calc(lim);
    	for(int i=0;i<lim;++i) if(i<r[i]) swap(a[i],a[r[i]]);
    	for(int i=1;i<lim;i<<=1){
    		int wn=ksm(op>0?G:Gi,(p-1)/(i<<1));
    		for(int j=0;j<lim;j+=i<<1){
    			int w=1;
    			for(int k=0;k<i;++k,w=1ll*w*wn%p){
    				int x=a[j+k],y=1ll*w*a[j+i+k]%p;
    				a[j+k]=mod(x+y),a[j+i+k]=mod(x-y+p);
    			}
    		}
    	}
    	if(op==-1){
    		int inv=ksm(lim,p-2);
    		for(int i=0;i<lim;++i) a[i]=1ll*a[i]*inv%p;
    	}
    }
    void get_inv(int *a,int *b,int n){
    	if(n==1){b[0]=ksm(a[0],p-2);b[1]=0;return;}
    	get_inv(a,b,n+1>>1);
    	int c[N],lim=1;
    	while(lim<n+n) lim<<=1;
    	memcpy(c,a,4*n),memset(c+n,0,4*(lim-n)),
    	memset(b+n,0,4*(lim-n));
    	NTT(b,lim,1),NTT(c,lim,1);
    	for(int i=0;i<lim;++i) b[i]=1ll*mod(2-1ll*c[i]*b[i]%p+p)*b[i]%p;
    	NTT(b,lim,-1);memset(b+n,0,4*(lim-n));
    }
    void mul(int *a,int *b,int *c,int n,int m){
    	int _a[N],_b[N],lim=1;
    	while(lim<n+m) lim<<=1;
    	memcpy(_a,a,4*n),memcpy(_b,b,4*m),
    	memset(_a+n,0,4*(lim-n)),memset(_b+m,0,4*(lim-m));
    	NTT(_a,lim,1),NTT(_b,lim,1);
    	for(int i=0;i<lim;++i) c[i]=1ll*_a[i]*_b[i]%p;
    	NTT(c,lim,-1);
    }
    void dao(int *a,int *b,int n){for(int i=0;i<n-1;++i) b[i]=1ll*a[i+1]*(i+1)%p;b[n-1]=0;}
    void jifen(int *a,int *b,int n){for(int i=n-1;i;--i) b[i]=1ll*a[i-1]*inv[i]%p;b[0]=0;}
    IL void get_ln(int *a,int *b,int n){
    	int c[N],d[N];
    	dao(a,c,n),get_inv(a,d,n),
    	mul(c,d,c,n,n),jifen(c,b,n);
    }
    void get_exp(int *a,int *b,int n){
    	if(n==1){b[0]=1;b[1]=0;return;}
    	get_exp(a,b,n+1>>1);
    	int c[N],d[N],lim=1;
    	while(lim<n+n) lim<<=1;
    	get_ln(b,c,n),memset(c+n,0,4*(lim-n));
    	d[0]=(a[0]+1-c[0])%p;
    	for(int i=1;i<n;++i) d[i]=mod(a[i]-c[i]+p);
    	memset(d+n,0,4*(lim-n));
    	mul(b,d,b,n,n),memset(b+n,0,4*(lim-n));
    }
    void pre(int n){
    	inv[0]=inv[1]=1;
    	for(int i=2;i<=n;++i)
    	  inv[i]=1ll*(p-p/i)*inv[p%i]%p;
    }
    int main()
    {
    	n=in();pre(n+n);
    	for(int i=0;i<n;++i) a[i]=in();
    	get_exp(a,b,n);
    	for(int i=0;i<n;++i) printf("%d ",b[i]);
    	putchar('
    ');
    	return 0;
    }
    

    多项式开根

    #include<bits/stdc++.h>
    #define IL inline
    #define LL long long
    using namespace std;
    const int N=4e5+3,p=998244353,G=3,Gi=332748118;
    int n,m,a[N],b[N],r[N];
    IL int in(){
    	char c;int f=1;
    	while((c=getchar())<'0'||c>'9')
    	  if(c=='-') f=-1;
    	int x=c-'0';
    	while((c=getchar())>='0'&&c<='9')
    	  x=x*10+c-'0';
    	return x*f;
    }
    IL int ksm(int a,int b){
    	int c=1;
    	while(b){
    		if(b&1) c=1ll*c*a%p;
    		a=1ll*a*a%p,b>>=1;
    	}
    	return c;
    }
    IL int mod(int x){return x>=p?x-p:x;}
    IL void calc(int lim){
    	for(int i=0;i<lim;++i) r[i]=(r[i>>1]>>1)|((i&1)*(lim>>1));
    }
    void NTT(int *a,int lim,int op){
    	calc(lim);
    	for(int i=0;i<lim;++i) if(i<r[i]) swap(a[i],a[r[i]]);
    	for(int i=1;i<lim;i<<=1){
    		int wn=ksm(op>0?G:Gi,(p-1)/(i<<1));
    		for(int j=0;j<lim;j+=i<<1){
    			int w=1;
    			for(int k=0;k<i;++k,w=1ll*w*wn%p){
    				int x=a[j+k],y=1ll*w*a[j+i+k]%p;
    				a[j+k]=mod(x+y),a[j+i+k]=mod(x-y+p);
    			}
    		}
    	}
    	if(op==-1){
    		int inv=ksm(lim,p-2);
    		for(int i=0;i<lim;++i) a[i]=1ll*a[i]*inv%p;
    	}
    }
    void get_inv(int *a,int *b,int n){
    	if(n==1){b[0]=ksm(a[0],p-2);b[1]=0;return;}
    	get_inv(a,b,n+1>>1);
    	int lim=1,c[N];
    	while(lim<2*n) lim<<=1;
    	memcpy(c,a,4*n),memset(c+n,0,4*(lim-n));
    	memset(b+n,0,4*(lim-n));
    	NTT(c,lim,1),NTT(b,lim,1);
    	for(int i=0;i<lim;++i) b[i]=1ll*mod(2-1ll*c[i]*b[i]%p+p)*b[i]%p;
    	NTT(b,lim,-1);memset(b+n,0,4*(lim-n));
    }
    void mul(int *a,int *b,int *c,int n,int m){
    	int lim=1,_a[N],_b[N];
    	while(lim<n+m) lim<<=1;
    	memcpy(_a,a,4*n),memcpy(_b,b,4*m),
    	memset(_a+n,0,4*(lim-n)),memset(_b+m,0,4*(lim-m));
    	NTT(_a,lim,1),NTT(_b,lim,1);
    	for(int i=0;i<lim;++i) _a[i]=1ll*_a[i]*_b[i]%p;
    	NTT(_a,lim,-1);memcpy(c,_a,4*lim);
    }
    void get_sqrt(int *a,int *b,int n){
    	if(n==1){b[0]=1;return;}
    	get_sqrt(a,b,n+1>>1);
    	int lim=1,c[N],d[N],e[N];
    	while(lim<2*n) lim<<=1;
    	for(int i=0;i<n;++i) d[i]=mod(2*b[i]);
    	get_inv(d,e,n),memset(e+n,0,4*(lim-n));
    	mul(b,b,c,n,n),memset(c+n,0,4*(lim-n));
    	for(int i=0;i<n;++i) c[i]=mod(c[i]+a[i]);
    	mul(c,e,b,n,n),memset(b+n,0,4*(lim-n));
    }
    int main()
    {
    	n=in();
    	for(int i=0;i<n;++i) a[i]=in();
    	get_sqrt(a,b,n);
    	for(int i=0;i<n;++i) printf("%d ",b[i]);puts("");
    	return 0;
    }
    

    多项式快速幂

    #include<bits/stdc++.h>
    #define IL inline
    using namespace std;
    const int N=4e5+4,p=998244353,G=3,Gi=332748118;
    int n,m,k,a[N],b[N],d[N],r[N],inv[N];
    IL int in(){
    	char c;int f=1;
    	while((c=getchar())<'0'||c>'9')
    	  if(c=='-') f=-1;
    	int x=c-'0';
    	while((c=getchar())>='0'&&c<='9')
    	  x=x*10+c-'0';
    	return x*f;
    }
    IL int mod(int x){return x>=p?x-p:x;}
    IL int ksm(int a,int b){
    	int c=1;
    	while(b){
    		if(b&1) c=1ll*c*a%p;
    		a=1ll*a*a%p,b>>=1;
    	}
    	return c;
    }
    IL void calc(int lim){
    	for(int i=0;i<lim;++i) r[i]=(r[i>>1]>>1)|((i&1)*(lim>>1));
    }
    void pre(int n){
    	inv[0]=inv[1]=1;
    	for(int i=2;i<n;++i)
    	  inv[i]=1ll*(p-p/i)*inv[p%i]%p;
    }
    void NTT(int *a,int lim,int op){
    	calc(lim);
    	for(int i=0;i<lim;++i) if(i<r[i]) swap(a[i],a[r[i]]);
    	for(int i=1;i<lim;i<<=1){
    		int wn=ksm(op>0?G:Gi,(p-1)/(i<<1));
    		for(int j=0;j<lim;j+=i<<1){
    			int w=1;
    			for(int k=0;k<i;++k,w=1ll*w*wn%p){
    				int x=a[j+k],y=1ll*w*a[j+i+k]%p;
    				a[j+k]=mod(x+y),a[j+i+k]=mod(x-y+p);
    			}
    		}
    	}
    	if(op==-1){
    		int inv=ksm(lim,p-2);
    		for(int i=0;i<lim;++i) a[i]=1ll*a[i]*inv%p;
    	}
    }
    void get_inv(int *a,int *b,int n){
    	if(n==1){b[0]=ksm(a[0],p-2),b[1]=0;return;}
    	get_inv(a,b,n+1>>1);int lim=1,c[N];
    	while(lim<2*n) lim<<=1;
    	memcpy(c,a,4*n),memset(c+n,0,4*(lim-n)),
    	memset(b+n,0,4*(lim-n));
    	NTT(b,lim,1),NTT(c,lim,1);
    	for(int i=0;i<lim;++i) b[i]=1ll*mod(2-1ll*b[i]*c[i]%p+p)*b[i]%p;
    	NTT(b,lim,-1),memset(b+n,0,4*(lim-n));
    }
    void dao(int *a,int *b,int n){for(int i=0;i<n-1;++i) b[i]=1ll*(i+1)*a[i+1]%p;b[n-1]=0;}
    void jifen(int *a,int *b,int n){for(int i=n-1;i;--i) b[i]=1ll*a[i-1]*inv[i]%p;b[0]=0;}
    void get_ln(int *a,int *b,int n){
    	int c[N],d[N],lim=1;
    	while(lim<2*n) lim<<=1;
    	get_inv(a,c,n),dao(a,d,n);
    	memset(c+n,0,4*(lim-n)),memset(d+n,0,4*(lim-n));
    	NTT(c,lim,1),NTT(d,lim,1);
    	for(int i=0;i<lim;++i) c[i]=1ll*c[i]*d[i]%p;
    	NTT(c,lim,-1),jifen(c,b,n);
    }
    void get_exp(int *a,int *b,int n){
    	if(n==1){b[0]=1;return;}
    	get_exp(a,b,n+1>>1);
    	int c[N],d[N],lim=1;
    	while(lim<2*n) lim<<=1;
    	get_ln(b,c,n),get_ln(a,d,n);
    	for(int i=0;i<n;++i) d[i]=1ll*k*d[i]%p;
    	d[0]=(1-c[0]+d[0]+p)%p;
    	for(int i=1;i<n;++i) d[i]=mod(d[i]-c[i]+p);
    	memset(d+n,0,4*(lim-n));
    	NTT(d,lim,1),NTT(b,lim,1);
    	for(int i=0;i<lim;++i) b[i]=1ll*b[i]*d[i]%p;
    	NTT(b,lim,-1);memset(b+n,0,4*(lim-n));
    }
    int main()
    {
    	char c;
    	n=in();
    	while((c=getchar())<'0'||c>'9');
    	k=c-'0';
    	while((c=getchar())>='0'&&c<='9') 
    	  k=(10ll*k+c-'0')%p;
    	for(int i=0;i<n;++i) a[i]=in();
    	pre(n);
    	get_exp(a,b,n);
    	for(int i=0;i<n;++i) printf("%d ",b[i]);putchar('
    ');
    	return 0;
    }
    

    (MTT)

    #include<bits/stdc++.h>
    #define IL inline
    #define LF long double
    #define LL long long
    using namespace std;
    const LF Pi=acos(-1.0);
    const int N=5e5+3,mod=32000;
    int n,m,p,r[N];
    LL ans[N];
    struct com{
    	LF x,y;
    	com operator+(const com a) const{
    	return (com){x+a.x,y+a.y};}
    	com operator-(const com a) const{
    	return (com){x-a.x,y-a.y};}
    	com operator*(const com a) const{
    	return (com){x*a.x-y*a.y,x*a.y+y*a.x};}
    	com operator/(const LF a) const{
    	return (com){x/a,y/a};}
    }t1[N],t2[N],q[N];
    IL int in(){
    	char c;int f=1;
    	while((c=getchar())<'0'||c>'9')
    	  if(c=='-') f=-1;
    	int x=c-'0';
    	while((c=getchar())>='0'&&c<='9')
    	  x=x*10+c-'0';
    	return x*f;
    }
    IL void calc(int lim){
    	for(int i=0;i<lim;++i) r[i]=(r[i>>1]>>1)|((i&1)*(lim>>1));
    }
    IL LL get(LF x){return floor(x+0.5);}
    void FFT(com *a,int lim,int op){
    	calc(lim);
    	for(int i=0;i<lim;++i) if(i<r[i]) swap(a[i],a[r[i]]);
    	for(int i=1;i<lim;i<<=1){
    		com wn=(com){cos(Pi/i),op*sin(Pi/i)};
    		for(int j=0;j<lim;j+=i<<1){
    			com w=(com){1,0};
    			for(int k=0;k<i;++k,w=w*wn){
    				com x=a[j+k],y=w*a[j+i+k];
    				a[j+k]=x+y,a[j+i+k]=x-y;
    			}
    		}
    	}
    }
    int main()
    {
    	int x,lim=1;
    	n=in()+1,m=in()+1,p=in();
    	while(lim<n+m) lim<<=1;
    	for(int i=0;i<n;++i){
    		x=in();
    		t1[i]=(com){x/mod,x%mod},
    		t2[i]=(com){x/mod,-x%mod};
    	}
    	for(int i=0;i<m;++i){
    		x=in();
    		q[i]=(com){x/mod,x%mod};
    	}
    	FFT(t1,lim,1),FFT(t2,lim,1),FFT(q,lim,1);
    	for(int i=0;i<lim;++i) q[i]=q[i]/lim;
    	for(int i=0;i<lim;++i) t1[i]=t1[i]*q[i];
    	for(int i=0;i<lim;++i) t2[i]=t2[i]*q[i];
    	FFT(t1,lim,-1),FFT(t2,lim,-1);
    	for(int i=0;i<n+m-1;++i){
    		LL a1b1,a2b2,a1b2,a2b1;
    		a1b1=get((t1[i].x+t2[i].x)/2)%p;
    		a1b2=get((t1[i].y+t2[i].y)/2)%p;
    		a2b1=get(t1[i].y-a1b2)%p;
    		a2b2=get(t2[i].x-a1b1)%p;
    		ans[i]=((a1b1*mod%p+(a1b2+a2b1)%p)*mod%p+a2b2)%p;
    	}
    	for(int i=0;i<n+m-1;++i) printf("%lld ",ans[i]);puts("");
    	return 0;
    }
    

    常系数齐次线性递推

    #include<bits/stdc++.h>
    #define IL inline
    using namespace std;
    const int N=15e4+3,p=998244353,G=3,Gi=332748118;
    int n,m,a[N],b[N],c[N],f[N],v[N],r[N],Inv[N],Id[N],lim=1,ans,Wn[3][N];
    IL int in(){
    	char c;int f=1;
    	while((c=getchar())<'0'||c>'9')
    	  if(c=='-') f=-1;
    	int x=c-'0';
    	while((c=getchar())>='0'&&c<='9')
    	  x=x*10+c-'0';
    	return x*f;
    }
    IL int mod(int x){return x>=p?x-p:x;}
    IL int ksm(int a,int b){
    	int c=1;
    	while(b){
    		if(b&1) c=1ll*c*a%p;
    		a=1ll*a*a%p,b>>=1;
    	}
    	return c;
    }
    IL void calc(int lim){
    	for(int i=0;i<lim;++i)
    	  r[i]=(r[i>>1]>>1)|((i&1)*(lim>>1));
    }
    void NTT(int *a,int lim,int op){
    	for(int i=0;i<lim;++i) if(i<r[i]) swap(a[i],a[r[i]]);
    	for(int i=1;i<lim;i<<=1){
    		int wn=Wn[op+1][i];
    		for(int j=0;j<lim;j+=i<<1){
    			int w=1;
    			for(int k=0;k<i;++k,w=1ll*w*wn%p){
    				int x=a[j+k],y=1ll*w*a[j+i+k]%p;
    				a[j+k]=mod(x+y),a[j+i+k]=mod(x-y+p);
    			}
    		}
    	}
    	if(op==-1){
    		int inv=ksm(lim,p-2);
    		for(int i=0;i<lim;++i) a[i]=1ll*a[i]*inv%p;
    	}
    }
    void get_inv(int *a,int *b,int n){
    	if(n==1){b[0]=ksm(a[0],p-2);b[1]=0;return;}
    	get_inv(a,b,n+1>>1);
    	int c[N],lim=1;
    	while(lim<n+n) lim<<=1;calc(lim);
    	memcpy(c,a,4*n),memset(c+n,0,4*(lim-n)),
    	memset(b+n,0,4*(lim-n));
    	NTT(c,lim,1),NTT(b,lim,1);
    	for(int i=0;i<lim;++i) b[i]=1ll*mod(2-1ll*c[i]*b[i]%p+p)*b[i]%p;
    	NTT(b,lim,-1);memset(b+n,0,4*(lim-n));
    }
    void mul(int *a,int *b,int *c,int n,int m){
    	int _a[N],_b[N],lim=1;
    	while(lim<n+m) lim<<=1;calc(lim);
    	memcpy(_a,a,4*n),memcpy(_b,b,4*m),
    	memset(_a+n,0,4*(lim-n)),memset(_b+m,0,4*(lim-m));
    	NTT(_a,lim,1),NTT(_b,lim,1);
    	for(int i=0;i<lim;++i) _a[i]=1ll*_a[i]*_b[i]%p;
    	NTT(_a,lim,-1);memcpy(c,_a,4*lim);
    }
    void Mod(int *a,int n){
    	int k=n-m,b[N],c[N];
    	memcpy(c,a,4*n);
    	reverse(c,c+n);
    	mul(c,Inv,b,n,m+1);
    	reverse(b,b+k);
    	mul(b,Id,c,k,m+1);
    	for(int i=0;i<n;++i) a[i]=mod(a[i]-c[i]+p);
    }
    int main()
    {
      while(lim<7e4)
    	Wn[2][lim]=ksm(G,(p-1)/(lim<<1)),
    	Wn[0][lim]=ksm(Gi,(p-1)/(lim<<1)),
    	lim<<=1;
    	n=in(),m=in();
    	for(int i=0;i<m;++i) f[i]=mod(p-in());
    	reverse(f,f+m),f[m]=1;
    	memcpy(Id,f,4*(m+1));
    	reverse(Id,Id+m+1);
    	get_inv(Id,Inv,m+1);
    	reverse(Id,Id+m+1);
    	for(int i=0;i<m;++i) v[i]=mod(in()+p);
    	a[1]=1,c[0]=1;
    	lim=1;
    	while(lim<2*m) lim<<=1;
    	while(n){
    		if(n&1) mul(c,a,c,m,m),Mod(c,lim);
    		n>>=1,mul(a,a,a,m,m),Mod(a,lim);
    	}
    	for(int i=0;i<m;++i) ans=mod(ans+1ll*c[i]*v[i]%p);
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    2019.2.18接口
    第一阶段复习
    vue-cli使用介绍
    Webpack 入门教程
    js报错Uncaught TypeError: Cannot read property 'getElementsByTagName' of null
    用shell编程.编写一个程序,用循环创建多个目录 并在该目录下创建多个文件 在文件中写入内容:
    explorer.exe应用程序错误,怎么解决?
    [Java连接MySQL数据库——含详细步骤和代码](https://www.cnblogs.com/town123/p/8336244.html)
    墨刀的简单使用
    laravel报错:SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '0' for key 'PRIMARY...
  • 原文地址:https://www.cnblogs.com/yiqiAtiya/p/12184394.html
Copyright © 2011-2022 走看看