BZOJ_2179_FFT快速傅立叶_(FFT)

描述



http://www.lydsy.com/JudgeOnline/problem.php?id=2179

超大整数乘法

分析



FFT模板题.

把数字看成是多项式,x是10.然后用FFT做多项式乘法,最后进位就好了.

注意:

1.进位前要把每一位加0.5(或者更小),然后向下取整,应该是浮点数的计算误差吧...

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 const int maxn=140000;
 5 const double pi=acos(-1.0);
 6 int len;
 7 int rev[maxn],ans[maxn];
 8 char str[maxn];
 9 struct cp{//复数(complex)
10     double r,i;
11     cp(double r_=0.0,double i_=0.0):r(r_),i(i_){}
12     cp operator + (const cp &x) const { return cp(r+x.r,i+x.i); }
13     cp operator - (const cp &x) const { return cp(r-x.r,i-x.i); }
14     cp operator * (const cp &x) const { return cp(r*x.r-i*x.i,r*x.i+i*x.r); }
15 }a[maxn],b[maxn],A[maxn];
16 void brc(int &len){//二进制逆序置换(bit-reverse-copy)
17     memset(rev,-1,sizeof rev);
18     int k=1,l=0;
19     while(k<len) k<<=1,l++;
20     len=k;
21     rev[0]=0; rev[len-1]=len-1;
22     for(int i=1;i<len-1;i++){
23         if(rev[i]!=-1) continue;
24         int x=i,y=0,m=l;
25         while(m--) y<<=1, y|=(x&1), x>>=1;
26         rev[i]=y; rev[y]=i;
27     }
28 }
29 void dft(cp *a,int n,int flag){//离散傅里叶变换(discrete-Fourier-transform)
30     for(int i=0;i<n;i++) A[rev[i]]=a[i];
31     for(int i=0;i<n;i++) a[i]=A[i];
32     for(int m=2;m<=n;m<<=1){
33         cp wn(cos(2.0*pi/m*flag),sin(2.0*pi/m*flag));
34         for(int i=0;i<n;i+=m){
35             cp w(1.0,0.0); int k=m>>1;
36             for(int j=0;j<k;j++){
37                 cp t=w*a[i+j+k], u=a[i+j];
38                 a[i+j]=u+t;
39                 a[i+j+k]=u-t;
40                 w=w*wn;
41             }
42         }
43     }
44     if(flag==-1)for(int i=0;i<n;i++) a[i].r/=n;
45 }
46 void readin(cp *a){
47     scanf("%s",str);
48     int l=strlen(str);
49     for(int i=0;i<l;i++) a[i].r=str[l-1-i]-‘0‘;
50 }
51 int main(){
52     scanf("%d",&len);
53     len=len*2-1;
54     readin(a); readin(b);
55     brc(len);
56     dft(a,len,1); dft(b,len,1);
57     for(int i=0;i<len;i++) a[i]=a[i]*b[i];
58     dft(a,len,-1);
59     for(int i=0;i<len;i++) ans[i]=a[i].r+0.5;
60     for(int i=0;i<len;i++) ans[i+1]+=ans[i]/10, ans[i]%=10;
61     len++;
62     while(!ans[len]&&len) len--;
63     for(int i=len;i>=0;i--) printf("%d",ans[i]);
64     return 0;
65 }

2179: FFT快速傅立叶

Time Limit: 10 Sec  Memory Limit: 259 MB
Submit: 2567  Solved: 1308
[Submit][Status][Discuss]

Description

给出两个n位10进制整数x和y,你需要计算x*y。

Input

第一行一个正整数n。
第二行描述一个位数为n的正整数x。
第三行描述一个位数为n的正整数y。

Output

输出一行,即x*y的结果。

Sample Input

1
3
4

Sample Output

12

数据范围:
n<=60000

HINT

Source

时间: 2024-08-04 16:50:53

BZOJ_2179_FFT快速傅立叶_(FFT)的相关文章

快速傅立叶变换(FFT)相关内容汇总

FFT是近年考察非常频繁的算法,与其相关的知识点也相当多样. 这里主要是资料汇总,内容补充和总结等.具体应用应在各大OJ上做相关题目. 目录: 概述 1. 前置技能:数学基础 1.1 多项式概念与运算. 1.2 微积分初步与泰勒展开 1.3 普通型生成函数与指数型生成函数 1.4 线性代数相关(矩阵,行列式与特征多项式) 1.5 组合数与伯努利数 1.6 常系数齐次线性递推 1.7 初等数论与初等代数 1.8 卷积概念与O(n^2)求法 1.9 拉格朗日插值法 2. FFT:快速傅立叶变换算法总

【BZOJ】2179: FFT快速傅立叶(fft)

http://www.lydsy.com/JudgeOnline/problem.php?id=2179 fft裸题.... 为嘛我的那么慢....1000多ms.. #include <cstdio> #include <cstring> #include <cmath> #include <string> #include <iostream> #include <algorithm> #include <queue>

为什么要进行傅立叶变换?傅立叶变换究竟有何意义?如何用Matlab实现快速傅立叶变换

写在最前面:本文是我阅读了多篇相关文章后对它们进行分析重组整合而得,绝大部分内容非我所原创.在此向多位原创作者致敬!!! 一.傅立叶变换的由来 关于傅立叶变换,无论是书本还是在网上可以很容易找到关于傅立叶变换的描述,但是大都是些故弄玄虚的文章,太过抽象,尽是一些让人看了就望而生畏的公式的罗列,让人很难能够从感性上得到理解,最近,我偶尔从网上看到一个关于数字信号处理的电子书籍,是一个叫Steven W. Smith, Ph.D.外国人写的,写得非常浅显,里面有七章由浅入深地专门讲述关于离散信号的傅

快速傅立叶变换

多项式 对于多项式$ f\left(x\right)=\sum_{i=0}^{|f|}{f_ix^i} $,其中|f|表示多项式的阶数,fi表示多项式f中x^i的系数. 多项式的加法定义为$ c\left(x\right)=a\left(x\right)+b\left(x\right)=\sum_{i=0}^{\max\left(|a|,|b|\right)}{\left(a_i+b_i\right)x^i} $,即$ c_k=a_k+b_k $. 多项式的乘法定义为$ c\left(x\rig

BZOJ_2194_快速傅立叶之二_(FFT+卷积)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=2194 给出序列\(a[0],a[1],...,a[n-1]\)和\(b[0],b[1],...,b[n-1]\). \(c[k]=\sum_{i=k}^{n-1}a[i]b[i-k]\). 求序列\(c[]\). 分析 这题就是BZOJ_3527_[ZJOI2014]_力_(FFT+卷积)的后半段... 我们来重新分析一下. 首先我们要知道卷积的标准形式: $$c[i]=\sum_{j=0}

bzoj 2179: FFT快速傅立叶 -- FFT

2179: FFT快速傅立叶 Time Limit: 10 Sec  Memory Limit: 259 MB Description 给出两个n位10进制整数x和y,你需要计算x*y. Input 第一行一个正整数n. 第二行描述一个位数为n的正整数x. 第三行描述一个位数为n的正整数y. Output 输出一行,即x*y的结果. Sample Input 1 3 4 Sample Output 12 数据范围: n<=60000 HINT #include<map> #include

BZOJ 2179: FFT快速傅立叶

2179: FFT快速傅立叶 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 3138  Solved: 1620[Submit][Status][Discuss] Description 给出两个n位10进制整数x和y,你需要计算x*y. Input 第一行一个正整数n. 第二行描述一个位数为n的正整数x. 第三行描述一个位数为n的正整数y. Output 输出一行,即x*y的结果. Sample Input 1 3 4 Sample Outpu

【BZOJ 2194】2194: 快速傅立叶之二(FFT)

2194: 快速傅立叶之二 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1273  Solved: 745 Description 请计算C[k]=sigma(a[i]*b[i-k]) 其中 k < = i < n ,并且有 n < = 10 ^ 5. a,b中的元素均为小于等于100的非负整数. Input 第一行一个整数N,接下来N行,第i+2..i+N-1行,每行两个数,依次表示a[i],b[i] (0 < = i <

【bzoj2179】FFT快速傅立叶 FFT模板

2016-06-01  09:34:54 很久很久很久以前写的了... 今天又比较了一下效率,貌似手写复数要快很多. 贴一下模板: 1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<algorithm> 6 #include<cmath> 7 #include<queue> 8 #includ