• BZOJ2194: 快速傅立叶之二


    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2194

    题目大意:请计算C[k]=sigma(a[i]*b[i-k]) 其中 k < = i < n ,并且有 n < = 10 ^ 5。 a,b中的元素均为小于等于100的非负整数。

    题解:这就是所谓的卷积,找个时间一定要好好看看,上FFT咯

    代码:

     1 #include<iostream>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cstdio>
     5 #include<cmath>
     6 #define maxn 270005
     7 #define pi acos(-1)
     8 using namespace std;
     9 int n,m;
    10 int ans[maxn],rev[maxn];
    11 int l;
    12 struct F{
    13     double rea,ima;
    14     F operator +(const F &x){return (F){rea+x.rea,ima+x.ima};}
    15     F operator -(const F &x){return (F){rea-x.rea,ima-x.ima};}
    16     F operator *(const F &x){return (F){rea*x.rea-ima*x.ima,rea*x.ima+ima*x.rea};}
    17 }a[maxn],b[maxn],c[maxn],w,wn,t1,t2;
    18 int read()
    19 {
    20     int x=0; char ch; bool bo=0;
    21     while (ch=getchar(),ch<'0'||ch>'9') if (ch=='-') bo=1;
    22     while (x=x*10+ch-'0',ch=getchar(),ch>='0'&&ch<='9');
    23     if (bo) return -x; return x;
    24 }
    25 void fft(F *a,int type)
    26 {
    27     for (int i=0; i<n; i++) if (i<rev[i]) swap(a[i],a[rev[i]]);
    28     for (int s=2; s<=n; s<<=1)
    29     {
    30         wn=(F){cos(type*2*pi/s),sin(type*2*pi/s)};
    31         for (int i=0; i<n; i+=s)
    32         {
    33             w=(F){1,0};
    34             for (int j=i; j<(i+(s>>1)); j++,w=w*wn)
    35             {
    36                 t1=a[j],t2=a[j+(s>>1)]*w;
    37                 a[j]=t1+t2,a[j+(s>>1)]=t1-t2;
    38             }
    39         }
    40     }
    41 }
    42 int re(int x)
    43 {
    44     int t=0;
    45     for (int i=0; i<l; i++) t<<=1,t|=x&1,x>>=1;
    46     return t;
    47 }
    48 void init()
    49 {
    50     m=read();
    51     for (n=1; n<2*m; n<<=1) l++;
    52     for (int i=0; i<m; i++) 
    53     {
    54         a[i].rea=read(),b[m-i-1].rea=read();
    55     }
    56     for (int i=0; i<n; i++) rev[i]=re(i);
    57     fft(a,1); fft(b,1);
    58     for (int i=0; i<n; i++) c[i]=a[i]*b[i];
    59     fft(c,-1);
    60     for (int i=0; i<n; i++) ans[i]=(int)(c[i].rea/n+0.5);
    61     for (int i=m-1; i<2*m-1; i++) printf("%d
    ",ans[i]);
    62     
    63 }
    64 int main()
    65 {
    66     init();
    67 }
    View Code
  • 相关阅读:
    java 如何读取jar包外的properties文件(转)
    window.showModalDialog()之返回值
    Java web.xml随笔
    如何获取业务表中各位业务员的业务类型A与业务类型B的业务金额
    web.config Web配置文件(*.config)
    Eclipse常用捷键
    css圆角效果
    回车键事件
    WCF学习 之旅
    validation
  • 原文地址:https://www.cnblogs.com/HQHQ/p/5595150.html
Copyright © 2020-2023  润新知