BigInt64.hpp 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  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. std::deque<uint64_t>::iterator begin(){return data.begin();}
  54. std::deque<uint64_t>::iterator end(){return data.end();}
  55. std::deque<uint64_t>::reverse_iterator rbegin(){return data.rbegin();}
  56. std::deque<uint64_t>::reverse_iterator rend(){return data.rend();}
  57. std::deque<uint64_t>::const_iterator begin()const{return data.begin();}
  58. std::deque<uint64_t>::const_iterator end()const{return data.end();}
  59. std::deque<uint64_t>::const_reverse_iterator rbegin()const{return data.rbegin();}
  60. std::deque<uint64_t>::const_reverse_iterator rend()const{return data.rend();}
  61. uint64_t& operator[](size_t i){return data[i];}
  62. const uint64_t& operator[](size_t i)const{return data[i];}
  63. size_t size()const{return data.size();}
  64. auto cbegin()const{return data.cbegin();}
  65. auto cend()const{return data.cend();}
  66. auto crbegin()const{return data.crbegin();}
  67. auto crend()const{return data.crend();}
  68. inline bool operator<(const BigInt& o)const{
  69. if(signum > o.signum){
  70. return false;
  71. }
  72. if(signum < o.signum){
  73. return true;
  74. }
  75. const_iterator it1 = begin();
  76. const_iterator it2 = o.begin();
  77. if(size() > o.size()){
  78. it1 += size() - o.size();
  79. auto _t = begin();
  80. while(_t != it1)
  81. if(*_t)return false;
  82. }
  83. else if(size() < o.size()){
  84. it2 += o.size() - size();
  85. auto _t = o.begin();
  86. while(_t != it2)
  87. if(*_t)return true;
  88. }
  89. while(it1 != end() && it2 != o.end()){
  90. if(*(it1) < *(it2))return true;
  91. if(*(it1) > *(it2))return false;
  92. ++it1;++it2;
  93. }
  94. return false;
  95. }
  96. inline bool operator>(const BigInt& o)const{
  97. if(signum < o.signum){
  98. return false;
  99. }
  100. if(signum > o.signum){
  101. return true;
  102. }
  103. const_iterator it1 = begin();
  104. const_iterator it2 = o.begin();
  105. if(size() > o.size()){
  106. it1 += size() - o.size();
  107. auto _t = begin();
  108. while(_t != it1)
  109. if(*_t)return true;
  110. }
  111. else if(size() < o.size()){
  112. it2 += o.size() - size();
  113. auto _t = o.begin();
  114. while(_t != it2)
  115. if(*_t)return false;
  116. }
  117. while(it1 != end() && it2 != o.end()){
  118. if(*(it1) > *(it2))return true;
  119. if(*(it1) < *(it2))return false;
  120. ++it1;++it2;
  121. }
  122. return false;
  123. }
  124. inline bool operator<=(const BigInt& o)const{
  125. if(signum > o.signum){
  126. return false;
  127. }
  128. if(signum < o.signum){
  129. return true;
  130. }
  131. const_iterator it1 = begin();
  132. const_iterator it2 = o.begin();
  133. if(size() > o.size()){
  134. it1 += size() - o.size();
  135. auto _t = begin();
  136. while(_t != it1)
  137. if(*_t)return true;
  138. }
  139. else if(size() < o.size()){
  140. it2 += o.size() - size();
  141. auto _t = o.begin();
  142. while(_t != it2)
  143. if(*_t)return false;
  144. }
  145. while(it1 != end() && it2 != o.end()){
  146. if(*(it1) < *(it2))return true;
  147. if(*(it1) > *(it2))return false;
  148. ++it1;++it2;
  149. }
  150. return true;
  151. }
  152. inline bool operator>=(const BigInt& o)const{
  153. if(signum < o.signum){
  154. return false;
  155. }
  156. if(signum > o.signum){
  157. return true;
  158. }
  159. const_iterator it1 = begin();
  160. const_iterator it2 = o.begin();
  161. if(size() > o.size()){
  162. it1 += size() - o.size();
  163. auto _t = begin();
  164. while(_t != it1)
  165. if(*_t)return true;
  166. }
  167. else if(size() < o.size()){
  168. it2 += o.size() - size();
  169. auto _t = o.begin();
  170. while(_t != it2)
  171. if(*_t)return false;
  172. }
  173. while(it1 != end() && it2 != o.end()){
  174. if(*(it1) > *(it2))return true;
  175. if(*(it1) < *(it2))return false;
  176. ++it1;++it2;
  177. }
  178. return true;
  179. }
  180. inline bool operator==(const BigInt& o)const{
  181. if(signum < o.signum){
  182. return false;
  183. }
  184. if(signum > o.signum){
  185. return false;
  186. }
  187. const_iterator it1 = begin();
  188. const_iterator it2 = o.begin();
  189. if(size() > o.size()){
  190. it1 += size() - o.size();
  191. auto _t = begin();
  192. while(_t != it1)
  193. if(*_t)return false;
  194. }
  195. else if(size() < o.size()){
  196. it2 += o.size() - size();
  197. auto _t = o.begin();
  198. while(_t != it2)
  199. if(*_t)return false;
  200. }
  201. while(it1 != end() && it2 != o.end()){
  202. if(*(it1) != *(it2))return false;
  203. ++it1;++it2;
  204. }
  205. return true;
  206. }
  207. inline bool isZero()const{
  208. for(auto it = data.begin();it != data.end();it++){
  209. if(*it)return false;
  210. }
  211. return true;
  212. }
  213. inline void setZero(){
  214. for(auto it = begin();it != end();it++)*it = 0;
  215. }
  216. inline void trim(){
  217. while(data[0] == 0 && data.size() != 0){
  218. data.pop_front();
  219. }
  220. }
  221. inline BigInt div(uint64_t d)const{
  222. BigInt ret = *this;
  223. lui carry = 0;
  224. for(auto it = ret.data.begin();it != ret.data.end();it++){
  225. lui temp = (lui)*it;
  226. temp += carry;
  227. carry = temp % d;
  228. *it = (uint64_t)(temp / d);
  229. carry <<= 64;
  230. }
  231. return ret;
  232. }
  233. inline BigInt& div(uint64_t d){
  234. lui carry = 0;
  235. for(auto it = data.begin();it != data.end();it++){
  236. lui temp = (lui)*it;
  237. temp += carry;
  238. carry = temp % d;
  239. *it = (uint64_t)(temp / d);
  240. carry <<= 64;
  241. }
  242. return *this;
  243. }
  244. inline uint64_t mod(uint64_t m)const{
  245. lui carry = 0;
  246. for(auto it = data.begin();it != data.end();it++){
  247. carry <<= 64;
  248. carry = (*it + carry) % m;
  249. }
  250. return carry;
  251. }
  252. inline BigInt& chunkshiftLeft(int c){
  253. if(c < 0)return chunkshiftRight(-c);
  254. if((unsigned int)c >= size()){std::fill(begin(),end(),0);return *this;}
  255. auto it1 = data.begin();
  256. auto it2 = it1 + c;
  257. while(it2 != data.end())*(it1++) = *(it2++);
  258. while(it1 != data.end())*(it1++) = 0;
  259. return *this;
  260. }
  261. inline BigInt& chunkshiftRight(int c){
  262. if(c < 0)return chunkshiftLeft(-c);
  263. if((unsigned int)c >= size()){std::fill(begin(),end(),0);return *this;}
  264. auto it1 = data.rbegin();
  265. auto it2 = it1 + c;
  266. while(it2 != data.rend())*(it1++) = *(it2++);
  267. while(it1 != data.rend())*(it1++) = 0;
  268. return *this;
  269. }
  270. inline BigInt add(const BigInt& o){
  271. BigInt ret = *this;
  272. ret.adda(o);
  273. return ret;
  274. }
  275. inline BigInt& adda(const BigInt& o){
  276. while(size() < o.size())data.push_front(0);
  277. bool carry = 0;
  278. auto it1 = rbegin();
  279. auto it2 = o.rbegin();
  280. while(it1 != rend() && it2 != o.rend()){
  281. carry = __builtin_uaddll_overflow(*it1, *it2 + carry, (unsigned long long*)(&(*it1)));
  282. carry |= (*it2 + carry) == 0 && *it2;
  283. it1++;
  284. it2++;
  285. }
  286. while(it1 != rend() && carry){
  287. carry = __builtin_uaddll_overflow(*it1, carry, (unsigned long long*)(&(*it1)));
  288. }
  289. if(carry)data.push_front(1);
  290. return *this;
  291. }
  292. inline BigInt& suba(const BigInt& o){
  293. assert((*this) >= (o));
  294. bool carry = 0;
  295. auto it1 = rbegin();
  296. auto it2 = o.rbegin();
  297. while(it1 != rend() && it2 != o.rend()){
  298. carry = __builtin_usubll_overflow(*it1 - carry, *it2, (unsigned long long*)(&(*it1)));
  299. carry |= ((*it1 - carry) == std::numeric_limits<uint64_t>::max());
  300. it1++;
  301. it2++;
  302. }
  303. while(it1 != rend() && carry){
  304. carry = __builtin_usubll_overflow(*it1, carry, (unsigned long long*)(&(*it1)));
  305. }
  306. return *this;
  307. }
  308. inline BigInt mult(const BigInt& o)const{
  309. BigInt result(size() + o.size() + 1,0);
  310. BigInt temp(size() + o.size() + 1,0);
  311. int p = 0;
  312. for(auto it1 = rbegin();it1 != rend();it1++){
  313. auto it = temp.rbegin();
  314. lui carry = 0;
  315. for(auto it2 = o.rbegin();it2 != o.rend();it2++){
  316. lui prod = ((lui)*it1) * (*it2);
  317. prod += carry;
  318. *(it++) = (uint64_t)prod;
  319. carry = (prod >> 64);
  320. }
  321. if(carry)(*it) += carry;
  322. temp.chunkshiftLeft(p++);
  323. result.adda(temp);
  324. temp.setZero();
  325. }
  326. result.trim();
  327. return result;
  328. }
  329. inline std::string rawString(){
  330. std::string s = "";
  331. bool flag;
  332. for(unsigned int i = 0;i < size();i++){
  333. if(data[i])flag = true;
  334. if(flag);
  335. s += std::to_string(data[i]);
  336. if(i < size() - 1)s += "|";
  337. }
  338. return s;
  339. }
  340. inline std::string toString(){
  341. std::deque<char> c_str;
  342. const uint64_t q = 1000000000000000000ULL;
  343. //c_str.reserve(size() * 19);
  344. BigInt diver = *this;
  345. while(!diver.isZero()){
  346. std::string frac = std::to_string(diver.mod(q));
  347. int a = 0;
  348. for(auto it = frac.rbegin();it != frac.rend();it++){
  349. c_str.push_front(*it);
  350. a++;
  351. }
  352. while(a < 18){
  353. c_str.push_front('0');
  354. a++;
  355. }
  356. diver.div(q);
  357. }
  358. auto it = c_str.begin();
  359. while(*(it) == '0')++it;
  360. return std::string(it, c_str.end());
  361. }
  362. inline std::string toString(unsigned int base){
  363. std::vector<char> c_str;
  364. c_str.reserve(size() * (unsigned int)(64.0 * std::log(2) / std::log((double)base)));
  365. BigInt diver = *this;
  366. while(!diver.isZero()){
  367. c_str.push_back(chars.at(diver.mod(base)));
  368. diver.div(base);
  369. }
  370. return std::string(c_str.rbegin(), c_str.rend());
  371. }
  372. };
  373. #endif //BIGINT64_HPP