洛谷 - P3803 【模板】多项式乘法(FFT/NTT)
生活随笔
收集整理的這篇文章主要介紹了
洛谷 - P3803 【模板】多项式乘法(FFT/NTT)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:點擊查看
題目大意:給出兩個多項式 F( x ) 和 G( x ) 的系數,求其卷積后的系數
題目分析:存一個FFT的模板,原理學不明白,數論和dp都扔給隊友了,當個快樂的fw
代碼:
// Problem: P3803 【模板】多項式乘法(FFT) // Contest: Luogu // URL: https://www.luogu.com.cn/problem/P3803 // Memory Limit: 500 MB // Time Limit: 2000 ms // // Powered by CP Editor (https://cpeditor.org)// #pragma GCC optimize(2) // #pragma GCC optimize("Ofast","inline","-ffast-math") // #pragma GCC target("avx,sse2,sse3,sse4,mmx") #include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> #include<cassert> #include<bitset> #include<list> #include<unordered_map> #define lowbit(x) (x&-x) using namespace std; typedef long long LL; typedef unsigned long long ull; template<typename T> inline void read(T &x) {T f=1;x=0;char ch=getchar();while(0==isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(0!=isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();x*=f; } template<typename T> inline void write(T x) {if(x<0){x=~(x-1);putchar('-');}if(x>9)write(x/10);putchar(x%10+'0'); } const int inf=0x3f3f3f3f; const int N=1e6+100; const double Pi=acos(-1.0); struct complex {double x,y;complex (double xx=0,double yy=0){x=xx,y=yy;} }A[N<<2],B[N<<2]; complex operator + (complex a,complex b){ return complex(a.x+b.x , a.y+b.y);} complex operator - (complex a,complex b){ return complex(a.x-b.x , a.y-b.y);} complex operator * (complex a,complex b){ return complex(a.x*b.x-a.y*b.y , a.x*b.y+a.y*b.x);} int limit,r[N<<2],res[N<<2]; void FFT(complex *A,int type) {for(int i=0;i<limit;i++) if(i<r[i]) swap(A[i],A[r[i]]); for(int mid=1;mid<limit;mid<<=1) {complex Wn( cos(Pi/mid) , type*sin(Pi/mid) );for(int R=mid<<1,j=0;j<limit;j+=R) {complex w(1,0);for(int k=0;k<mid;k++,w=w*Wn) {complex x=A[j+k],y=w*A[j+mid+k];A[j+k]=x+y;A[j+mid+k]=x-y;}}} } void init(int n) {limit=1;while(limit<=n) limit<<=1;for(int i=1;i<limit;i++) r[i]=r[i>>1]>>1|((i&1)?limit>>1:0); } int main() { #ifndef ONLINE_JUDGE // freopen("data.in.txt","r",stdin); // freopen("data.out.txt","w",stdout); #endif // ios::sync_with_stdio(false);int n,m;read(n),read(m);n++,m++;init(n+m);for(int i=0,x;i<n;i++) {read(x);A[i].x=x;}for(int i=0,x;i<m;i++) {read(x);B[i].x=x;}FFT(A,1),FFT(B,1);for(int i=0;i<limit;i++) {A[i]=A[i]*B[i];}FFT(A,-1);for(int i=0;i<limit;i++) {res[i]=floor(A[i].x/limit+0.5);}for(int i=0;i<n+m-1;i++) {printf("%d ",res[i]);}return 0; } // Problem: P3803 【模板】多項式乘法(FFT) // Contest: Luogu // URL: https://www.luogu.com.cn/problem/P3803 // Memory Limit: 500 MB // Time Limit: 2000 ms // // Powered by CP Editor (https://cpeditor.org)// #pragma GCC optimize(2) // #pragma GCC optimize("Ofast","inline","-ffast-math") // #pragma GCC target("avx,sse2,sse3,sse4,mmx") #include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> #include<cassert> #include<bitset> #include<list> #include<unordered_map> #define lowbit(x) (x&-x) using namespace std; typedef long long LL; typedef unsigned long long ull; template<typename T> inline void read(T &x) {T f=1;x=0;char ch=getchar();while(0==isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(0!=isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();x*=f; } template<typename T> inline void write(T x) {if(x<0){x=~(x-1);putchar('-');}if(x>9)write(x/10);putchar(x%10+'0'); } const int inf=0x3f3f3f3f; const int N=5e6+100; const int mod=998244353,G=3,Gi=(mod+1)/3; int limit,L,r[N]; int a[N],b[N]; int q_pow(int a,int b) {int ans=1;while(b) {if(b&1) ans=1LL*ans*a%mod;a=1LL*a*a%mod,b>>=1;}return ans; } void NTT(int *A,int type) {for(int i=0;i<limit;i++) if(i<r[i]) swap(A[i],A[r[i]]);for(int mid=1;mid<limit;mid<<=1) { int Wn=q_pow(type==1?G:Gi,(mod-1)/(mid<<1));for(int j=0;j<limit;j+=(mid<<1)) {int w=1;for(int k=0;k<mid;k++,w=1LL*w*Wn%mod) {int x=A[j+k],y=1LL*w*A[j+k+mid]%mod;A[j+k]=(x+y)%mod,A[j+k+mid]=(x-y+mod)%mod;}}}if(type==-1) {int inv=q_pow(limit,mod-2);for(int i=0;i<limit;i++) {A[i]=1LL*A[i]*inv%mod;}} } void init(int n,int m) {limit=1;L=0;while(limit<=n+m) limit<<=1,L++;for(int i=0;i<limit;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(L-1)); } int main() { #ifndef ONLINE_JUDGE // freopen("data.in.txt","r",stdin); // freopen("data.out.txt","w",stdout); #endif // ios::sync_with_stdio(false);int n,m;read(n),read(m);n++,m++;init(n,m);for(int i=0;i<n;i++) {read(a[i]);}for(int i=0;i<m;i++) {read(b[i]);}NTT(a,1),NTT(b,1);for(int i=0;i<limit;i++) {a[i]=1LL*a[i]*b[i]%mod;}NTT(a,-1);for(int i=0;i<n+m-1;i++) {printf("%d ",a[i]);}return 0; }總結
以上是生活随笔為你收集整理的洛谷 - P3803 【模板】多项式乘法(FFT/NTT)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CodeForces - 1420D R
- 下一篇: 中石油训练赛 - Cafebazaar’