BigInt64.hpp 17 KB

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