1. 程式人生 > >[Luogu 1919]【模板】A*B Problem升級版(FFT快速傅裏葉)

[Luogu 1919]【模板】A*B Problem升級版(FFT快速傅裏葉)

vector sample lex cstring 模板 rip putc -s and

Description

給出兩個n位10進制整數x和y,你需要計算x*y。

Input

第一行一個正整數n。 第二行描述一個位數為n的正整數x。 第三行描述一個位數為n的正整數y。

Output

輸出一行,即x*y的結果。(註意判斷前導0)

Sample Input

1
3
4

Sample Output

12

HINT

n<=60000

題解

A*B Problem。和 A+B Problem 一樣簡單。

1 input() and print(int(input()) * int(input()))

對於一個大數 $\overline{a_na_{n-1}\cdots a_0}$ ,顯然我們可以將其記為 $N=a_0\cdot 10^0+a_1\cdot 10^1+\cdots+a_n\cdot10^n$ 。將 $10^k$ 變為形式冪級數 $x^k$ : $N=a_0\cdot x^0+a_1\cdot x^1+\cdots+a_n\cdot x^n$ 。顯然這是一個多項式。? $FFT$ 的板子即可。

註意輸入的數有前導零...

 1 //It is made by Awson on 2018.1.27
 2 #include <set>
 3 #include <map>
 4 #include <cmath>
 5 #include <ctime>
 6 #include <queue>
 7 #include <stack>
 8 #include <cstdio>
 9 #include <string>
10 #include <vector>
11 #include <cstdlib>
12
#include <cstring> 13 #include <complex> 14 #include <iostream> 15 #include <algorithm> 16 #define LL long long 17 #define dob complex<double> 18 #define Abs(a) ((a) < 0 ? (-(a)) : (a)) 19 #define Max(a, b) ((a) > (b) ? (a) : (b)) 20 #define Min(a, b) ((a) < (b) ? (a) : (b)) 21
#define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b)) 22 #define writeln(x) (write(x), putchar(‘\n‘)) 23 #define lowbit(x) ((x)&(-(x))) 24 using namespace std; 25 const int INF = ~0u>>1; 26 const double pi = acos(-1.0); 27 const int N = 6e4*4; 28 void read(int &x) { 29 char ch; bool flag = 0; 30 for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == -)) || 1); ch = getchar()); 31 for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar()); 32 x *= 1-2*flag; 33 } 34 void write(int x) { 35 if (x > 9) write(x/10); 36 putchar(x%10+48); 37 } 38 39 int n, m, L, R[N+5], sum[N+5]; 40 dob a[N+5], b[N+5]; 41 42 int getnum() {char ch = getchar(); while (ch < 0 || ch > 9) ch = getchar(); return ch-48; } 43 void FFT(dob *A, int o) { 44 for (int i = 0; i < n; i++) if (i > R[i]) swap(A[i], A[R[i]]); 45 for (int i = 1; i < n; i <<= 1) { 46 dob wn(cos(pi/i), sin(pi*o/i)), x, y; 47 for (int j = 0; j < n; j += (i<<1)) { 48 dob w(1, 0); 49 for (int k = 0; k < i; k++, w *= wn) { 50 x = A[j+k], y = w*A[i+j+k]; 51 A[j+k] = x+y, A[i+j+k] = x-y; 52 } 53 } 54 } 55 } 56 void work() { 57 read(n); n--; 58 for (int i = n; i >= 0; i--) a[i] = getnum(); 59 for (int i = n; i >= 0; i--) b[i] = getnum(); 60 m = n<<1; 61 for (n = 1; n <= m; n <<= 1) L++; 62 for (int i = 0; i < n; i++) R[i] = (R[i>>1]>>1)|((i&1)<<(L-1)); 63 FFT(a, 1), FFT(b, 1); 64 for (int i = 0; i < n; i++) a[i] *= b[i]; 65 FFT(a, -1); 66 for (int i = 0; i <= m; i++) sum[i] = int(a[i].real()/n+0.5); 67 for (int i = 0; i <= m; i++) sum[i+1] += sum[i]/10, sum[i] %= 10; 68 if (sum[m+1]) m++; while (!sum[m]) m--; 69 for (int i = m; i >= 0; i--) write(sum[i]); 70 } 71 int main() { 72 work(); 73 return 0; 74 }

[Luogu 1919]【模板】A*B Problem升級版(FFT快速傅裏葉)