BigInt64.hpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735
  1. #ifndef BIGINT64_HPP
  2. #define BIGINT64_HPP
  3. #include <cstdint>
  4. #include <cstdlib>
  5. #include <cmath>
  6. #include <cassert>
  7. #include <algorithm>
  8. #include <iterator>
  9. #include <limits>
  10. #include <initializer_list>
  11. #include <deque>
  12. #include <vector>
  13. #include <string>
  14. #include <bitset>
  15. #include <iostream>
  16. const std::vector<char> chars = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
  17. const __uint128_t _m = ((__uint128_t)1) << 64;
  18. std::uint64_t _mulx_u64(std::uint64_t a, std::uint64_t b, std::uint64_t* hi){
  19. __uint128_t r = a * b;
  20. *hi = (r >> 64);
  21. return r;
  22. }
  23. template<typename T>
  24. inline int signum(T t){
  25. if(t < 0)return -1;
  26. if(t >= 0)return 1;
  27. assert(false);
  28. }
  29. inline std::ostream& operator<<(std::ostream& out, __uint128_t o){
  30. if(o == 0)return out << "0";
  31. while(o > 0){
  32. out << std::to_string((int)(o % 10));
  33. o /= 10;
  34. }
  35. return out;
  36. }
  37. struct BigInt{
  38. using size_t = std::size_t;
  39. using ssize_t = std::int64_t;
  40. using uint64_t = std::uint64_t;
  41. using uint32_t = std::uint32_t;
  42. using lui = ::__uint128_t;
  43. using iterator = std::deque<uint64_t>::iterator;
  44. using const_iterator = std::deque<uint64_t>::const_iterator;
  45. using reverse_iterator = std::deque<uint64_t>::reverse_iterator;
  46. using const_reverse_iterator = std::deque<uint64_t>::const_reverse_iterator;
  47. std::deque<uint64_t> data;
  48. int signum;
  49. inline BigInt() : data(1,0),signum(1){}
  50. inline BigInt(size_t _s, uint64_t fill) : data(_s, fill), signum(1){}
  51. inline BigInt(int a) : data(1, std::abs(a)),signum(::signum(a)){}
  52. inline BigInt(unsigned int a) : data(1, a),signum(1){}
  53. inline BigInt(unsigned long long a) : data(1, a), signum(1){}
  54. inline BigInt(long long a) : data(1, std::abs(a)),signum(::signum(a)){}
  55. inline BigInt(const std::initializer_list<uint64_t>& l) : data(l), signum(1){}
  56. inline BigInt(std::initializer_list<uint64_t>&& l) : data(std::move(l)), signum(1){}
  57. inline BigInt(const BigInt& o) : data(o.data), signum(o.signum){}
  58. inline BigInt(BigInt&& o) : data(std::move(o.data)), signum(o.signum){}
  59. inline BigInt(const std::string& o){
  60. signum = 1;
  61. auto it = o.rbegin();
  62. BigInt baseTen(1);
  63. while(it != o.rend()){
  64. if(*it == '-'){
  65. assert(it != o.rbegin());
  66. assert((++it) == o.rend());
  67. signum = -1;
  68. break;
  69. }
  70. BigInt l = baseTen.mult(BigInt(*it - '0'));
  71. adda(l);
  72. baseTen = baseTen.mult(BigInt(10));
  73. ++it;
  74. }
  75. trim();
  76. }
  77. template<typename InputIterator>
  78. inline BigInt(InputIterator begin, InputIterator end) : data(begin, end), signum(1){}
  79. template<typename RNG>
  80. inline BigInt(RNG& rng, size_t length) : data(length, 0), signum(1){std::generate(data.begin(),data.end(), [&rng](){return rng();});}
  81. inline std::deque<uint64_t>::iterator begin(){return data.begin();}
  82. inline std::deque<uint64_t>::iterator end(){return data.end();}
  83. inline std::deque<uint64_t>::reverse_iterator rbegin(){return data.rbegin();}
  84. inline std::deque<uint64_t>::reverse_iterator rend(){return data.rend();}
  85. inline std::deque<uint64_t>::const_iterator begin()const{return data.begin();}
  86. inline std::deque<uint64_t>::const_iterator end()const{return data.end();}
  87. inline std::deque<uint64_t>::const_reverse_iterator rbegin()const{return data.rbegin();}
  88. inline std::deque<uint64_t>::const_reverse_iterator rend()const{return data.rend();}
  89. inline uint64_t& operator[](size_t i){return data[i];}
  90. inline const uint64_t& operator[](size_t i)const{return data[i];}
  91. inline size_t size()const{return data.size();}
  92. inline auto cbegin()const{return data.cbegin();}
  93. inline auto cend()const{return data.cend();}
  94. inline auto crbegin()const{return data.crbegin();}
  95. inline auto crend()const{return data.crend();}
  96. inline BigInt& operator=(const BigInt& o){signum = o.signum;data = o.data;return *this;}
  97. inline BigInt& operator=(BigInt&& o){data = std::move(o.data);signum = o.signum;return *this;}
  98. inline size_t bitscanForward()const{
  99. auto it = begin();
  100. size_t s = 0;
  101. while(*it == 0 && it != end()){
  102. ++it;
  103. s += 64;
  104. }
  105. if(it == end())return s + 64;
  106. return s + __builtin_clzll(*it);
  107. }
  108. inline size_t bitscanReverse()const{
  109. auto it = rbegin();
  110. size_t s = 0;
  111. while(*it == 0 && it != rend()){
  112. ++it;
  113. s += 64;
  114. }
  115. if(it == rend())return s + 64;
  116. return s + __builtin_ctzll(*it);
  117. }
  118. inline bool operator<(const BigInt& o)const{
  119. if(signum > o.signum){
  120. return false;
  121. }
  122. if(signum < o.signum){
  123. return true;
  124. }
  125. const_iterator it1 = begin();
  126. const_iterator it2 = o.begin();
  127. if(size() > o.size()){
  128. it1 += size() - o.size();
  129. auto _t = begin();
  130. while(_t != it1){
  131. if(*_t)return false;
  132. ++_t;
  133. }
  134. }
  135. else if(size() < o.size()){
  136. it2 += o.size() - size();
  137. auto _t = o.begin();
  138. while(_t != it2){
  139. if(*_t)return true;
  140. ++_t;
  141. }
  142. }
  143. while(it1 != end() && it2 != o.end()){
  144. if(*(it1) < *(it2))return true;
  145. if(*(it1) > *(it2))return false;
  146. ++it1;++it2;
  147. }
  148. return false;
  149. }
  150. inline bool operator>(const BigInt& o)const{
  151. if(signum < o.signum){
  152. return false;
  153. }
  154. if(signum > o.signum){
  155. return true;
  156. }
  157. const_iterator it1 = begin();
  158. const_iterator it2 = o.begin();
  159. if(size() > o.size()){
  160. it1 += size() - o.size();
  161. auto _t = begin();
  162. while(_t != it1){
  163. if(*_t)return true;
  164. ++_t;
  165. }
  166. }
  167. else if(size() < o.size()){
  168. it2 += o.size() - size();
  169. auto _t = o.begin();
  170. while(_t != it2){
  171. if(*_t)return false;
  172. ++_t;
  173. }
  174. }
  175. while(it1 != end() && it2 != o.end()){
  176. if(*(it1) > *(it2))return true;
  177. if(*(it1) < *(it2))return false;
  178. ++it1;++it2;
  179. }
  180. return false;
  181. }
  182. inline bool operator<=(const BigInt& o)const{
  183. if(signum > o.signum){
  184. return false;
  185. }
  186. if(signum < o.signum){
  187. return true;
  188. }
  189. const_iterator it1 = begin();
  190. const_iterator it2 = o.begin();
  191. if(size() > o.size()){
  192. it1 += size() - o.size();
  193. auto _t = begin();
  194. while(_t != it1){
  195. if(*_t)return true;
  196. ++_t;
  197. }
  198. }
  199. else if(size() < o.size()){
  200. it2 += o.size() - size();
  201. auto _t = o.begin();
  202. while(_t != it2){
  203. if(*_t)return false;
  204. ++_t;
  205. }
  206. }
  207. while(it1 != end() && it2 != o.end()){
  208. if(*(it1) < *(it2))return true;
  209. if(*(it1) > *(it2))return false;
  210. ++it1;++it2;
  211. }
  212. return true;
  213. }
  214. inline bool operator>=(const BigInt& o)const{
  215. if(signum < o.signum){
  216. return false;
  217. }
  218. if(signum > o.signum){
  219. return true;
  220. }
  221. const_iterator it1 = begin();
  222. const_iterator it2 = o.begin();
  223. if(size() > o.size()){
  224. it1 += size() - o.size();
  225. auto _t = begin();
  226. while(_t != it1){
  227. if(*_t)return true;
  228. ++_t;
  229. }
  230. }
  231. else if(size() < o.size()){
  232. it2 += o.size() - size();
  233. auto _t = o.begin();
  234. while(_t != it2){
  235. if(*_t)return false;
  236. ++_t;
  237. }
  238. }
  239. while(it1 != end() && it2 != o.end()){
  240. if(*(it1) > *(it2))return true;
  241. if(*(it1) < *(it2))return false;
  242. ++it1;++it2;
  243. }
  244. return true;
  245. }
  246. inline bool operator==(const BigInt& o)const{
  247. if(signum < o.signum){
  248. return false;
  249. }
  250. if(signum > o.signum){
  251. return false;
  252. }
  253. const_iterator it1 = begin();
  254. const_iterator it2 = o.begin();
  255. if(size() > o.size()){
  256. it1 += size() - o.size();
  257. auto _t = begin();
  258. while(_t != it1){
  259. if(*_t)return false;
  260. ++_t;
  261. }
  262. }
  263. else if(size() < o.size()){
  264. it2 += o.size() - size();
  265. auto _t = o.begin();
  266. while(_t != it2){
  267. if(*_t)return false;
  268. ++_t;
  269. }
  270. }
  271. while(it1 != end() && it2 != o.end()){
  272. if(*(it1) != *(it2))return false;
  273. ++it1;++it2;
  274. }
  275. return true;
  276. }
  277. inline bool operator==(uint64_t o){
  278. return size() == 1 && *rbegin() == o;
  279. }
  280. inline bool isZero()const{
  281. for(auto it = data.begin();it != data.end();it++){
  282. if(*it)return false;
  283. }
  284. return true;
  285. }
  286. inline void setZero(){
  287. for(auto it = begin();it != end();it++)*it = 0;
  288. }
  289. inline BigInt& trim(){
  290. while(data[0] == 0 && data.size() > 1){
  291. data.pop_front();
  292. }
  293. return *this;
  294. }
  295. inline BigInt div(uint64_t d)const{
  296. BigInt ret = *this;
  297. lui carry = 0;
  298. for(auto it = ret.data.begin();it != ret.data.end();it++){
  299. lui temp = (lui)*it;
  300. temp += carry;
  301. carry = temp % d;
  302. *it = (uint64_t)(temp / d);
  303. carry <<= 64;
  304. }
  305. return ret;
  306. }
  307. inline BigInt& div(uint64_t d){
  308. lui carry = 0;
  309. for(auto it = data.begin();it != data.end();it++){
  310. lui temp = (lui)*it;
  311. temp += carry;
  312. carry = temp % d;
  313. *it = (uint64_t)(temp / d);
  314. carry <<= 64;
  315. }
  316. return *this;
  317. }
  318. inline uint64_t mod(uint64_t m)const{
  319. lui carry = 0;
  320. for(auto it = data.begin();it != data.end();it++){
  321. carry <<= 64;
  322. carry = (*it + carry) % m;
  323. }
  324. return carry;
  325. }
  326. inline BigInt& bitshiftLeft(int c){
  327. if(c < 0)return bitshiftRight(-c);
  328. unsigned int sh = c % 64;
  329. unsigned int jmp = c / 64;
  330. if((unsigned int)jmp >= size()){std::fill(begin(),end(),0);return *this;}
  331. auto it1 = begin();
  332. auto it2 = it1 + jmp;
  333. auto beforeEnd = end() - 1;
  334. while(it2 != beforeEnd){
  335. *it1 = (*it2 << sh);
  336. if(sh)
  337. *it1 |= (*(it2 + 1) >> (64 - sh));
  338. ++it1;++it2;
  339. }
  340. *it1 = (*it2 << sh);
  341. ++it1;++it2;
  342. while(it1 != end()){
  343. *it1 = 0;
  344. ++it1;
  345. }
  346. return *this;
  347. }
  348. inline BigInt& bitshiftLeft_expand(int c){
  349. if(c < 0)return bitshiftRight(-c);
  350. unsigned int sh = c % 64;
  351. unsigned int jmp = c / 64;
  352. int insert_count = std::max((size_t)0, jmp - bitscanForward() / 64 + 1);
  353. while(insert_count --> 0)
  354. data.push_front(0);
  355. auto it1 = begin();
  356. auto it2 = it1 + jmp;
  357. auto beforeEnd = end() - 1;
  358. while(it2 != beforeEnd){
  359. *it1 = (*it2 << sh);
  360. if(sh)
  361. *it1 |= (*(it2 + 1) >> (64 - sh));
  362. ++it1;++it2;
  363. }
  364. *it1 = (*it2 << sh);
  365. ++it1;++it2;
  366. while(it1 != end()){
  367. *it1 = 0;
  368. ++it1;
  369. }
  370. return *this;
  371. }
  372. inline BigInt& bitshiftRight(int c){
  373. if(c < 0)return bitshiftLeft(-c);
  374. unsigned int sh = c % 64;
  375. unsigned int jmp = c / 64;
  376. if((unsigned int)jmp >= size()){std::fill(begin(),end(),0);return *this;}
  377. auto it1 = rbegin();
  378. auto it2 = it1 + jmp;
  379. auto beforeRend = rend() - 1;
  380. while(it2 != beforeRend){
  381. *it1 = (*it2 >> sh);
  382. if(sh)
  383. *it1 |= (*(it2 + 1) << (64 - sh));
  384. ++it1;++it2;
  385. }
  386. *it1 = (*it2 >> sh);
  387. ++it1;++it2;
  388. while(it1 != rend()){
  389. *it1 = 0;
  390. ++it1;
  391. }
  392. return *this;
  393. }
  394. inline BigInt operator<<(int c)const{
  395. BigInt ret = *this;
  396. ret.bitshiftLeft(c);
  397. return ret;
  398. }
  399. inline BigInt operator>>(int c)const{
  400. BigInt ret = *this;
  401. ret.bitshiftRight(c);
  402. return ret;
  403. }
  404. inline BigInt& operator<<=(int c){
  405. return bitshiftLeft(c);
  406. }
  407. inline BigInt& operator>>=(int c){
  408. return bitshiftRight(c);
  409. }
  410. inline BigInt& operator&=(const BigInt& o){
  411. auto it1 = rbegin();
  412. auto it2 = o.rbegin();
  413. while(it1 != rend() && it2 != o.rend())
  414. *(it1++) &= *(it2++);
  415. return *this;
  416. }
  417. inline BigInt& operator|=(const BigInt& o){
  418. auto it1 = rbegin();
  419. auto it2 = o.rbegin();
  420. while(it1 != rend() && it2 != o.rend())
  421. *(it1++) |= *(it2++);
  422. return *this;
  423. }
  424. inline BigInt& operator^=(const BigInt& o){
  425. auto it1 = rbegin();
  426. auto it2 = o.rbegin();
  427. while(it1 != rend() && it2 != o.rend())
  428. *(it1++) ^= *(it2++);
  429. return *this;
  430. }
  431. inline BigInt operator&(const BigInt& o)const{
  432. BigInt ret(*this);
  433. ret &= o;
  434. return ret;
  435. }
  436. inline BigInt operator|(const BigInt& o)const{
  437. BigInt ret(*this);
  438. ret |= o;
  439. return ret;
  440. }
  441. inline BigInt operator^(const BigInt& o)const{
  442. BigInt ret(*this);
  443. ret ^= o;
  444. return ret;
  445. }
  446. inline BigInt& cut(size_t chunks){
  447. while(size() > chunks)data.pop_front();
  448. }
  449. inline int bitDifference(const BigInt& o){
  450. int pos1(0),pos2(0);
  451. auto it1 = begin();
  452. auto it2 = o.begin();
  453. bool bitfound = false;
  454. while(it1 != end()){
  455. if(*it1 == 0)
  456. pos1 += 64;
  457. else{
  458. pos1 += __builtin_clzll(*it1);
  459. bitfound = true;
  460. break;
  461. }
  462. ++it1;
  463. }
  464. if(!bitfound)pos1 = size() * 64;
  465. bitfound = false;
  466. while(it2 != o.end()){
  467. if(*it2 == 0)
  468. pos2 += 64;
  469. else{
  470. pos2 += __builtin_clzll(*it2);
  471. bitfound = true;
  472. break;
  473. }
  474. ++it2;
  475. }
  476. if(!bitfound)pos2 = o.size() * 64;
  477. int sizediff = ((signed int)size()) - ((signed int)o.size());
  478. return pos2 - pos1 + sizediff * 64;
  479. }
  480. inline BigInt& chunkshiftLeft(int c){
  481. if(c < 0)return chunkshiftRight(-c);
  482. if((unsigned int)c >= size()){std::fill(begin(),end(),0);return *this;}
  483. auto it1 = data.begin();
  484. auto it2 = it1 + c;
  485. while(it2 != data.end())*(it1++) = *(it2++);
  486. while(it1 != data.end())*(it1++) = 0;
  487. return *this;
  488. }
  489. inline BigInt& chunkshiftRight(int c){
  490. if(c < 0)return chunkshiftLeft(-c);
  491. if((unsigned int)c >= size()){std::fill(begin(),end(),0);return *this;}
  492. auto it1 = data.rbegin();
  493. auto it2 = it1 + c;
  494. while(it2 != data.rend())*(it1++) = *(it2++);
  495. while(it1 != data.rend())*(it1++) = 0;
  496. return *this;
  497. }
  498. inline BigInt bitshiftLeft(int c)const{
  499. if(c < 0)return bitshiftRight(-c);
  500. BigInt _this = *this;
  501. _this.bitshiftLeft(c);
  502. return _this;
  503. }
  504. inline BigInt bitshiftRight(int c)const{
  505. if(c < 0)return bitshiftLeft(-c);
  506. BigInt _this = *this;
  507. _this.bitshiftRight(c);
  508. return _this;
  509. }
  510. inline BigInt chunkshiftLeft(int c)const{
  511. if(c < 0)return chunkshiftRight(-c);
  512. BigInt _this = *this;
  513. _this.chunkshiftLeft(c);
  514. return _this;
  515. }
  516. inline BigInt chunkshiftRight(int c)const{
  517. if(c < 0)return chunkshiftLeft(-c);
  518. BigInt _this = *this;
  519. _this.chunkshiftRight(c);
  520. return _this;
  521. }
  522. inline BigInt add(const BigInt& o){
  523. BigInt ret = *this;
  524. ret.adda(o);
  525. return ret;
  526. }
  527. inline BigInt& adda(const BigInt& o){
  528. while(size() < o.size())data.push_front(0);
  529. bool carry = 0;
  530. auto it1 = rbegin();
  531. auto it2 = o.rbegin();
  532. while(it1 != rend() && it2 != o.rend()){
  533. carry = __builtin_uaddll_overflow(*it1, *it2 + carry, (unsigned long long*)(&(*it1)));
  534. carry |= (*it2 + carry) == 0 && *it2;
  535. ++it1;
  536. ++it2;
  537. }
  538. while(it1 != rend() && carry){
  539. carry = __builtin_uaddll_overflow(*it1, carry, (unsigned long long*)(&(*it1)));
  540. ++it1;
  541. }
  542. if(carry)data.push_front(1);
  543. return *this;
  544. }
  545. inline BigInt& suba(const BigInt& o){
  546. assert((*this) >= (o));
  547. bool carry = 0;
  548. auto it1 = rbegin();
  549. auto it2 = o.rbegin();
  550. while(it1 != rend() && it2 != o.rend()){
  551. carry = __builtin_usubll_overflow(*it1 - carry, *it2, (unsigned long long*)(&(*it1)));
  552. if(!carry)carry = ((*it1 - carry) == std::numeric_limits<uint64_t>::max());
  553. ++it1;++it2;
  554. }
  555. while(it1 != rend() && carry){
  556. carry = __builtin_usubll_overflow(*it1, carry, (unsigned long long*)(&(*it1)));
  557. ++it1;
  558. }
  559. return *this;
  560. }
  561. inline BigInt& moda(const BigInt& o){
  562. assert(!o.isZero());
  563. if(o > *this)return *this;
  564. BigInt mo = o;
  565. mo = o;
  566. int bd = bitDifference(o);
  567. mo.bitshiftLeft_expand(bd);
  568. if(mo > *this)mo.bitshiftRight(1);
  569. this->suba(mo);
  570. if(*this < o)return *this;
  571. while(true){
  572. bd = mo.bitDifference(*this);
  573. mo >>= bd;
  574. mo.trim();
  575. if(mo > *this)mo >>= 1;
  576. this->suba(mo);
  577. if(*this < o)return *this;
  578. }
  579. return *this;
  580. }
  581. inline bool even(){
  582. return !(*rbegin() & 1);
  583. }
  584. inline BigInt modPow(BigInt o, const BigInt& mod)const{
  585. BigInt t = *this;
  586. BigInt odd(1);
  587. while(true){
  588. if(o.even()){
  589. t = t.mult(t);
  590. t.trim();
  591. t.moda(mod);
  592. o.div(2);
  593. }
  594. else{
  595. odd = odd.mult(t);
  596. odd.moda(mod);
  597. odd.trim();
  598. t.trim();
  599. t.moda(mod);
  600. o.suba(BigInt(1));
  601. }
  602. //::cout << "Reduced" << std::endl;
  603. o.trim();
  604. if(o == 1){t = t.mult(odd);t.moda(mod);return t;}
  605. }
  606. }
  607. inline BigInt multNew(const BigInt& o)const{
  608. BigInt result(size() + o.size() + 1,0);
  609. BigInt temp(size() + o.size() + 1,0);
  610. int p = 0;
  611. for(auto it1 = rbegin();it1 != rend();it1++){
  612. auto it = temp.rbegin();
  613. uint64_t carry = 0;
  614. for(auto it2 = o.rbegin();it2 != o.rend();it2++){
  615. uint64_t hi;
  616. uint64_t lo = _mulx_u64(*it1, *it2, &hi);
  617. bool ac = __builtin_uaddll_overflow(lo, carry, (unsigned long long*)(&(*(it++))));
  618. carry = hi + ac;
  619. }
  620. if(carry)(*it) += carry;
  621. temp.chunkshiftLeft(p++);
  622. result.adda(temp);
  623. temp.setZero();
  624. }
  625. result.trim();
  626. return result;
  627. }
  628. inline BigInt mult(const BigInt& o)const{
  629. BigInt result(size() + o.size() + 1,0);
  630. BigInt temp(size() + o.size() + 1,0);
  631. int p = 0;
  632. for(auto it1 = rbegin();it1 != rend();it1++){
  633. auto it = temp.rbegin();
  634. lui carry = 0;
  635. for(auto it2 = o.rbegin();it2 != o.rend();it2++){
  636. lui prod = ((lui)*it1) * (*it2);
  637. prod += carry;
  638. *(it++) = (uint64_t)prod;
  639. carry = (prod >> 64);
  640. }
  641. if(carry)(*it) += carry;
  642. temp.chunkshiftLeft(p++);
  643. result.adda(temp);
  644. temp.setZero();
  645. }
  646. result.trim();
  647. return result;
  648. }
  649. inline std::string rawString()const{
  650. std::string s = "";
  651. bool flag;
  652. for(unsigned int i = 0;i < size();i++){
  653. if(data[i])flag = true;
  654. if(flag);
  655. s += std::to_string(data[i]);
  656. if(i < size() - 1)s += "|";
  657. }
  658. return s;
  659. }
  660. inline std::string bitString()const{
  661. auto it = begin();
  662. std::string ret = "";
  663. //std::cout << size() << "; " << std::flush;
  664. while(it != end()){
  665. std::bitset<64> bits(*it);
  666. for(unsigned int i = 0;i < 64;i++){
  667. ret += chars.at(((*it) & (1ULL << (64 - i))) != 0);
  668. }
  669. ++it;
  670. }
  671. return ret;
  672. }
  673. inline std::string toString()const{
  674. if(isZero())return std::to_string(0);
  675. std::deque<char> c_str;
  676. const uint64_t q = 1000000000000000000ULL;
  677. BigInt diver = *this;
  678. while(!diver.isZero()){
  679. std::string frac = std::to_string(diver.mod(q));
  680. int a = 0;
  681. for(auto it = frac.rbegin();it != frac.rend();it++){
  682. c_str.push_front(*it);
  683. a++;
  684. }
  685. while(a < 18){
  686. c_str.push_front('0');
  687. a++;
  688. }
  689. diver.div(q);
  690. }
  691. auto it = c_str.begin();
  692. while(*(it) == '0')++it;
  693. return std::string(it, c_str.end());
  694. }
  695. inline std::string toString(unsigned int base)const{
  696. if(isZero())return std::to_string(0);
  697. if(base == 2)return bitString();
  698. if(base == 10)return toString();
  699. std::vector<char> c_str;
  700. c_str.reserve(size() * (unsigned int)(64.0 * std::log(2) / std::log((double)base)));
  701. BigInt diver = *this;
  702. while(!diver.isZero()){
  703. c_str.push_back(chars.at(diver.mod(base)));
  704. diver.div(base);
  705. }
  706. return std::string(c_str.rbegin(), c_str.rend());
  707. }
  708. };
  709. namespace std{
  710. template<>
  711. struct hash<BigInt>{
  712. inline size_t operator()(const BigInt& o)const{
  713. size_t ret = 0;
  714. std::for_each(o.begin(), o.end(), [&ret](const uint64_t& ui){ret ^= ui;});
  715. return ret;
  716. }
  717. };
  718. }
  719. const static BigInt secure_prime("25517712857249265246309662191040714920292930135958602873503082695880945015180270627160886016284304866241119009429935511497986916016509065559298646199688497746399172174316028774533924795864096565081478741603241830675436336762053778667047857025632695617746551090247164369324008907433218665135569658200641651876344533506145721941113011977317356006176781796659698883765657005845351846184505291996942442336931455986790727248315517902731173678888064950798931396279140373592203530274617983159864665935475637811846793653407441533829095478201308785445059955697867933027578011378694502392722655274554801068451419037021634697683");
  720. #endif //BIGINT64_HPP