BigInt64.hpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #ifndef BIGINT64_HPP
  2. #define BIGINT64_HPP
  3. #include <cstdint>
  4. #include <cstdlib>
  5. #include <algorithm>
  6. #include <iterator>
  7. #include <initializer_list>
  8. #include <deque>
  9. #include <vector>
  10. #include <string>
  11. #include <cmath>
  12. #include <bitset>
  13. #include <iostream>
  14. const std::vector<char> chars = {'0','1','2','3','4','5','6','7','8','9'};
  15. const __uint128_t _m = ((__uint128_t)1) << 64;
  16. template<typename T>
  17. inline int signum(T t){
  18. if(t < 0)return -1;
  19. if(t >= 0)return 1;
  20. }
  21. inline std::ostream& operator<<(std::ostream& out, __uint128_t o){
  22. if(o == 0)return out << "0";
  23. while(o > 0){
  24. out << std::to_string((int)(o % 10));
  25. o /= 10;
  26. }
  27. return out;
  28. }
  29. struct BigInt{
  30. using size_t = std::size_t;
  31. using ssize_t = std::int64_t;
  32. using uint64_t = std::uint64_t;
  33. using uint32_t = std::uint32_t;
  34. using lui = ::__uint128_t;
  35. std::deque<uint64_t> data;
  36. int signum;
  37. inline BigInt() : data(1,0),signum(1){}
  38. inline BigInt(size_t _s, uint64_t fill) : data(_s,fill), signum(1){}
  39. inline BigInt(int a) : signum(::signum(a)), data(1, std::abs(a)){}
  40. inline BigInt(unsigned int a) : signum(1), data(1, a){}
  41. inline BigInt(unsigned long long a) : signum(1), data(1, a){}
  42. inline BigInt(long long a) : signum(::signum(a)), data(1, std::abs(a)){}
  43. inline BigInt(const std::initializer_list<uint64_t>& l) : data(l), signum(1){}
  44. inline BigInt(std::initializer_list<uint64_t>&& l) : data(std::move(l)), signum(1){}
  45. template<typename InputIterator>
  46. inline BigInt(InputIterator begin, InputIterator end) : data(begin, end), signum(1){}
  47. std::deque<uint64_t>::iterator begin(){return data.begin();}
  48. std::deque<uint64_t>::iterator end(){return data.end();}
  49. std::deque<uint64_t>::reverse_iterator rbegin(){return data.rbegin();}
  50. std::deque<uint64_t>::reverse_iterator rend(){return data.rend();}
  51. std::deque<uint64_t>::const_iterator begin()const{return data.begin();}
  52. std::deque<uint64_t>::const_iterator end()const{return data.end();}
  53. std::deque<uint64_t>::const_reverse_iterator rbegin()const{return data.rbegin();}
  54. std::deque<uint64_t>::const_reverse_iterator rend()const{return data.rend();}
  55. size_t size()const{return data.size();}
  56. auto cbegin(){return data.cbegin();}
  57. auto cend(){return data.cend();}
  58. auto crbegin(){return data.crbegin();}
  59. auto crend(){return data.crend();}
  60. auto cbegin()const{return data.cbegin();}
  61. auto cend()const{return data.cend();}
  62. auto crbegin()const{return data.crbegin();}
  63. auto crend()const{return data.crend();}
  64. inline bool isZero()const{
  65. for(auto it = data.begin();it != data.end();it++){
  66. if(*it)return false;
  67. }
  68. return true;
  69. }
  70. inline void setZero(){
  71. for(auto it = begin();it != end();it++)*it = 0;
  72. }
  73. inline void trim(){
  74. while(data[0] == 0 && data.size() != 0){
  75. data.pop_front();
  76. }
  77. }
  78. inline BigInt div(uint64_t d)const{
  79. BigInt ret = *this;
  80. lui carry = 0;
  81. for(auto it = ret.data.begin();it != ret.data.end();it++){
  82. lui temp = (lui)*it;
  83. temp += carry;
  84. carry = temp % d;
  85. *it = (uint64_t)(temp / d);
  86. carry <<= 64;
  87. }
  88. return ret;
  89. }
  90. inline BigInt& div(uint64_t d){
  91. lui carry = 0;
  92. for(auto it = data.begin();it != data.end();it++){
  93. lui temp = (lui)*it;
  94. temp += carry;
  95. carry = temp % d;
  96. *it = (uint64_t)(temp / d);
  97. carry <<= 64;
  98. }
  99. return *this;
  100. }
  101. inline uint64_t mod(uint64_t m)const{
  102. lui carry = 0;
  103. for(auto it = data.begin();it != data.end();it++){
  104. carry <<= 64;
  105. carry = (*it + carry) % m;
  106. }
  107. return carry;
  108. }
  109. inline BigInt& chunkshiftLeft(int c){
  110. if(c < 0)return chunkshiftRight(-c);
  111. if(c >= size()){std::fill(begin(),end(),0);return *this;}
  112. auto it1 = data.begin();
  113. auto it2 = it1 + c;
  114. while(it2 != data.end())*(it1++) = *(it2++);
  115. while(it1 != data.end())*(it1++) = 0;
  116. return *this;
  117. }
  118. inline BigInt& chunkshiftRight(int c){
  119. if(c < 0)return chunkshiftLeft(-c);
  120. if(c >= size()){std::fill(begin(),end(),0);return *this;}
  121. auto it1 = data.rbegin();
  122. auto it2 = it1 + c;
  123. while(it2 != data.rend())*(it1++) = *(it2++);
  124. while(it1 != data.rend())*(it1++) = 0;
  125. return *this;
  126. }
  127. inline BigInt& adda(const BigInt& o){
  128. while(size() < o.size())data.push_front(0);
  129. bool carry = 0;
  130. auto it1 = rbegin();
  131. auto it2 = o.rbegin();
  132. while(it1 != rend() && it2 != o.rend()){
  133. carry = __builtin_uaddll_overflow(*it1, *it2 + carry, (unsigned long long*)(&(*it1)));
  134. carry |= (*it2 + carry) == 0 && *it2;
  135. it1++;
  136. it2++;
  137. }
  138. while(it1 != rend() && carry){
  139. carry = __builtin_uaddll_overflow(*it1, carry, (unsigned long long*)(&(*it1)));
  140. }
  141. if(carry)data.push_front(1);
  142. return *this;
  143. }
  144. inline BigInt mult(const BigInt& o){
  145. BigInt result(size() + o.size(),0);
  146. BigInt temp(size() + o.size(),0);
  147. int p = 0;
  148. for(auto it1 = rbegin();it1 != rend();it1++){
  149. auto it = temp.rbegin();
  150. lui carry = 0;
  151. for(auto it2 = o.rbegin();it2 != o.rend();it2++){
  152. lui prod = ((lui)*it1) * (*it2);
  153. prod += carry;
  154. *(it++) = (uint64_t)prod;
  155. carry = (prod >> 64);
  156. }
  157. if(carry)(*it)++;
  158. temp.chunkshiftLeft(p++);
  159. result.adda(temp);
  160. temp.setZero();
  161. }
  162. result.trim();
  163. return result;
  164. }
  165. inline std::string toString(){
  166. std::vector<char> c_str;
  167. c_str.reserve(data.size() * 19);
  168. BigInt diver = *this;
  169. while(!diver.isZero()){
  170. c_str.push_back(chars.at(diver.mod(10)));
  171. diver.div(10);
  172. }
  173. return std::string(c_str.rbegin(), c_str.rend());
  174. }
  175. };
  176. #endif //BIGINT64_HPP