1. 程式人生 > >數論-FFT高精度乘法

數論-FFT高精度乘法

turn 輸入 str name clas ret lag BE 題目

NKOJ3071 模板題:求兩個整數之積.

FFT 函數裏 ty = 1 表示 DFT 運算,ty = -1 表示 IDFT 運算.

 1 #include <stdio.h>
 2 #include <complex>
 3 
 4 using namespace std;
 5 
 6 typedef complex<double> CP;
 7 typedef long long LL;
 8 
 9 const int _N = 300005;
10 const double PI = 3.1415926535897932384626433832795
; 11 12 LL rev[_N], Ans[_N]; 13 char str1[_N], str2[_N]; 14 CP X[_N], Y[_N]; 15 16 void GetRev(LL bit) 17 { 18 for (LL i = 0; i < (1<<bit); ++i) 19 rev[i] = (rev[i>>1]>>1) | ((i&1)<<(bit-1)); 20 return; 21 } 22 23 void FFT(CP *A, LL n, LL ty)
24 { 25 LL i, k, len; 26 for (i = 0; i < n; ++i) 27 if (i < rev[i]) swap(A[i], A[rev[i]]); 28 29 for (len = 1; len < n; len <<= 1) { 30 CP wn = exp(CP(0, ty*PI/len)); 31 for (i = 0; i < n; i += len<<1) { 32 CP wi(1, 0
); 33 for (k = i; k < i+len; ++k) { 34 CP t0 = A[k], t1 = wi*A[k+len]; 35 A[k] = t0+t1, A[k+len] = t0-t1; 36 wi *= wn; 37 } 38 } 39 } 40 if (ty == -1) 41 for (i = 0; i < n; ++i) A[i] /= n; 42 return; 43 } 44 45 bool Input(LL &len, char *str) 46 { 47 char tt; bool flag = false; int i; 48 while (((tt = getchar()) < 0 || tt > 9) && tt != -); 49 if (tt == -) flag = true, i = -1; 50 else str[0] = tt, i = 0; 51 while ((tt = getchar()) >= 0 && tt <= 9) str[++i] = tt; 52 len = i+1; 53 return flag; 54 } 55 56 int main() 57 { 58 LL flag1, flag2, l1, l2, i; 59 flag1 = Input(l1, str1), flag2 = Input(l2, str2); 60 // printf("\n\n%s %s\n\n %lld %lld\n", str1, str2, l1, l2); 61 LL a = 1, x = 0; 62 while (a < l1+l2-1) a <<= 1, ++x; 63 // printf("\n\na = %lld, x = %lld\n\n", a, x); 64 for (i = 0; i < l1; ++i) X[i] = (double)(str1[l1-1-i]-0); 65 for (i = 0; i < l2; ++i) Y[i] = (double)(str2[l2-1-i]-0); 66 GetRev(x), FFT(X, a, 1), FFT(Y, a, 1); 67 for (i = 0; i < a; ++i) X[i] *= Y[i]; 68 FFT(X, a, -1); 69 for (i = 0; i < l1+l2; ++i) 70 Ans[i] += (long long)(X[i].real() + 0.5), Ans[i+1] += Ans[i]/10, Ans[i] %= 10; 71 for (i = l1+l2; i >= 0 && !Ans[i]; --i); 72 if (i == -1) { printf("0\n"); return 0; } 73 if (flag1 ^ flag2) putchar(-); 74 while (i >= 0) putchar(Ans[i] + 0), --i; 75 putchar(\n); 76 return 0; 77 }

題目

P3071【高精度】a*b
時間限制 : 10000 MS 空間限制 : 65536 KB
問題描述

給你兩個正整數a,b,計算它們的乘積。

輸入格式

第一行一個正整數a
第二行一個正整數b

輸出格式

一行,表示a*b

樣例輸入

111222333444555666777888999
999888777666555444333222111

樣例輸出

111209963037098814851876554444456814851901296370456889

提示

a,b分別不超過100000位


來源 感謝nodgd放題並提供數據

數論-FFT高精度乘法