zoukankan      html  css  js  c++  java
  • 数论-FFT高精度乘法

    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("
    
    %s %s
    
     %lld %lld
    ", str1, str2, l1, l2);
    61     LL a = 1, x = 0;
    62     while (a < l1+l2-1) a <<= 1, ++x;
    63 //    printf("
    
    a = %lld, x = %lld
    
    ", 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
    "); return 0; }
    73     if (flag1 ^ flag2) putchar('-');
    74     while (i >= 0) putchar(Ans[i] + '0'), --i;
    75     putchar('
    ');
    76     return 0;
    77 }

    题目

    P3071【高精度】a*b
    时间限制 : 10000 MS   空间限制 : 65536 KB
    问题描述

    给你两个正整数a,b,计算它们的乘积。

    输入格式

    第一行一个正整数a
    第二行一个正整数b

    输出格式

    一行,表示a*b

    样例输入

    111222333444555666777888999
    999888777666555444333222111

    样例输出

    111209963037098814851876554444456814851901296370456889

    提示

    a,b分别不超过100000位


    来源  感谢nodgd放题并提供数据
  • 相关阅读:
    wpf Behavior
    wpf Trigger
    语法糖
    Lambda 表达式
    wpf 3D动画
    IEnumerable接口学习
    Delegates, Events, and Anonymous Methods 委托、事件与匿名方法
    wpf 平滑效果随记
    软件工程第一篇博客
    记考研高数第一课
  • 原文地址:https://www.cnblogs.com/ghcred/p/8877051.html
Copyright © 2011-2022 走看看