[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 - 高精度]高精度模板的主要内容,如果未能解决你的问题,请参考以下文章