【HDU1402】【FNT版】A * B Problem Plus

Problem Description
Calculate A * B.
 
Input
Each line will contain two integers A and B. Process to end of file.

Note: the length of each integer will not exceed 50000.
 
Output
For each case, output A * B in one line.
Sample Input
1 2 1000 2
Sample Output
2 2000
Author
DOOM III
 
Recommend
DOOM III   |   We have carefully selected several similar problems for you:  1215 1695 1066 1042 1408
【分析】
写个数论变换还被卡出翔....
什么世道啊。。。。
  1 /*
  2 宋代朱敦儒
  3 《西江月·世事短如春梦》
  4 世事短如春梦,人情薄似秋云。不须计较苦劳心。万事原来有命。
  5 幸遇三杯酒好,况逢一朵花新。片时欢笑且相亲。明日阴晴未定。 
  6 */
  7 #include <cstdio>
  8 #include <cstring>
  9 #include <algorithm>
 10 #include <cmath>
 11 #include <queue>
 12 #include <vector>
 13 #include <iostream>
 14 #include <string>
 15 #include <ctime>
 16 #define LOCAL
 17 const int MAXN = 202000 + 10;
 18 const long long MOD = (479ll<<21ll) + 1;//费马数论变换的费马素数 
 19 long long G = 3;//元根 
 20 using namespace std;
 21 typedef long long ll;
 22 ll x1[MAXN], x2[MAXN];
 23 ll Inv[MAXN], wn[MAXN];
 24 ll Inv2[MAXN];
 25 char a[MAXN], b[MAXN];
 26 
 27 ll pow(ll a, ll b){
 28    if (b == 0) return 1 % MOD;
 29    if (b == 1) return a % MOD;
 30    ll tmp = pow(a, b / 2);
 31    if (b % 2 == 0) return (tmp * tmp) % MOD;
 32    else return ((tmp * tmp) % MOD * (a % MOD)) % MOD;
 33 }
 34 ll exgcd(ll a, ll b, ll &x, ll &y){
 35    if (b == 0){x = 1ll; y = 0; return a;}
 36    ll tmp = exgcd(b, a % b, y, x);
 37    y -= x * (a / b);
 38    return tmp;
 39 }
 40 ll inv(ll a, ll p){
 41    ll x, y;
 42    ll tmp = exgcd(a, p, x, y);
 43    return ((x % MOD) + MOD) % MOD; 
 44 }
 45 void change(ll *x, int len, int loglen){
 46      for (int i = 0; i < len; i++){
 47          int t = i, k = 0, tmp = loglen;
 48          while (tmp--) {k = (k << 1) + (t & 1); t >>= 1;}
 49          if (k < i) swap(x[i], x[k]);
 50      }
 51      return;
 52 }
 53 void FNT(ll *x, int len, int loglen, int type){
 54      if (type) change(x, len, loglen);
 55      int t;
 56      t = (type ? 1: (1 << loglen));
 57      for (int i = 0; i < loglen; i++){
 58          if (!type) t >>= 1;
 59          int l = 0, r = l + t;
 60          while (l < len){
 61                ll a, b;
 62                ll tmp = 1ll, w = wn[t] % MOD;
 63                if (!type) w = Inv[t];
 64                for (int j = l; j < l + t; j++){
 65                    if (type){
 66                       a = x[j] % MOD;
 67                       b = (x[j + t] * (tmp % MOD)) % MOD;
 68                       x[j] = (a + b) % MOD;
 69                       x[j + t] = ((a - b) % MOD + MOD) % MOD; 
 70                    }else{
 71                       a = (x[j] + x[j + t]) % MOD;
 72                       b = ((((x[j] - x[j + t]) % MOD + MOD) % MOD) * tmp) % MOD;
 73                       x[j] = a;
 74                       x[j + t] = b;
 75                    }
 76                    tmp = (tmp * w) % MOD;
 77                }
 78                l = r + t;
 79                r = l + t;
 80          } 
 81          if (type) t <<= 1;
 82      }
 83      if (!type){
 84         change(x, len, loglen);
 85         for (int i = 0; i < len; i++) x[i] = (x[i] % MOD * Inv2[len]) % MOD;
 86      }
 87 }
 88 int work(char *a, char *b){
 89      int len1, len2, loglen = 0;
 90      len1 = strlen(a);
 91      len2 = strlen(b);
 92      while ((1 << loglen) < (max(len1, len2) << 1)) loglen++;
 93      for (int i = 0; i < len1; i++) x1[i] = 1ll * (a[i] - '0');
 94      for (int i = 0; i < len2; i++) x2[i] = 1ll * (b[i] - '0');
 95      for (int i = len1; i < (1<<loglen); i++) x1[i] = 0;
 96      for (int i = len2; i < (1<<loglen); i++) x2[i] = 0;
 97      FNT(x1, (1<<loglen), loglen, 1);
 98      FNT(x2, (1<<loglen), loglen, 1);
 99      for (int i = 0; i < (1<<loglen); i++) x1[i] = (x1[i] * x2[i]) % MOD;
100      FNT(x1, (1<<loglen), loglen, 0);
101      
102      int len;
103      ll over, t;
104      over = 0;
105      len = 0;
106      for (int i = (len1 + len2) - 2; i >= 0; i--){
107          t = x1[i] + over;
108          a[len++] = t % 10;
109          over = t / 10;
110      }
111      while (over){
112            a[len++] = over % 10;
113            over /= 10;
114      }
115      return len;
116 }
117 void print(char *t, int len){
118      for (; len >= 0 && !t[len]; len--);
119      if (len < 0) printf("0");
120      else for (int i = len; i >= 0; i--) printf("%c", t[i] + '0');
121      printf("
");
122 }
123 void prepare(){
124      wn[0] = MOD - 1;
125      for (int i = 1; i < 200010; i++){
126          if (i != 1 && (MOD - 1) / (i * 2) == (MOD - 1) / ((i - 1) * 2)){
127             wn[i] = wn[i - 1];
128             Inv[i] = Inv[i - 1];
129          }else{
130             wn[i] = pow(G, (MOD - 1) / (2 * i));
131             Inv[i] = inv(wn[i], MOD);
132          }
133          Inv2[i] = inv(i, MOD); 
134      }
135 }
136 
137 int main() {
138     memset(a, 0, sizeof(a));
139     memset(b, 0, sizeof(b));
140     prepare();
141     while (scanf("%s%s", a, b) != EOF){
142           print(a, work(a, b));
143           memset(a, 0, sizeof(a));
144           memset(b, 0, sizeof(b));
145     }
146     return 0;
147 }
View Code
原文地址:https://www.cnblogs.com/hoskey/p/4378720.html