BigInt64.hpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  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. }
  23. inline std::ostream& operator<<(std::ostream& out, __uint128_t o){
  24. if(o == 0)return out << "0";
  25. while(o > 0){
  26. out << std::to_string((int)(o % 10));
  27. o /= 10;
  28. }
  29. return out;
  30. }
  31. struct BigInt{
  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 lui = ::__uint128_t;
  37. using iterator = std::deque<uint64_t>::iterator;
  38. using const_iterator = std::deque<uint64_t>::const_iterator;
  39. using reverse_iterator = std::deque<uint64_t>::reverse_iterator;
  40. using const_reverse_iterator = std::deque<uint64_t>::const_reverse_iterator;
  41. std::deque<uint64_t> data;
  42. int signum;
  43. inline BigInt() : data(1,0),signum(1){}
  44. inline BigInt(size_t _s, uint64_t fill) : data(_s,fill), signum(1){}
  45. inline BigInt(int a) : data(1, std::abs(a)),signum(::signum(a)){}
  46. inline BigInt(unsigned int a) : data(1, a),signum(1){}
  47. inline BigInt(unsigned long long a) : data(1, a), signum(1){}
  48. inline BigInt(long long a) : data(1, std::abs(a)),signum(::signum(a)){}
  49. inline BigInt(const std::initializer_list<uint64_t>& l) : data(l), signum(1){}
  50. inline BigInt(std::initializer_list<uint64_t>&& l) : data(std::move(l)), signum(1){}
  51. template<typename InputIterator>
  52. inline BigInt(InputIterator begin, InputIterator end) : data(begin, end), signum(1){}
  53. template<typename RNG>
  54. inline BigInt(RNG& rng, size_t length) : data(length, 0), signum(1){std::generate(data.begin(),data.end(), [&rng](){return rng();});}
  55. std::deque<uint64_t>::iterator begin(){return data.begin();}
  56. std::deque<uint64_t>::iterator end(){return data.end();}
  57. std::deque<uint64_t>::reverse_iterator rbegin(){return data.rbegin();}
  58. std::deque<uint64_t>::reverse_iterator rend(){return data.rend();}
  59. std::deque<uint64_t>::const_iterator begin()const{return data.begin();}
  60. std::deque<uint64_t>::const_iterator end()const{return data.end();}
  61. std::deque<uint64_t>::const_reverse_iterator rbegin()const{return data.rbegin();}
  62. std::deque<uint64_t>::const_reverse_iterator rend()const{return data.rend();}
  63. uint64_t& operator[](size_t i){return data[i];}
  64. const uint64_t& operator[](size_t i)const{return data[i];}
  65. size_t size()const{return data.size();}
  66. auto cbegin()const{return data.cbegin();}
  67. auto cend()const{return data.cend();}
  68. auto crbegin()const{return data.crbegin();}
  69. auto crend()const{return data.crend();}
  70. inline bool operator<(const BigInt& o)const{
  71. if(signum > o.signum){
  72. return false;
  73. }
  74. if(signum < o.signum){
  75. return true;
  76. }
  77. const_iterator it1 = begin();
  78. const_iterator it2 = o.begin();
  79. if(size() > o.size()){
  80. it1 += size() - o.size();
  81. auto _t = begin();
  82. while(_t != it1){
  83. if(*_t)return false;
  84. ++_t;
  85. }
  86. }
  87. else if(size() < o.size()){
  88. it2 += o.size() - size();
  89. auto _t = o.begin();
  90. while(_t != it2){
  91. if(*_t)return true;
  92. ++_t;
  93. }
  94. }
  95. while(it1 != end() && it2 != o.end()){
  96. if(*(it1) < *(it2))return true;
  97. if(*(it1) > *(it2))return false;
  98. ++it1;++it2;
  99. }
  100. return false;
  101. }
  102. inline bool operator>(const BigInt& o)const{
  103. if(signum < o.signum){
  104. return false;
  105. }
  106. if(signum > o.signum){
  107. return true;
  108. }
  109. const_iterator it1 = begin();
  110. const_iterator it2 = o.begin();
  111. if(size() > o.size()){
  112. it1 += size() - o.size();
  113. auto _t = begin();
  114. while(_t != it1){
  115. if(*_t)return true;
  116. ++_t;
  117. }
  118. }
  119. else if(size() < o.size()){
  120. it2 += o.size() - size();
  121. auto _t = o.begin();
  122. while(_t != it2){
  123. if(*_t)return false;
  124. ++_t;
  125. }
  126. }
  127. while(it1 != end() && it2 != o.end()){
  128. if(*(it1) > *(it2))return true;
  129. if(*(it1) < *(it2))return false;
  130. ++it1;++it2;
  131. }
  132. return false;
  133. }
  134. inline bool operator<=(const BigInt& o)const{
  135. if(signum > o.signum){
  136. return false;
  137. }
  138. if(signum < o.signum){
  139. return true;
  140. }
  141. const_iterator it1 = begin();
  142. const_iterator it2 = o.begin();
  143. if(size() > o.size()){
  144. it1 += size() - o.size();
  145. auto _t = begin();
  146. while(_t != it1){
  147. if(*_t)return true;
  148. ++_t;
  149. }
  150. }
  151. else if(size() < o.size()){
  152. it2 += o.size() - size();
  153. auto _t = o.begin();
  154. while(_t != it2){
  155. if(*_t)return false;
  156. ++_t;
  157. }
  158. }
  159. while(it1 != end() && it2 != o.end()){
  160. if(*(it1) < *(it2))return true;
  161. if(*(it1) > *(it2))return false;
  162. ++it1;++it2;
  163. }
  164. return true;
  165. }
  166. inline bool operator>=(const BigInt& o)const{
  167. if(signum < o.signum){
  168. return false;
  169. }
  170. if(signum > o.signum){
  171. return true;
  172. }
  173. const_iterator it1 = begin();
  174. const_iterator it2 = o.begin();
  175. if(size() > o.size()){
  176. it1 += size() - o.size();
  177. auto _t = begin();
  178. while(_t != it1){
  179. if(*_t)return true;
  180. ++_t;
  181. }
  182. }
  183. else if(size() < o.size()){
  184. it2 += o.size() - size();
  185. auto _t = o.begin();
  186. while(_t != it2){
  187. if(*_t)return false;
  188. ++_t;
  189. }
  190. }
  191. while(it1 != end() && it2 != o.end()){
  192. if(*(it1) > *(it2))return true;
  193. if(*(it1) < *(it2))return false;
  194. ++it1;++it2;
  195. }
  196. return true;
  197. }
  198. inline bool operator==(const BigInt& o)const{
  199. if(signum < o.signum){
  200. return false;
  201. }
  202. if(signum > o.signum){
  203. return false;
  204. }
  205. const_iterator it1 = begin();
  206. const_iterator it2 = o.begin();
  207. if(size() > o.size()){
  208. it1 += size() - o.size();
  209. auto _t = begin();
  210. while(_t != it1){
  211. if(*_t)return false;
  212. ++_t;
  213. }
  214. }
  215. else if(size() < o.size()){
  216. it2 += o.size() - size();
  217. auto _t = o.begin();
  218. while(_t != it2){
  219. if(*_t)return false;
  220. ++_t;
  221. }
  222. }
  223. while(it1 != end() && it2 != o.end()){
  224. if(*(it1) != *(it2))return false;
  225. ++it1;++it2;
  226. }
  227. return true;
  228. }
  229. inline bool isZero()const{
  230. for(auto it = data.begin();it != data.end();it++){
  231. if(*it)return false;
  232. }
  233. return true;
  234. }
  235. inline void setZero(){
  236. for(auto it = begin();it != end();it++)*it = 0;
  237. }
  238. inline void trim(){
  239. while(data[0] == 0 && data.size() != 0){
  240. data.pop_front();
  241. }
  242. }
  243. inline BigInt div(uint64_t d)const{
  244. BigInt ret = *this;
  245. lui carry = 0;
  246. for(auto it = ret.data.begin();it != ret.data.end();it++){
  247. lui temp = (lui)*it;
  248. temp += carry;
  249. carry = temp % d;
  250. *it = (uint64_t)(temp / d);
  251. carry <<= 64;
  252. }
  253. return ret;
  254. }
  255. inline BigInt& div(uint64_t d){
  256. lui carry = 0;
  257. for(auto it = data.begin();it != data.end();it++){
  258. lui temp = (lui)*it;
  259. temp += carry;
  260. carry = temp % d;
  261. *it = (uint64_t)(temp / d);
  262. carry <<= 64;
  263. }
  264. return *this;
  265. }
  266. inline uint64_t mod(uint64_t m)const{
  267. lui carry = 0;
  268. for(auto it = data.begin();it != data.end();it++){
  269. carry <<= 64;
  270. carry = (*it + carry) % m;
  271. }
  272. return carry;
  273. }
  274. inline BigInt& bitshiftLeft(int c){
  275. if(c < 0)return bitshiftRight(-c);
  276. if((unsigned int)c >= size() * sizeof(uint64_t)){std::fill(begin(),end(),0);return *this;}
  277. unsigned int sh = c % 64;
  278. unsigned int jmp = c / 64;
  279. auto it1 = begin();
  280. auto it2 = it1 + jmp;
  281. auto beforeEnd = end() - 1;
  282. while(it2 != beforeEnd){
  283. *it1 = (*it2 << sh);
  284. *it1 |= (*(it2 + 1) >> (64 - sh));
  285. ++it1;++it2;
  286. }
  287. ++it1;++it2;
  288. *it1 = (*it2 << sh);
  289. while(it1 != end()){
  290. *it1 = 0;
  291. ++it1;
  292. }
  293. return *this;
  294. }
  295. inline BigInt& bitshiftRight(int c){
  296. if(c < 0)return bitshiftLeft(-c);
  297. if((unsigned int)c >= size() * sizeof(uint64_t)){std::fill(begin(),end(),0);return *this;}
  298. unsigned int sh = c % 64;
  299. unsigned int jmp = c / 64;
  300. auto it1 = rbegin();
  301. auto it2 = it1 + jmp;
  302. auto beforeRend = rend() - 1;
  303. while(it2 != beforeRend){
  304. *it1 = (*it2 >> sh);
  305. *it1 |= (*(it2 + 1) << (64 - sh));
  306. ++it1;++it2;
  307. }
  308. ++it1;++it2;
  309. *it1 = (*it2 << sh);
  310. while(it1 != rend()){
  311. *it1 = 0;
  312. ++it1;
  313. }
  314. return *this;
  315. }
  316. inline BigInt& chunkshiftLeft(int c){
  317. if(c < 0)return chunkshiftRight(-c);
  318. if((unsigned int)c >= size()){std::fill(begin(),end(),0);return *this;}
  319. auto it1 = data.begin();
  320. auto it2 = it1 + c;
  321. while(it2 != data.end())*(it1++) = *(it2++);
  322. while(it1 != data.end())*(it1++) = 0;
  323. return *this;
  324. }
  325. inline BigInt& chunkshiftRight(int c){
  326. if(c < 0)return chunkshiftLeft(-c);
  327. if((unsigned int)c >= size()){std::fill(begin(),end(),0);return *this;}
  328. auto it1 = data.rbegin();
  329. auto it2 = it1 + c;
  330. while(it2 != data.rend())*(it1++) = *(it2++);
  331. while(it1 != data.rend())*(it1++) = 0;
  332. return *this;
  333. }
  334. inline BigInt bitshiftLeft(int c)const{
  335. if(c < 0)return bitshiftRight(-c);
  336. BigInt _this = *this;
  337. _this.bitshiftLeft(c);
  338. return _this;
  339. }
  340. inline BigInt bitshiftRight(int c)const{
  341. if(c < 0)return bitshiftLeft(-c);
  342. BigInt _this = *this;
  343. _this.bitshiftRight(c);
  344. return _this;
  345. }
  346. inline BigInt chunkshiftLeft(int c)const{
  347. if(c < 0)return chunkshiftRight(-c);
  348. BigInt _this = *this;
  349. _this.chunkshiftLeft(c);
  350. return _this;
  351. }
  352. inline BigInt chunkshiftRight(int c)const{
  353. if(c < 0)return chunkshiftLeft(-c);
  354. BigInt _this = *this;
  355. _this.chunkshiftRight(c);
  356. return _this;
  357. }
  358. inline BigInt add(const BigInt& o){
  359. BigInt ret = *this;
  360. ret.adda(o);
  361. return ret;
  362. }
  363. inline BigInt& adda(const BigInt& o){
  364. while(size() < o.size())data.push_front(0);
  365. bool carry = 0;
  366. auto it1 = rbegin();
  367. auto it2 = o.rbegin();
  368. while(it1 != rend() && it2 != o.rend()){
  369. carry = __builtin_uaddll_overflow(*it1, *it2 + carry, (unsigned long long*)(&(*it1)));
  370. carry |= (*it2 + carry) == 0 && *it2;
  371. it1++;
  372. it2++;
  373. }
  374. while(it1 != rend() && carry){
  375. carry = __builtin_uaddll_overflow(*it1, carry, (unsigned long long*)(&(*it1)));
  376. ++it1;
  377. }
  378. if(carry)data.push_front(1);
  379. return *this;
  380. }
  381. inline BigInt& suba(const BigInt& o){
  382. assert((*this) >= (o));
  383. bool carry = 0;
  384. auto it1 = rbegin();
  385. auto it2 = o.rbegin();
  386. while(it1 != rend() && it2 != o.rend()){
  387. carry = __builtin_usubll_overflow(*it1 - carry, *it2, (unsigned long long*)(&(*it1)));
  388. carry |= ((*it1 - carry) == std::numeric_limits<uint64_t>::max());
  389. it1++;
  390. it2++;
  391. }
  392. while(it1 != rend() && carry){
  393. carry = __builtin_usubll_overflow(*it1, carry, (unsigned long long*)(&(*it1)));
  394. ++it1;
  395. }
  396. return *this;
  397. }
  398. inline BigInt mult(const BigInt& o)const{
  399. BigInt result(size() + o.size() + 1,0);
  400. BigInt temp(size() + o.size() + 1,0);
  401. int p = 0;
  402. for(auto it1 = rbegin();it1 != rend();it1++){
  403. auto it = temp.rbegin();
  404. lui carry = 0;
  405. for(auto it2 = o.rbegin();it2 != o.rend();it2++){
  406. lui prod = ((lui)*it1) * (*it2);
  407. prod += carry;
  408. *(it++) = (uint64_t)prod;
  409. carry = (prod >> 64);
  410. }
  411. if(carry)(*it) += carry;
  412. temp.chunkshiftLeft(p++);
  413. result.adda(temp);
  414. temp.setZero();
  415. }
  416. result.trim();
  417. return result;
  418. }
  419. inline std::string rawString(){
  420. std::string s = "";
  421. bool flag;
  422. for(unsigned int i = 0;i < size();i++){
  423. if(data[i])flag = true;
  424. if(flag);
  425. s += std::to_string(data[i]);
  426. if(i < size() - 1)s += "|";
  427. }
  428. return s;
  429. }
  430. inline std::string toString(){
  431. std::deque<char> c_str;
  432. const uint64_t q = 1000000000000000000ULL;
  433. //c_str.reserve(size() * 19);
  434. BigInt diver = *this;
  435. while(!diver.isZero()){
  436. std::string frac = std::to_string(diver.mod(q));
  437. int a = 0;
  438. for(auto it = frac.rbegin();it != frac.rend();it++){
  439. c_str.push_front(*it);
  440. a++;
  441. }
  442. while(a < 18){
  443. c_str.push_front('0');
  444. a++;
  445. }
  446. diver.div(q);
  447. }
  448. auto it = c_str.begin();
  449. while(*(it) == '0')++it;
  450. return std::string(it, c_str.end());
  451. }
  452. inline std::string toString(unsigned int base){
  453. std::vector<char> c_str;
  454. c_str.reserve(size() * (unsigned int)(64.0 * std::log(2) / std::log((double)base)));
  455. BigInt diver = *this;
  456. while(!diver.isZero()){
  457. c_str.push_back(chars.at(diver.mod(base)));
  458. diver.div(base);
  459. }
  460. return std::string(c_str.rbegin(), c_str.rend());
  461. }
  462. };
  463. namespace std{
  464. template<>
  465. struct hash<BigInt>{
  466. size_t operator()(const BigInt& o){
  467. size_t ret = 0;
  468. std::for_each(o.begin(), o.end(), [&ret](const uint64_t& ui){ret ^= ui;});
  469. return ret;
  470. }
  471. };
  472. }
  473. #endif //BIGINT64_HPP