FFT之大数乘法

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <cmath>
 4 #include <algorithm>
 5 #include <cstring>
 6 #include <vector>
 7 using namespace std;
 8 #define N 50500*2
 9 const double PI = acos(-1.0);
10 struct Vir
11 {
12     double re, im;
13     Vir(double _re = 0., double _im = 0.) :re(_re), im(_im){}
14     Vir operator*(Vir r) { return Vir(re*r.re - im*r.im, re*r.im + im*r.re); }
15     Vir operator+(Vir r) { return Vir(re + r.re, im + r.im); }
16     Vir operator-(Vir r) { return Vir(re - r.re, im - r.im); }
17 };
18 void bit_rev(Vir *a, int loglen, int len)
19 {
20     for (int i = 0; i < len; ++i)
21     {
22         int t = i, p = 0;
23         for (int j = 0; j < loglen; ++j)
24         {
25             p <<= 1;
26             p = p | (t & 1);
27             t >>= 1;
28         }
29         if (p < i)
30         {
31             Vir temp = a[p];
32             a[p] = a[i];
33             a[i] = temp;
34         }
35     }
36 }
37 void FFT(Vir *a, int loglen, int len, int on)
38 {
39     bit_rev(a, loglen, len);
40
41     for (int s = 1, m = 2; s <= loglen; ++s, m <<= 1)
42     {
43         Vir wn = Vir(cos(2 * PI*on / m), sin(2 * PI*on / m));
44         for (int i = 0; i < len; i += m)
45         {
46             Vir w = Vir(1.0, 0);
47             for (int j = 0; j < m / 2; ++j)
48             {
49                 Vir u = a[i + j];
50                 Vir v = w*a[i + j + m / 2];
51                 a[i + j] = u + v;
52                 a[i + j + m / 2] = u - v;
53                 w = w*wn;
54             }
55         }
56     }
57     if (on == -1)
58     {
59         for (int i = 0; i < len; ++i) a[i].re /= len, a[i].im /= len;
60     }
61 }
62 char a[N * 2], b[N * 2];
63 Vir pa[N * 2], pb[N * 2];
64 int ans[N * 2];
65 int main()
66 {
67     while (scanf("%s%s", a, b) != EOF)
68     {
69         int lena = strlen(a);
70         int lenb = strlen(b);
71         int n = 1, loglen = 0;
72         while (n < lena + lenb) n <<= 1, loglen++;
73         for (int i = 0, j = lena - 1; i < n; ++i, --j)
74             pa[i] = Vir(j >= 0 ? a[j] - ‘0‘ : 0., 0.);
75         for (int i = 0, j = lenb - 1; i < n; ++i, --j)
76             pb[i] = Vir(j >= 0 ? b[j] - ‘0‘ : 0., 0.);
77         for (int i = 0; i <= n; ++i) ans[i] = 0;
78
79         FFT(pa, loglen, n, 1);
80         FFT(pb, loglen, n, 1);
81         for (int i = 0; i < n; ++i)
82             pa[i] = pa[i] * pb[i];
83         FFT(pa, loglen, n, -1);
84
85         for (int i = 0; i < n; ++i) ans[i] = pa[i].re + 0.5;
86         for (int i = 0; i<n; ++i) ans[i + 1] += ans[i] / 10, ans[i] %= 10;
87
88         int pos = lena + lenb - 1;
89         for (; pos>0 && ans[pos] <= 0; --pos);
90         for (; pos >= 0; --pos) printf("%d", ans[pos]);
91         puts("");
92     }
93     return 0;
94 }
时间: 2024-10-20 04:23:34

FFT之大数乘法的相关文章

ACM学习历程—51NOD1028 大数乘法V2(FFT)

题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1028 题目大意就是求两个大数的乘法. 但是用普通的大数乘法,这个长度的大数肯定不行. 大数可以表示点值表示法,然后卷积乘法就能用FFT加速运算了. 这道题是来存模板的. 代码: #include <iostream> #include <cstdio> #include <cstdlib> #include <cmath>

[hdu1402]大数乘法(FFT模板)

题意:大数乘法 思路:FFT模板 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81

大数乘法的几种算法分析及比较(2014腾讯南京笔试题)

转自:http://blog.csdn.net/chhuach2005/article/details/21168179 1.题目 编写两个任意位数的大数相乘的程序,给出计算结果. 2.题目分析 该题相继被ACM.华为.腾讯等选作笔试.面试题,若无准备要写出这种程序,还是要花一定的时间的.故,觉得有必要深入研究一下.搜索了网上的大多数该类程序和算法,发现,大数乘法主要有模拟手工计算的普通大数乘法,分治算法和FFT算法.其中普通大数乘法占据了90%以上,其优点是空间复杂度低,实现简单,时间复杂度为

最短的计算大数乘法的c程序

#include <stdio.h> char s[99],t[99]; int m,n; void r(int i,int c) { int j=0,k=i; while(k)c+=s[j++]*t[k---1]; if(i)r(i-1,c/10); printf("%d",c%10); } void main() { gets(s);gets(t); while(s[n])s[n++]-=48; while(t[m])t[m++]-=48; r(m+n-1,0); }

大数乘法

1027 大数乘法 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 给出2个大整数A,B,计算A*B的结果. Input 第1行:大数A 第2行:大数B (A,B的长度 <= 1000,A,B >= 0) Output 输出A * B Input示例 123456 234567 Output示例 28958703552 相关问题 大数加法 0 大数开平方 640 大数进制转换 320 大数除法 320 大数乘法 V2 80 代码: 1 #inclu

【大数乘法】

1 #include<cstdio> 2 #include<cstring> 3 const int Len = 100; 4 void Mul(char a[],char b[],char c[])//大数乘法 5 { 6 int i,j; 7 int alen = strlen(a),blen = strlen(b); 8 memset(c,0,Len); 9 for(i = 0; i < alen; i++) 10 for(j = 0; j < blen; j++

HDOJ-1042 N!(大数乘法)

http://acm.hdu.edu.cn/showproblem.php?pid=1042 题意清晰..简单明了开门见山的大数乘法.. 10000的阶乘有35000多位 数组有36000够了 # include <stdio.h> # include <string.h> # define MAX 36000 int BigNum[MAX], NowLen; void Multi(int number) { int Temp[MAX]={0}, Tlen = 0, t;//Tem

大数乘法 (poj2389)

模板 #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; void cheng( char *a, char *b, char *sum ) { int temp[2500]; int lena,lenb,l; lena=strlen(a); lenb=strlen(b); int len = lena + lenb;

Uva-oj Product 大数乘法

Product Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Description The problem is to multiply two integers X, Y. (0<=X,Y<10250) Input The input will consist of a set of pairs of lines. Each line in pair cont