Advertisement
BaoJIaoPisu

Untitled

Oct 15th, 2022
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.54 KB | None | 0 0
  1. const int base = 1000000000;
  2. const int base_digits = 9;
  3. struct BigNum {
  4. vector<int> a;
  5. int sign;
  6. /*<arpa>*/
  7. int size() {
  8. if (a.empty())return 0;
  9. int ans = (a.size() - 1) * base_digits;
  10. int ca = a.back();
  11. while (ca)
  12. ans++, ca /= 10;
  13. return ans;
  14. }
  15. BigNum operator ^(const BigNum &v) {
  16. BigNum ans = 1, a = *this, b = v;
  17. while (!b.isZero()) {
  18. if (b % 2)
  19. ans *= a;
  20. a *= a, b /= 2;
  21. }
  22. return ans;
  23. }
  24. string to_string() {
  25. stringstream ss;
  26. ss << *this;
  27. string s;
  28. ss >> s;
  29. return s;
  30. }
  31. int sumof() {
  32. string s = to_string();
  33. int ans = 0;
  34. for (auto c : s) ans += c - '0';
  35. return ans;
  36. }
  37. /*</arpa>*/
  38. BigNum() :
  39. sign(1) {
  40. }
  41.  
  42. BigNum(long long v) {
  43. *this = v;
  44. }
  45.  
  46. BigNum(const string &s) {
  47. read(s);
  48. }
  49.  
  50. void operator=(const BigNum &v) {
  51. sign = v.sign;
  52. a = v.a;
  53. }
  54.  
  55. void operator=(long long v) {
  56. sign = 1;
  57. a.clear();
  58. if (v < 0)
  59. sign = -1, v = -v;
  60. for (; v > 0; v = v / base)
  61. a.push_back(v % base);
  62. }
  63.  
  64. BigNum operator+(const BigNum &v) const {
  65. if (sign == v.sign) {
  66. BigNum res = v;
  67.  
  68. for (int i = 0, carry = 0; i < (int) max(a.size(), v.a.size()) || carry; ++i) {
  69. if (i == (int) res.a.size())
  70. res.a.push_back(0);
  71. res.a[i] += carry + (i < (int) a.size() ? a[i] : 0);
  72. carry = res.a[i] >= base;
  73. if (carry)
  74. res.a[i] -= base;
  75. }
  76. return res;
  77. }
  78. return *this - (-v);
  79. }
  80.  
  81. BigNum operator-(const BigNum &v) const {
  82. if (sign == v.sign) {
  83. if (abs() >= v.abs()) {
  84. BigNum res = *this;
  85. for (int i = 0, carry = 0; i < (int) v.a.size() || carry; ++i) {
  86. res.a[i] -= carry + (i < (int) v.a.size() ? v.a[i] : 0);
  87. carry = res.a[i] < 0;
  88. if (carry)
  89. res.a[i] += base;
  90. }
  91. res.trim();
  92. return res;
  93. }
  94. return -(v - *this);
  95. }
  96. return *this + (-v);
  97. }
  98.  
  99. void operator*=(int v) {
  100. if (v < 0)
  101. sign = -sign, v = -v;
  102. for (int i = 0, carry = 0; i < (int) a.size() || carry; ++i) {
  103. if (i == (int) a.size())
  104. a.push_back(0);
  105. long long cur = a[i] * (long long) v + carry;
  106. carry = (int) (cur / base);
  107. a[i] = (int) (cur % base);
  108. //asm("divl %%ecx" : "=a"(carry), "=d"(a[i]) : "A"(cur), "c"(base));
  109. }
  110. trim();
  111. }
  112.  
  113. BigNum operator*(int v) const {
  114. BigNum res = *this;
  115. res *= v;
  116. return res;
  117. }
  118.  
  119.  
  120. friend pair<BigNum, BigNum> divmod(const BigNum &a1, const BigNum &b1) {
  121. int norm = base / (b1.a.back() + 1);
  122. BigNum a = a1.abs() * norm;
  123. BigNum b = b1.abs() * norm;
  124. BigNum q, r;
  125. q.a.resize(a.a.size());
  126.  
  127. for (int i = a.a.size() - 1; i >= 0; i--) {
  128. r *= base;
  129. r += a.a[i];
  130. int s1 = r.a.size() <= b.a.size() ? 0 : r.a[b.a.size()];
  131. int s2 = r.a.size() <= b.a.size() - 1 ? 0 : r.a[b.a.size() - 1];
  132. int d = ((long long) base * s1 + s2) / b.a.back();
  133. r -= b * d;
  134. while (r < 0)
  135. r += b, --d;
  136. q.a[i] = d;
  137. }
  138.  
  139. q.sign = a1.sign * b1.sign;
  140. r.sign = a1.sign;
  141. q.trim();
  142. r.trim();
  143. return make_pair(q, r / norm);
  144. }
  145.  
  146. BigNum operator/(const BigNum &v) const {
  147. return divmod(*this, v).first;
  148. }
  149.  
  150. BigNum operator%(const BigNum &v) const {
  151. return divmod(*this, v).second;
  152. }
  153.  
  154. void operator/=(int v) {
  155. if (v < 0)
  156. sign = -sign, v = -v;
  157. for (int i = (int) a.size() - 1, rem = 0; i >= 0; --i) {
  158. long long cur = a[i] + rem * (long long) base;
  159. a[i] = (int) (cur / v);
  160. rem = (int) (cur % v);
  161. }
  162. trim();
  163. }
  164.  
  165. BigNum operator/(int v) const {
  166. BigNum res = *this;
  167. res /= v;
  168. return res;
  169. }
  170.  
  171. int operator%(int v) const {
  172. if (v < 0)
  173. v = -v;
  174. int m = 0;
  175. for (int i = a.size() - 1; i >= 0; --i)
  176. m = (a[i] + m * (long long) base) % v;
  177. return m * sign;
  178. }
  179.  
  180. void operator+=(const BigNum &v) {
  181. *this = *this + v;
  182. }
  183. void operator-=(const BigNum &v) {
  184. *this = *this - v;
  185. }
  186. void operator*=(const BigNum &v) {
  187. *this = *this * v;
  188. }
  189. void operator/=(const BigNum &v) {
  190. *this = *this / v;
  191. }
  192.  
  193. bool operator<(const BigNum &v) const {
  194. if (sign != v.sign)
  195. return sign < v.sign;
  196. if (a.size() != v.a.size())
  197. return a.size() * sign < v.a.size() * v.sign;
  198. for (int i = a.size() - 1; i >= 0; i--)
  199. if (a[i] != v.a[i])
  200. return a[i] * sign < v.a[i] * sign;
  201. return false;
  202. }
  203.  
  204. bool operator>(const BigNum &v) const {
  205. return v < *this;
  206. }
  207. bool operator<=(const BigNum &v) const {
  208. return !(v < *this);
  209. }
  210. bool operator>=(const BigNum &v) const {
  211. return !(*this < v);
  212. }
  213. bool operator==(const BigNum &v) const {
  214. return !(*this < v) && !(v < *this);
  215. }
  216. bool operator!=(const BigNum &v) const {
  217. return *this < v || v < *this;
  218. }
  219.  
  220. void trim() {
  221. while (!a.empty() && !a.back())
  222. a.pop_back();
  223. if (a.empty())
  224. sign = 1;
  225. }
  226.  
  227. bool isZero() const {
  228. return a.empty() || (a.size() == 1 && !a[0]);
  229. }
  230.  
  231. BigNum operator-() const {
  232. BigNum res = *this;
  233. res.sign = -sign;
  234. return res;
  235. }
  236.  
  237. BigNum abs() const {
  238. BigNum res = *this;
  239. res.sign *= res.sign;
  240. return res;
  241. }
  242.  
  243. long long longValue() const {
  244. long long res = 0;
  245. for (int i = a.size() - 1; i >= 0; i--)
  246. res = res * base + a[i];
  247. return res * sign;
  248. }
  249.  
  250. friend BigNum gcd(const BigNum &a, const BigNum &b) {
  251. return b.isZero() ? a : gcd(b, a % b);
  252. }
  253. friend BigNum lcm(const BigNum &a, const BigNum &b) {
  254. return a / gcd(a, b) * b;
  255. }
  256.  
  257. void read(const string &s) {
  258. sign = 1;
  259. a.clear();
  260. int pos = 0;
  261. while (pos < (int) s.size() && (s[pos] == '-' || s[pos] == '+')) {
  262. if (s[pos] == '-')
  263. sign = -sign;
  264. ++pos;
  265. }
  266. for (int i = s.size() - 1; i >= pos; i -= base_digits) {
  267. int x = 0;
  268. for (int j = max(pos, i - base_digits + 1); j <= i; j++)
  269. x = x * 10 + s[j] - '0';
  270. a.push_back(x);
  271. }
  272. trim();
  273. }
  274.  
  275. friend istream& operator>>(istream &stream, BigNum &v) {
  276. string s;
  277. stream >> s;
  278. v.read(s);
  279. return stream;
  280. }
  281.  
  282. friend ostream& operator<<(ostream &stream, const BigNum &v) {
  283. if (v.sign == -1)
  284. stream << '-';
  285. stream << (v.a.empty() ? 0 : v.a.back());
  286. for (int i = (int) v.a.size() - 2; i >= 0; --i)
  287. stream << setw(base_digits) << setfill('0') << v.a[i];
  288. return stream;
  289. }
  290.  
  291. static vector<int> convert_base(const vector<int> &a, int old_digits, int new_digits) {
  292. vector<long long> p(max(old_digits, new_digits) + 1);
  293. p[0] = 1;
  294. for (int i = 1; i < (int) p.size(); i++)
  295. p[i] = p[i - 1] * 10;
  296. vector<int> res;
  297. long long cur = 0;
  298. int cur_digits = 0;
  299. for (int i = 0; i < (int) a.size(); i++) {
  300. cur += a[i] * p[cur_digits];
  301. cur_digits += old_digits;
  302. while (cur_digits >= new_digits) {
  303. res.push_back((int)(cur % p[new_digits]));
  304. cur /= p[new_digits];
  305. cur_digits -= new_digits;
  306. }
  307. }
  308. res.push_back((int) cur);
  309. while (!res.empty() && !res.back())
  310. res.pop_back();
  311. return res;
  312. }
  313.  
  314. typedef vector<long long> vll;
  315.  
  316. static vll karatsubaMultiply(const vll &a, const vll &b) {
  317. int n = a.size();
  318. vll res(n + n);
  319. if (n <= 32) {
  320. for (int i = 0; i < n; i++)
  321. for (int j = 0; j < n; j++)
  322. res[i + j] += a[i] * b[j];
  323. return res;
  324. }
  325.  
  326. int k = n >> 1;
  327. vll a1(a.begin(), a.begin() + k);
  328. vll a2(a.begin() + k, a.end());
  329. vll b1(b.begin(), b.begin() + k);
  330. vll b2(b.begin() + k, b.end());
  331.  
  332. vll a1b1 = karatsubaMultiply(a1, b1);
  333. vll a2b2 = karatsubaMultiply(a2, b2);
  334.  
  335. for (int i = 0; i < k; i++)
  336. a2[i] += a1[i];
  337. for (int i = 0; i < k; i++)
  338. b2[i] += b1[i];
  339.  
  340. vll r = karatsubaMultiply(a2, b2);
  341. for (int i = 0; i < (int) a1b1.size(); i++)
  342. r[i] -= a1b1[i];
  343. for (int i = 0; i < (int) a2b2.size(); i++)
  344. r[i] -= a2b2[i];
  345.  
  346. for (int i = 0; i < (int) r.size(); i++)
  347. res[i + k] += r[i];
  348. for (int i = 0; i < (int) a1b1.size(); i++)
  349. res[i] += a1b1[i];
  350. for (int i = 0; i < (int) a2b2.size(); i++)
  351. res[i + n] += a2b2[i];
  352. return res;
  353. }
  354.  
  355. BigNum operator*(const BigNum &v) const {
  356. vector<int> a6 = convert_base(this->a, base_digits, 6);
  357. vector<int> b6 = convert_base(v.a, base_digits, 6);
  358. vll a(a6.begin(), a6.end());
  359. vll b(b6.begin(), b6.end());
  360. while (a.size() < b.size())
  361. a.push_back(0);
  362. while (b.size() < a.size())
  363. b.push_back(0);
  364. while (a.size() & (a.size() - 1))
  365. a.push_back(0), b.push_back(0);
  366. vll c = karatsubaMultiply(a, b);
  367. BigNum res;
  368. res.sign = sign * v.sign;
  369. for (int i = 0, carry = 0; i < (int) c.size(); i++) {
  370. long long cur = c[i] + carry;
  371. res.a.push_back((int) (cur % 1000000));
  372. carry = (int) (cur / 1000000);
  373. }
  374. res.a = convert_base(res.a, 6, base_digits);
  375. res.trim();
  376. return res;
  377. }
  378. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement