BigInt64.hpp 18 KB

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