BigInt64.hpp 19 KB

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