Advertisement
Guest User

Untitled

a guest
Mar 27th, 2017
42
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.67 KB | None | 0 0
  1. const int base = 1000000000;
  2. const int base_digits = 9;
  3. struct bigint {
  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. bigint operator ^(const bigint &v){
  16. bigint 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. bigint() :
  39. sign(1) {
  40. }
  41.  
  42. bigint(long long v) {
  43. *this = v;
  44. }
  45.  
  46. bigint(const string &s) {
  47. read(s);
  48. }
  49.  
  50. void operator=(const bigint &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. bigint operator+(const bigint &v) const {
  65. if (sign == v.sign) {
  66. bigint 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. bigint operator-(const bigint &v) const {
  82. if (sign == v.sign) {
  83. if (abs() >= v.abs()) {
  84. bigint 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. bigint operator*(int v) const {
  114. bigint res = *this;
  115. res *= v;
  116. return res;
  117. }
  118.  
  119. friend pair<bigint, bigint> divmod(const bigint &a1, const bigint &b1) {
  120. int norm = base / (b1.a.back() + 1);
  121. bigint a = a1.abs() * norm;
  122. bigint b = b1.abs() * norm;
  123. bigint q, r;
  124. q.a.resize(a.a.size());
  125.  
  126. for (int i = a.a.size() - 1; i >= 0; i--) {
  127. r *= base;
  128. r += a.a[i];
  129. int s1 = r.a.size() <= b.a.size() ? 0 : r.a[b.a.size()];
  130. int s2 = r.a.size() <= b.a.size() - 1 ? 0 : r.a[b.a.size() - 1];
  131. int d = ((long long) base * s1 + s2) / b.a.back();
  132. r -= b * d;
  133. while (r < 0)
  134. r += b, --d;
  135. q.a[i] = d;
  136. }
  137.  
  138. q.sign = a1.sign * b1.sign;
  139. r.sign = a1.sign;
  140. q.trim();
  141. r.trim();
  142. return make_pair(q, r / norm);
  143. }
  144.  
  145. bigint operator/(const bigint &v) const {
  146. return divmod(*this, v).first;
  147. }
  148.  
  149. bigint operator%(const bigint &v) const {
  150. return divmod(*this, v).second;
  151. }
  152.  
  153. void operator/=(int v) {
  154. if (v < 0)
  155. sign = -sign, v = -v;
  156. for (int i = (int) a.size() - 1, rem = 0; i >= 0; --i) {
  157. long long cur = a[i] + rem * (long long) base;
  158. a[i] = (int) (cur / v);
  159. rem = (int) (cur % v);
  160. }
  161. trim();
  162. }
  163.  
  164. bigint operator/(int v) const {
  165. bigint res = *this;
  166. res /= v;
  167. return res;
  168. }
  169.  
  170. int operator%(int v) const {
  171. if (v < 0)
  172. v = -v;
  173. int m = 0;
  174. for (int i = a.size() - 1; i >= 0; --i)
  175. m = (a[i] + m * (long long) base) % v;
  176. return m * sign;
  177. }
  178.  
  179. void operator+=(const bigint &v) {
  180. *this = *this + v;
  181. }
  182. void operator-=(const bigint &v) {
  183. *this = *this - v;
  184. }
  185. void operator*=(const bigint &v) {
  186. *this = *this * v;
  187. }
  188. void operator/=(const bigint &v) {
  189. *this = *this / v;
  190. }
  191.  
  192. bool operator<(const bigint &v) const {
  193. if (sign != v.sign)
  194. return sign < v.sign;
  195. if (a.size() != v.a.size())
  196. return a.size() * sign < v.a.size() * v.sign;
  197. for (int i = a.size() - 1; i >= 0; i--)
  198. if (a[i] != v.a[i])
  199. return a[i] * sign < v.a[i] * sign;
  200. return false;
  201. }
  202.  
  203. bool operator>(const bigint &v) const {
  204. return v < *this;
  205. }
  206. bool operator<=(const bigint &v) const {
  207. return !(v < *this);
  208. }
  209. bool operator>=(const bigint &v) const {
  210. return !(*this < v);
  211. }
  212. bool operator==(const bigint &v) const {
  213. return !(*this < v) && !(v < *this);
  214. }
  215. bool operator!=(const bigint &v) const {
  216. return *this < v || v < *this;
  217. }
  218.  
  219. void trim() {
  220. while (!a.empty() && !a.back())
  221. a.pop_back();
  222. if (a.empty())
  223. sign = 1;
  224. }
  225.  
  226. bool isZero() const {
  227. return a.empty() || (a.size() == 1 && !a[0]);
  228. }
  229.  
  230. bigint operator-() const {
  231. bigint res = *this;
  232. res.sign = -sign;
  233. return res;
  234. }
  235.  
  236. bigint abs() const {
  237. bigint res = *this;
  238. res.sign *= res.sign;
  239. return res;
  240. }
  241.  
  242. long long longValue() const {
  243. long long res = 0;
  244. for (int i = a.size() - 1; i >= 0; i--)
  245. res = res * base + a[i];
  246. return res * sign;
  247. }
  248.  
  249. friend bigint gcd(const bigint &a, const bigint &b) {
  250. return b.isZero() ? a : gcd(b, a % b);
  251. }
  252. friend bigint lcm(const bigint &a, const bigint &b) {
  253. return a / gcd(a, b) * b;
  254. }
  255.  
  256. void read(const string &s) {
  257. sign = 1;
  258. a.clear();
  259. int pos = 0;
  260. while (pos < (int) s.size() && (s[pos] == '-' || s[pos] == '+')) {
  261. if (s[pos] == '-')
  262. sign = -sign;
  263. ++pos;
  264. }
  265. for (int i = s.size() - 1; i >= pos; i -= base_digits) {
  266. int x = 0;
  267. for (int j = max(pos, i - base_digits + 1); j <= i; j++)
  268. x = x * 10 + s[j] - '0';
  269. a.push_back(x);
  270. }
  271. trim();
  272. }
  273.  
  274. friend istream& operator>>(istream &stream, bigint &v) {
  275. string s;
  276. stream >> s;
  277. v.read(s);
  278. return stream;
  279. }
  280.  
  281. friend ostream& operator<<(ostream &stream, const bigint &v) {
  282. if (v.sign == -1)
  283. stream << '-';
  284. stream << (v.a.empty() ? 0 : v.a.back());
  285. for (int i = (int) v.a.size() - 2; i >= 0; --i)
  286. stream << setw(base_digits) << setfill('0') << v.a[i];
  287. return stream;
  288. }
  289.  
  290. static vector<int> convert_base(const vector<int> &a, int old_digits, int new_digits) {
  291. vector<long long> p(max(old_digits, new_digits) + 1);
  292. p[0] = 1;
  293. for (int i = 1; i < (int) p.size(); i++)
  294. p[i] = p[i - 1] * 10;
  295. vector<int> res;
  296. long long cur = 0;
  297. int cur_digits = 0;
  298. for (int i = 0; i < (int) a.size(); i++) {
  299. cur += a[i] * p[cur_digits];
  300. cur_digits += old_digits;
  301. while (cur_digits >= new_digits) {
  302. res.push_back(int(cur % p[new_digits]));
  303. cur /= p[new_digits];
  304. cur_digits -= new_digits;
  305. }
  306. }
  307. res.push_back((int) cur);
  308. while (!res.empty() && !res.back())
  309. res.pop_back();
  310. return res;
  311. }
  312.  
  313. typedef vector<long long> vll;
  314.  
  315. static vll karatsubaMultiply(const vll &a, const vll &b) {
  316. int n = a.size();
  317. vll res(n + n);
  318. if (n <= 32) {
  319. for (int i = 0; i < n; i++)
  320. for (int j = 0; j < n; j++)
  321. res[i + j] += a[i] * b[j];
  322. return res;
  323. }
  324.  
  325. int k = n >> 1;
  326. vll a1(a.begin(), a.begin() + k);
  327. vll a2(a.begin() + k, a.end());
  328. vll b1(b.begin(), b.begin() + k);
  329. vll b2(b.begin() + k, b.end());
  330.  
  331. vll a1b1 = karatsubaMultiply(a1, b1);
  332. vll a2b2 = karatsubaMultiply(a2, b2);
  333.  
  334. for (int i = 0; i < k; i++)
  335. a2[i] += a1[i];
  336. for (int i = 0; i < k; i++)
  337. b2[i] += b1[i];
  338.  
  339. vll r = karatsubaMultiply(a2, b2);
  340. for (int i = 0; i < (int) a1b1.size(); i++)
  341. r[i] -= a1b1[i];
  342. for (int i = 0; i < (int) a2b2.size(); i++)
  343. r[i] -= a2b2[i];
  344.  
  345. for (int i = 0; i < (int) r.size(); i++)
  346. res[i + k] += r[i];
  347. for (int i = 0; i < (int) a1b1.size(); i++)
  348. res[i] += a1b1[i];
  349. for (int i = 0; i < (int) a2b2.size(); i++)
  350. res[i + n] += a2b2[i];
  351. return res;
  352. }
  353.  
  354. bigint operator*(const bigint &v) const {
  355. vector<int> a6 = convert_base(this->a, base_digits, 6);
  356. vector<int> b6 = convert_base(v.a, base_digits, 6);
  357. vll a(a6.begin(), a6.end());
  358. vll b(b6.begin(), b6.end());
  359. while (a.size() < b.size())
  360. a.push_back(0);
  361. while (b.size() < a.size())
  362. b.push_back(0);
  363. while (a.size() & (a.size() - 1))
  364. a.push_back(0), b.push_back(0);
  365. vll c = karatsubaMultiply(a, b);
  366. bigint res;
  367. res.sign = sign * v.sign;
  368. for (int i = 0, carry = 0; i < (int) c.size(); i++) {
  369. long long cur = c[i] + carry;
  370. res.a.push_back((int) (cur % 1000000));
  371. carry = (int) (cur / 1000000);
  372. }
  373. res.a = convert_base(res.a, 6, base_digits);
  374. res.trim();
  375. return res;
  376. }
  377. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement