bzoj2179 FFT快速傅立叶
2179: FFT快速傅立叶
Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 4155 Solved: 2222
[Submit][Status][Discuss]
Description
给出两个n位10进制整数x和y,你需要计算x*y。
Input
第一行一个正整数n。 第二行描述一个位数为n的正整数x。 第三行描述一个位数为n的正整数y。
Output
输出一行,即x*y的结果。
Sample Input
1
3
4
3
4
Sample Output
12
数据范围:
n<=60000
数据范围:
n<=60000
分析:终于把fft给学了. 推荐一篇文章:传送门
#include <cstdio> #include <cmath> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 2e5+5; const double pai = acos(-1.0); int len1,len2,len,res[maxn]; char s1[maxn],s2[maxn]; struct node { double real, imag; node(double real = 0.0, double imag = 0.0) { this->real = real, this->imag = imag; } node operator - (const node&elem) const { return node(this->real - elem.real, this->imag - elem.imag); } node operator + (const node&elem) const { return node(this->real + elem.real, this->imag + elem.imag); } node operator * (const node&elem) const { return node(this->real * elem.real - this->imag * elem.imag, this->real * elem.imag + this->imag * elem.real); } void set(double real = 0.0, double imag = 0.0) { this->real = real, this->imag = imag; } } A[maxn],B[maxn]; void pre() { len1 = strlen(s1),len2 = strlen(s2); int maxx = max(len1,len2); len = 1; while (len < (maxx << 1)) len <<= 1; for (int i = 0; i < len1; i++) A[i].set(s1[len1 - i - 1] - '0',0); for (int i = 0; i < len2; i++) B[i].set(s2[len2 - i - 1] - '0',0); for (int i = len1; i < len; i++) A[i].set(); for (int i = len2; i < len; i++) B[i].set(); } void Swap(node &a,node &b) { node temp = a; a = b; b = temp; } void zhuan(node y[]) { for (int i = 1, j = len >> 1,k; i < len - 1; i++) { if (i < j) Swap(y[i],y[j]); k = len >> 1; while (j >= k) { j -= k; k >>= 1; } if (j < k) j += k; } } void FFT(node y[],int op) { zhuan(y); for (int h = 2; h <= len; h <<= 1) { node temp(cos(op * 2 * pai / h),sin(op * 2 * pai / h)); for (int i = 0; i < len; i += h) { node W(1,0); for (int j = i; j < i + h / 2; j++) { node u = y[j]; node t = W * y[j + h / 2]; y[j] = u + t; y[j + h / 2] = u - t; W = W * temp; } } } if (op == -1) for (int i = 0; i < len; i++) y[i].real /= len; } void solve(node *A,node *B) { FFT(A,1); FFT(B,1); for (int i = 0; i < len; i++) A[i] = A[i] * B[i]; FFT(A,-1); for (int i = 0; i < len; i++) res[i] = (int)(A[i].real + 0.5); } void calc(int *a) { for (int i = 0; i < len; i++) { res[i + 1] += res[i] / 10; res[i] %= 10; } while (--len && res[len] == 0); } void print(int *a) { for (int i = len; i >= 0; i--) putchar(a[i] + '0'); printf("\n"); } int main() { int nn; scanf("%d",&nn); getchar(); gets(s1); gets(s2); pre(); solve(A,B); calc(res); print(res); return 0; }