[OI - 高精度]高精度模板

Posted aiyi2000

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[OI - 高精度]高精度模板相关的知识,希望对你有一定的参考价值。

1.高精度加法

复杂度O(n)

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 
 6 using namespace std;
 7 #define DEBUG(x) cerr << #x << "=" << x << endl
 8 const int L = 110; 
 9 
10 string a, b;
11 
12 string add(string a, string b)//只限两个非负整数相加 
13 {
14     string ans;
15     int na[L] = {0};
16     int nb[L] = {0};
17     int la = a.size();
18     int lb = b.size();
19     for (int i = 0; i < la; i++) 
20         na[la - 1 - i] = a[i] - 0;
21     for (int i = 0; i < lb; i++) 
22         nb[lb - 1 - i] = b[i] - 0;
23     int lmax = la > lb ? la : lb;
24     for (int i = 0; i < lmax; i++) 
25     {
26         na[i] += nb[i];
27         na[i + 1] += na[i] / 10;
28         na[i] %= 10;
29     } 
30     if (na[lmax]) lmax++;
31     for (int i = lmax - 1; i >= 0; i--) 
32         ans += na[i] + 0;
33     return ans;
34 }
35 
36 int main()
37 {
38     ios::sync_with_stdio(false);
39     cin.tie(0);
40     while (cin >> a >> b) 
41         cout << add(a, b) << endl;
42     return 0;
43 }

2.高精度减法

复杂度O(n)

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstdlib>
  4 #include <cstring> 
  5 
  6 using namespace std;
  7 //#define DEBUG(x) cerr << #x << "=" << x << endl
  8 typedef unsigned char BYTE;
  9 
 10 BYTE a[10005] = {0};
 11 BYTE b[10005] = {0};
 12 BYTE *pa = 0, *pb = 0;
 13 int la, lb;
 14 int sign;
 15 
 16 int main()
 17 {
 18     scanf("%s", a);
 19     scanf("%s", b);
 20     la = strlen((char*)a);
 21     lb = strlen((char*)b);
 22     int i;
 23     for (int i = 0; i < la; i++)
 24     {
 25         a[i] -= 0;
 26     }
 27     for (int i = 0; i < lb; i++)
 28     {
 29         b[i] -= 0;
 30     }
 31     if (la > lb)
 32     {
 33         sign = 1;
 34     }
 35     else if (la < lb)
 36     {
 37         sign = 0;
 38     }
 39     else 
 40     {
 41         sign = -1;
 42         int BCT;
 43         for (BCT = 0; BCT < la; BCT++)
 44         {
 45             if (a[BCT] > b[BCT])
 46             {
 47                 sign = 1;
 48                 break;
 49             }
 50             if (a[BCT] < b[BCT])
 51             {
 52                 sign = 0;
 53                 break;
 54             }
 55         }
 56         if (sign == -1)
 57         {
 58             printf("0");
 59             return 0;
 60         }
 61     }
 62     if (sign == 1)
 63     {
 64         pa = a;
 65         pb = b;
 66     }
 67     else 
 68     {
 69         pa = b;
 70         pb = a;
 71         int buf;
 72         buf = la;
 73         la = lb;
 74         lb = buf;
 75     }
 76     memmove(pb + la - lb, pb, lb);
 77     memset(pb, 0, la - lb);
 78     for (int i = 0; i < la; i++)
 79     {
 80         pb[i] = 9 - pb[i];
 81     }
 82     pb[la - 1]++;
 83     for (int i = la - 1; i >= 0; i--)
 84     {
 85         pa[i] += pb[i];
 86         if (pa[i] >= 10)
 87         {
 88             pa[i] -= 10;
 89             if (i != 0)
 90             {
 91                 pa[i - 1]++;
 92             }
 93         }
 94     }
 95     for (int i = 0; i < la; i++)
 96     {
 97         pa[i] += 0;
 98     }
 99     if (sign == 0)
100     {
101         printf("-");
102     }
103     for (int i = 0; i < la; i++)
104     {
105         if (pa[i] != 0)
106         {
107             printf((char*)pa + i);
108             return 0;
109         }
110     }
111     return 0;
112 }

3.高精度乘法

复杂度O(n*n)

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 
 6 using namespace std;
 7 //#define DEBUG(x) cerr << #x << "=" << x << endl
 8 const int L = 110;
 9 
10 string a, b;
11 
12 string mul(string a, string b)
13 {
14     string s;
15     int na[L];
16     int nb[L];
17     int nc[L];
18     int La = a.size();
19     int Lb = b.size();
20     fill(na, na + L, 0);
21     fill(nb, nb + L, 0);
22     fill(nc, nc + L, 0);
23     for (int i = La - 1; i >= 0; i--)
24         na[La - i] = a[i] - 0;
25     for (int i = Lb - 1; i >= 0; i--)
26         nb[Lb - i] = b[i] - 0;
27     for (int i = 1; i <= La; i++)
28     {
29         for (int j = 1; j <= Lb; j++)
30         {
31             nc[i + j - 1] += na[i] * nb[j];
32         }
33     }
34     for (int i = 1; i <= La + Lb; i++)
35     {
36         nc[i + 1] += nc[i] / 10;
37         nc[i] %= 10;
38     }
39     if (nc[La + Lb]) 
40        s += nc[La + Lb] + 0;
41     for (int i = La + Lb - 1; i >= 1; i--)
42         s += nc[i] + 0;
43     return s;  
44 }
45 
46 int main()
47 {
48     while (cin >> a >> b) 
49         cout << mul(a, b) << endl;
50     return 0;
51 }

4.高精度乘法FFT优化

