Code[VS] 3123 高精度练习之超大整数乘法

Posted You Siki

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Code[VS] 3123 高精度练习之超大整数乘法相关的知识,希望对你有一定的参考价值。

FFT 做 高精度乘法

  1 #include <bits/stdc++.h>
  2 
  3 const double pi = acos(-1);
  4 
  5 struct complex
  6 {
  7     double a, b;
  8     
  9     inline complex(
 10         double _a = 0,
 11         double _b = 0) 
 12     {
 13         a = _a;
 14         b = _b;
 15     }
 16     
 17     inline friend complex operator +
 18     (const complex &a, const complex &b)
 19     {
 20         return complex(a.a + b.a, a.b + b.b);
 21     }
 22     
 23     inline friend complex operator - 
 24     (const complex &a, const complex &b)
 25     {
 26         return complex(a.a - b.a, a.b - b.b);
 27     }
 28     
 29     inline friend complex operator *
 30     (const complex &a, const complex &b)
 31     {
 32         return complex(a.a*b.a - a.b*b.b, a.a*b.b + a.b*b.a);
 33     }
 34     
 35     inline friend complex & operator +=
 36     (complex &a, const complex &b)
 37     {
 38         return a = a+b;
 39     }
 40     
 41     inline friend complex & operator -=
 42     (complex &a, const complex &b)
 43     {
 44         return a = a-b;
 45     }
 46     
 47     inline friend complex & operator *= 
 48     (complex &a, const complex &b)
 49     {
 50         return a = a*b;
 51     }
 52 };
 53 
 54 inline complex alpha(double a)
 55 {
 56     return complex(cos(a), sin(a));
 57 }
 58 
 59 typedef std::vector<complex> vec;
 60 
 61 vec FFT(const vec &a)
 62 {
 63     int n = a.size();
 64     
 65     if (n == 1)return a;
 66     
 67     complex w_k(1, 0);
 68     complex w_n = alpha(pi*2/n);
 69     
 70     vec ar[2], yr[2], y(n);
 71     
 72     for (int i = 0; i < n; ++i)
 73         ar[i & 1].push_back(a[i]);
 74         
 75     for (int i = 0; i < 2; ++i)
 76         yr[i] = FFT(ar[i]);
 77         
 78     for (int i = 0; i < n/2; ++i, w_k *= w_n)
 79     {
 80         y[i] = yr[0][i] + w_k * yr[1][i];
 81         y[i + n/2] = yr[0][i] - w_k * yr[1][i];
 82     }
 83         
 84     return y;
 85 }
 86 
 87 vec IFFT(const vec &a)
 88 {
 89     int n = a.size();
 90     
 91     if (n == 1)return a;
 92     
 93     complex w_k(1, 0);
 94     complex w_n = alpha(-pi*2/n);
 95     
 96     vec ar[2], yr[2], y(n);
 97     
 98     for (int i = 0; i < n; ++i)
 99         ar[i & 1].push_back(a[i]);
100         
101     for (int i = 0; i < 2; ++i)
102         yr[i] = IFFT(ar[i]);
103         
104     for (int i = 0; i < n/2; ++i, w_k *= w_n)
105     {
106         y[i] = yr[0][i] + w_k * yr[1][i];
107         y[i + n/2] = yr[0][i] - w_k * yr[1][i];
108     }
109         
110     return y;
111 }
112 
113 char s1[100005]; int len1;
114 char s2[100005]; int len2;
115 
116 vec v1, v2, p1, p2, mul, ans;
117 
118 signed main(void)
119 {
120     scanf("%s", s1); len1 = strlen(s1);
121     scanf("%s", s2); len2 = strlen(s2);
122     
123     int len = len1 + len2;
124     
125     while (len != (len&-len))++len;
126     
127     for (int i = len1 - 1; ~i; --i)v1.push_back(complex(s1[i] - 0, 0));
128     for (int i = len2 - 1; ~i; --i)v2.push_back(complex(s2[i] - 0, 0));
129     
130     while ((int)v1.size() < len)v1.push_back(complex());
131     while ((int)v2.size() < len)v2.push_back(complex());
132     
133     p1 = FFT(v1);
134     p2 = FFT(v2);
135     
136     for (int i = 0; i < len; ++i)
137         mul.push_back(p1[i] * p2[i]);
138         
139     ans = IFFT(mul);
140     
141     std::vector<int> ret;
142     
143     for (int i = 0; i < len; ++i)
144         ret.push_back((int)round(ans[i].a / len));
145         
146     for (int i = 0; i < len; ++i)
147         if (ret[i] >= 10)
148         {
149             ret[i + 1] += ret[i] / 10;
150             ret[i] %= 10;
151         }
152         
153     while (ret.size() != 1 && !ret[ret.size() - 1])
154         ret.pop_back();
155         
156     for (int i = ret.size() - 1; i >= 0; --i)
157         putchar(0 + ret[i]);
158     putchar(\n);
159 }

@Author: YouSiki

以上是关于Code[VS] 3123 高精度练习之超大整数乘法的主要内容,如果未能解决你的问题,请参考以下文章

[code3119]高精度练习之大整数开根

3118 高精度练习之除法

codevs 3119 高精度练习之大整数开根 (各种高精+压位)

3116 高精度练习之加法

3117 高精度练习之乘法

3115 高精度练习之减法