luogu P4245 模板任意模数NTT MTT
Posted guangheli
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu P4245 模板任意模数NTT MTT相关的知识,希望对你有一定的参考价值。
Code:
#include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) #define maxn 1000000 #define M 32768 #define double long double #define ll long long using namespace std; namespace poly{ const double pi=acos(-1); int rev[maxn],l; struct Cpx{ double x,y; Cpx (double t1=0,double t2=0){x=t1,y=t2;} }; Cpx operator+(Cpx a,Cpx b){ return Cpx(a.x+b.x,a.y+b.y);} Cpx operator-(Cpx a,Cpx b){ return Cpx(a.x-b.x, a.y-b.y); } Cpx operator*(Cpx a,Cpx b){ return Cpx(a.x*b.x-a.y*b.y, a.x*b.y+a.y*b.x); } void FFT(Cpx *a,int n,int flag){ for(int i=0;i<n;++i) rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1)); for(int i=0;i<n;++i) if(i<rev[i]) swap(a[i],a[rev[i]]); for(int mid=1;mid<n;mid<<=1){ Cpx wn(cos(pi/mid), flag*sin(pi/mid)),x,y; for(int j=0;j<n;j+=(mid<<1)){ Cpx w(1,0); for(int k=0;k<mid;++k) { x=a[j+k],y=w*a[j+mid+k]; a[j+k]=x+y,a[j+mid+k]=x-y, w=w*wn; } } } if(flag==1) return; for(int i=0;i<n;++i) a[i].x=a[i].x/(double)n; } Cpx a[maxn<<1],b[maxn<<1],c[maxn<<1],d[maxn<<1]; Cpx e[maxn<<1],g[maxn<<1],f[maxn<<1],h[maxn<<1]; int ans[maxn]; void MTT(int n,int m,int *F,int *G,int p){ n+=m,l=0; for(m=1;m<=n;m<<=1) ++l; for(int i=0;i<n;++i) { a[i].x=F[i]/M,b[i].x=F[i]%M; c[i].x=G[i]/M,d[i].x=G[i]%M; } FFT(a,m,1),FFT(b,m,1),FFT(c,m,1),FFT(d,m,1); for(int i=0;i<m;++i){ e[i]=a[i]*c[i],f[i]=a[i]*d[i]; g[i]=b[i]*c[i],h[i]=b[i]*d[i]; } FFT(e,m,-1),FFT(f,m,-1),FFT(g,m,-1),FFT(h,m,-1); for(int i=0;i<m;++i){ ans[i]=(ll)(e[i].x+0.5)%p*M%p*M%p,ans[i]%=p; ans[i]+=(ll)(f[i].x+0.5)%p*M%p,ans[i]%=p; ans[i]+=(ll)(g[i].x+0.5)%p*M%p,ans[i]%=p; ans[i]+=(ll)(h[i].x+0.5)%p; ans[i]%=p; } } }; int n,m,p; int A[maxn<<1],B[maxn<<1]; int main(){ //setIO("input"); scanf("%d%d%d",&n,&m,&p); for(int i=0;i<=n;++i) scanf("%d",&A[i]); for(int i=0;i<=m;++i) scanf("%d",&B[i]); poly::MTT(n,m,A,B,p); for(int i=0;i<=n+m;++i) printf("%d ",poly::ans[i]); return 0; }
以上是关于luogu P4245 模板任意模数NTT MTT的主要内容,如果未能解决你的问题,请参考以下文章