• 【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
  • 相关阅读:
    webpack的安装与配置
    npm初始化
    gitignore的配置
    git本地已有文件夹和远程仓库对应
    git 配置
    开发环境和开发工具
    git 码云使用教程
    递归
    LeetCode 392. 判断子序列
    MongoDB基本操作
  • 原文地址:https://www.cnblogs.com/hoskey/p/4378720.html
Copyright © 2020-2023  润新知