LG3803 [テンプレート]多項式乗算(FFT)

P3803 [テンプレート]多項式乗算(FFT)

注意:この質問は3Sを開くが、1秒以内に終えることができるプログラムは、この質問は、一定の最適化をある程度必要とすることをお勧めしますが。

タイトル説明

次の多項式のN F(X)、及びm次多項式G(x)で与えられます。

畳み込みF(x)とG(X)のを要求します。

入出力フォーマット

入力フォーマット:

2つの正の整数N、Mの最初の行。

高い係数F(X)にローから表される次のラインN + 1桁。

ローからハイ係数G(X)に示される次のラインm + 1桁)の。

出力フォーマット:

行N + M +ローからハイ係数Fに示される1桁(X)* G(x)での。

サンプル入力と出力

入力サンプル#1: コピー
1 2 
1 2 
1 2 1
出力サンプル#1: コピー
1 4 5 2

説明

係数入力が0以上と以下9と同じであることを確認します。

$ nは、m個の\当量{10} ^ 6 $、20個のデータ点の総数、2S:データの100%まで。

データは、勾配を持っています。

スペースの制約:256メガバイト

高速フーリエ変換(FFT)高速フーリエ変換を変換します

情報のすべての種類は非常に明確に書かれている、何も言うことはありません。

次いで、高精度で小さい定数(部分)バイナリバタフライ演算において具現コード、およびフリップを総括。

ここで私は、コードをカプセル化し、3秒に、その後のオープンTLE ...... O2繰り返しポストカード。


#8
交流
2923ms / 78800キロバイト


9#
交流
2949ms / 81944キロバイト

その後、出力され-0問題。時間複雑 \(O(N \ログN )\)

#include<bits/stdc++.h>
#define il inline
#define co const
template<class T>T read(){
    T data=0,w=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
    for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
    return data*w;
}
template<class T>il T read(T&x) {return x=read<T>();}
typedef long long LL;
using namespace std;
typedef vector<complex<double> > polynomial;

co double PI=acos(-1);
void Fourier_Transform(polynomial&a,int inverse){
    int limit=a.size(),len=log2(limit);
     // bit reserval
    vector<int> bit_rev(limit);
    for(int i=0;i<limit;++i) bit_rev[i]=bit_rev[i>>1]>>1|(i&1)<<len-1;
    for(int i=0;i<limit;++i)if(i<bit_rev[i]) swap(a[i],a[bit_rev[i]]);
    // Butterfly diagram
    for(int step=1;step<limit;step<<=1){
        double alpha=inverse*PI/step;
        for(int k=0;k<step;++k){
            complex<double> omega_k=exp(complex<double>(0,alpha*k));
            for(int even_k=k;even_k<limit;even_k+=step<<1){
                int odd_k=even_k+step;
                complex<double> t=omega_k*a[odd_k];
                a[odd_k]=a[even_k]-t,a[even_k]+=t;
            }
        }
    }
    if(inverse==-1)for(int i=0;i<limit;++i) a[i]/=limit;
}

int main(){
//  freopen("LG3803.in","r",stdin),freopen("LG3803.out","w",stdout);
    int n=read<int>(),m=read<int>();
    polynomial a(n+1),b(m+1);
    for(int i=0;i<=n;++i) read(a[i].real());
    for(int i=0;i<=m;++i) read(b[i].real());
    int limit=1;
    while(limit<n+m+1) limit<<=1;
    a.resize(limit),b.resize(limit);
    Fourier_Transform(a,1),Fourier_Transform(b,1);
    for(int i=0;i<limit;++i) a[i]*=b[i];
    Fourier_Transform(a,-1);
    for(int i=0;i<=n+m;++i) printf("%.0lf ",a[i].real()+1e-9); // edit 1:-0
    return 0;
}

おすすめ

転載: www.cnblogs.com/autoint/p/11096321.html