zoukankan      html  css  js  c++  java
  • bzoj2179: FFT快速傅立叶

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

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2179

    题目大意:给定两个大数a,b,求a*b,位数n<=60000;

    做法:FFT入门题,FFT的做法可以自己去看算法导论,这题是裸的卷积,直接上DFT或者NTT,我贴的是DFT的。

  • 相关阅读:
    [转]google gflags 库完全使用
    机器学习者面试,看这10个建议
    分享10个数据分析的小技巧(Python)
    工作学习上实用的编程相关知识分享
    前端React 框架- UmiJS有听说过吗?
    PyTorch如何构建深度学习模型?
    Sigmoid 和 Softmax 如何进行函数处理分类?
    从零开始学习机器学习最简单的 kNN 算法
    监督学习中的决策树算法(含代码)
    可视化Bert网络,发掘其中真实世界的嵌入
  • 原文地址:https://www.cnblogs.com/OYzx/p/5877632.html
Copyright © 2011-2022 走看看