BigInt64.hpp 18 KB

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