zoukankan      html  css  js  c++  java
  • bzoj2194: 快速傅立叶之二

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <algorithm>
     6 using namespace std;
     7 const int maxn=400005;
     8 const double PI=acos(-1);
     9 struct node{
    10     double real,imag;
    11     void clear(){real=imag=0;}
    12     node operator +(const node &x){return (node){real+x.real,imag+x.imag};}
    13     node operator -(const node &x){return (node){real-x.real,imag-x.imag};}
    14     node operator *(const node &x){return (node){real*x.real-imag*x.imag,real*x.imag+imag*x.real};}
    15 }a[maxn],b[maxn],c[maxn],t1,t2,w,wn;
    16 int m,n,len,rev[maxn],ans[maxn];
    17 void read(int &x){
    18     x=0; int f=1; char ch;
    19     for (ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') f=-1;
    20     for (;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; x*=f;
    21 }
    22 int Rev(int x){
    23     int temp=0;
    24     for (int i=1;i<=len;i++) temp<<=1,temp+=(x&1),x>>=1;
    25     return temp;
    26 }
    27 void FFT(node *a,int op){
    28     for (int i=0;i<n;i++) if (i<rev[i]) swap(a[i],a[rev[i]]);
    29     for (int s=2;s<=n;s<<=1){
    30         wn=(node){cos(2*op*PI/s),sin(2*op*PI/s)};
    31         for (int i=0;i<n;i+=s){
    32             w=(node){1,0};
    33             for (int j=i;j<i+s/2;j++,w=w*wn){
    34                 t1=a[j],t2=w*a[j+s/2];
    35                 a[j]=t1+t2,a[j+s/2]=t1-t2;
    36             }
    37         }
    38     }
    39 }
    40 int main(){
    41     read(m); n=1,len=0;
    42     while (n<(m<<1)) n<<=1,len++;
    43     for (int i=0;i<n;i++) rev[i]=Rev(i);
    44     for (int x,i=0;i<m;i++) read(x),a[i].real=x,read(x),b[m-1-i].real=x;
    45     FFT(a,1),FFT(b,1);
    46     for (int i=0;i<n;i++) c[i]=a[i]*b[i];
    47     FFT(c,-1);
    48     for (int i=0;i<n;i++) ans[i]=(int)round(c[i].real/n);
    49     for (int i=m-1;i<2*m-1;i++) printf("%d
    ",ans[i]);
    50     return 0;
    51 }
    View Code

    题目链接: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的非负整数。

    做法:考虑把b数组翻转,Ck的计算就成为了裸的卷积,对于这种题目,翻转是个重要的手段。

  • 相关阅读:
    概率论基础学习笔记
    树点涂色
    2016北京集训测试赛(八)Problem C: 直径
    BZOJ 4361 ISN
    2017省选集训测试赛(二十五)Problem B recollection
    2016北京集训测试赛(六)Problem B: 矩阵
    记录Vue和Jquery混合开发中关于点击事件的一个bug
    记录JQ-WEUI中滚动加载的一个BUG
    Vue Elementui 如何让输入框每次自动聚焦
    什么是CDN加速?(转载)
  • 原文地址:https://www.cnblogs.com/OYzx/p/5877639.html
Copyright © 2011-2022 走看看