复杂度O(nlogn)

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <cmath>
  6 
  7 using namespace std;
  8 //#define DEBUG(x) cerr << #x << "=" << x << endl
  9 #define L(x) (1 << (x))
 10 const double PI = acos(-1.0);
 11 const int maxn = 133015;
 12 
 13 double ax[maxn], ay[maxn], bx[maxn], by[maxn];
 14 char sa[maxn / 2], sb[maxn / 2];
 15 int sum[maxn];
 16 int x1[maxn], x2[maxn];
 17 string a, b;
 18 
 19 int max(int a, int b)
 20 {
 21     return a > b ? a : b;
 22 }
 23 
 24 int revv(int x, int bits)
 25 {
 26     int ret = 0;
 27     for (int i = 0; i < bits; i++)
 28     {
 29         ret <<= 1;
 30         ret |= x & 1;
 31         x >>= 1;
 32     }
 33     return ret;
 34 }
 35 
 36 void fft(double *a, double *b, int n, bool rev)
 37 {
 38     int bits = 0;
 39     while (1 << bits < n) 
 40         ++bits;
 41     for (int i = 0; i < n; i++)
 42     {
 43         int j = revv(i, bits);
 44         if (i < j)
 45         {
 46             swap(a[i], a[j]);
 47             swap(b[i], b[j]);
 48         }
 49     }
 50     for (int len = 2; len <= n; len <<= 1)
 51     {
 52         int half = len >> 1;
 53         double wmx = cos(2 * PI / len);
 54         double wmy = sin(2 * PI / len);
 55         if (rev)
 56             wmy = -wmy;
 57         for (int i = 0; i < n; i += len)
 58         {
 59             double wx = 1;
 60             double wy = 0;
 61             for (int j = 0; j < half; j++)
 62             {
 63                 double cx = a[i + j];
 64                 double cy = b[i + j];
 65                 double dx = a[i + j + half];
 66                 double dy = b[i + j + half];
 67                 double ex = dx * wx - dy * wy;
 68                 double ey = dx * wy + dy * wx;
 69                 a[i + j] = cx + ex;
 70                 b[i + j] = cy + ey;
 71                 a[i + j + half] = cx - ex;
 72                 b[i + j + half] = cy - ey;
 73                 double wnx = wx * wmx - wy * wmy;
 74                 double wny = wx * wmy + wy * wmx;
 75                 wx = wnx;
 76                 wy = wny;
 77             }
 78         }
 79     }
 80     if (rev)
 81     {
 82         for (int i = 0; i < n; i++)
 83         {
 84             a[i] /= n;
 85             b[i] /= n;
 86         }
 87     }
 88 }
 89 
 90 int solve(int a[], int na, int b[], int nb, int ans[])
 91 {
 92     int len = max(na, nb);
 93     int ln;
 94     for (int ln = 0; L(ln) < len; ++ln)
 95         len = L(++ln);
 96     for (int i = 0; i < len; ++i)
 97     {
 98         if (i >= na)
 99         {
100             ax[i] = 0;                                                            
101             ay[i] = 0;
102         }             
103         else
104         {
105             ax[i] = a[i];
106             ay[i] = 0;
107         }                         
108     }
109     fft(ax, ay, len, 0);
110     for (int i = 0; i < len; ++i)
111     {
112         if (i >= nb)
113         {
114             bx[i] = 0;
115             by[i] = 0;
116         }
117         else 
118         {
119             bx[i] = b[i];
120             by[i] = 0;
121         }
122     }
123     fft(bx, by, len, 0);
124     for (int i = 0; i < len; ++i)
125     {
126         double cx = ax[i] * bx[i] - ay[i] * by[i];
127         double cy = ax[i] * by[i] + ay[i] * bx[i];
128         ax[i] = cx;
129         ay[i] = cy;
130     }
131     fft(ax, ay, len, 1);
132     for (int i = 0; i < len; ++i)
133         ans[i] = (int)(ax[i] + 0.5);
134     return len;
135 }
136 
137 string mul(string sa, string sb)
138 {
139     int l1, l2, l;
140     int i;
141     string ans;
142     memset(sum, 0, sizeof(sum));
143     l1 = sa.size();
144     l2 = sb.size();
145     for (int i = 0; i < l1; i++)
146         x1[i] = sa[l1 - i - 1] - 0;
147     for (int i = 0; i < l2; i++)
148         x2[i] = sb[l2 - i - 1] - 0;
149     l = solve(x1, l1, x2, l2, sum);
150     for (int i = 0; i < l || sum[i] >= 10; i++)
151     {
152         sum[i + 1] += sum[i] / 10;
153         sum[i] %= 10;
154     }
155     l = i;
156     while (sum[l] <= 0 && l > 0)
157         l--;
158     for (int i = l; i >= 0; i--)
159         ans += sum[i] + 0;
160     return ans;
161 }
162 
163 int main()
164 {
165     ios::sync_with_stdio(false);
166     cin.tie(0);
167     while (cin >> a >> b)
168         cout << mul(a, b) << endl;
169     return 0;
170 }

5.高精度乘单精度乘法

6.高精度除法(包括取模)

7.高精度除单精度除法

8.高精度对单精度取模

9.高精度阶乘

10.高精度幂

11.高精度GCD

12.高精度进制转换

13.高精度平方根

以上是关于[OI - 高精度]高精度模板的主要内容,如果未能解决你的问题,请参考以下文章

大数高精度运算(模板)

OI队内测试——石门一

[Template]高精度模板

OI已学知识点总结

模板 高精度运算

GLSL-片段着色器不同部分的精度不同