luogu3803 多项式乘法 (FFT)

Posted ressed

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu3803 多项式乘法 (FFT)相关的知识,希望对你有一定的参考价值。

FFT讲解传送门

简单记一下做法:

  1.算法流程:两式的系数表达转化为点值表达(O(nlogn))->利用点值表达使两式相乘(O(n))->将结果的点值表达转化回系数表达(O(nlogn))

  2.做法:

    $$目标:把一个n项多项式F(x)=sum_{i=0}^{n-1}a_ix^i转化为{(w^k_n,y_k)}的点值表达,其中w^k_n为n次单位根的k次方$$

    不妨设n为2的幂次,如果不是,则可以补上系数为0的高次项

    $$将a_ix^i按照幂次奇偶性分组,得到F(x)=(a_0x^0+a_2x^2+...+a_{n-2}x^{n-2})+(a_1x^1+a_3x^3..a_{n-1}x^{n-1})$$

    $$设F_0(x)=a_0x^0+a_2x^1+a_4x^2+...+a_{n-2}x^{frac{n}{2}-1} , F_1(x)=a_1x^0+a_3x^1+a_5x^2+...+a_{n-1}x^{frac{n}{2}-1}$$

    $$则F(x)=F_0(x^2)+xF_1(x^2)$$

    $$带入n次单位根,F(w^k_n)=F_0(w^{2k}_n)+w^k_nF_1(w^{2k}_n)$$

    $$w^{xk}_{xn}=w^k_n  ==> F(w^k_n)=F_0(w^k_{frac{n}{2}})+w^k_nF_1(w^k_{frac{n}{2}}) $$

    $$w^{k}_{n}=-w^{k+frac{n}{2}}_n ==> F(w^{k+frac{n}{2}}_n)=F_0(w^k_{frac{n}{2}})-w^k_nF_1(w^k_{frac{n}{2}}) $$

剩下明天写(2018-07-25)

 

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #define LL long long int
 6 using namespace std;
 7 const int maxn=2097152;
 8 const double Pi=acos(-1);
 9 
10 LL rd(){
11     LL x=0;int neg=1;char c=getchar();
12     while(c<0||c>9){if(c==-) neg=-1;c=getchar();}
13     while(c>=0&&c<=9) x=x*10+c-0,c=getchar();
14     return x*neg;
15 }
16 
17 struct Complex{
18     double x,y;
19     Complex(double x0=0,double y0=0){x=x0,y=y0;}
20 }A[maxn],B[maxn];
21 Complex operator * (Complex a,Complex b){return Complex(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
22 Complex operator + (Complex a,Complex b){return Complex(a.x+b.x,a.y+b.y);}
23 Complex operator - (Complex a,Complex b){return Complex(a.x-b.x,a.y-b.y);}
24 int rev[maxn],N,M,len=1;
25 
26 void fft(Complex *a,int opt){
27     for(int i=0;i<len;i++){
28         if(i<rev[i]) swap(a[i],a[rev[i]]);
29     }
30     for(int i=1;i<len;i<<=1){
31         Complex wn=Complex(cos(Pi/i),opt*sin(Pi/i));
32         int step=i<<1;
33         for(int j=0;j<len;j+=step){
34             Complex w=Complex(1,0);
35             for(int k=0;k<i;k++,w=w*wn){
36                 Complex x=a[j+k];
37                 Complex y=w*a[j+k+i];
38                 a[j+k]=x+y;
39                 a[j+k+i]=x-y;
40             }
41         }
42     }
43 }
44 
45 int main(){
46     int i,j,k;
47     N=rd()+1,M=rd()+1;
48     for(i=0;i<N;i++) A[i].x=rd();
49     for(i=0;i<M;i++) B[i].x=rd();
50     k=0;while(len<N+M-1) len<<=1,k++;
51     for(i=0;i<len;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(k-1));
52     fft(A,1);fft(B,1);
53     for(i=0;i<len;i++) A[i]=A[i]*B[i]; 
54     fft(A,-1);
55     for(i=0;i<N+M-1;i++){
56         printf("%d ",(int)(A[i].x/len+0.5));
57     }
58     return 0;
59 }

 

以上是关于luogu3803 多项式乘法 (FFT)的主要内容,如果未能解决你的问题,请参考以下文章

luogu P3803 模板多项式乘法(FFT)

[模板][P3803]多项式乘法

洛谷.3803.[模板]多项式乘法(FFT)

洛谷P3803 模板多项式乘法(FFT)

P3803 多项式乘积(FFT)

[uoj#34] [洛谷P3803] 多项式乘法(FFT)