BigInt64.hpp 17 KB

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