|
@@ -48,10 +48,12 @@ struct BigInt{
|
|
inline BigInt(long long a) : data(1, std::abs(a)),signum(::signum(a)){}
|
|
inline BigInt(long long a) : data(1, std::abs(a)),signum(::signum(a)){}
|
|
inline BigInt(const std::initializer_list<uint64_t>& l) : data(l), signum(1){}
|
|
inline BigInt(const std::initializer_list<uint64_t>& l) : data(l), signum(1){}
|
|
inline BigInt(std::initializer_list<uint64_t>&& l) : data(std::move(l)), signum(1){}
|
|
inline BigInt(std::initializer_list<uint64_t>&& l) : data(std::move(l)), signum(1){}
|
|
|
|
+ inline BigInt(const BigInt& o) : data(o.data), signum(o.signum){}
|
|
|
|
+ inline BigInt(BigInt&& o) : data(std::move(o.data)), signum(o.signum){}
|
|
template<typename InputIterator>
|
|
template<typename InputIterator>
|
|
inline BigInt(InputIterator begin, InputIterator end) : data(begin, end), signum(1){}
|
|
inline BigInt(InputIterator begin, InputIterator end) : data(begin, end), signum(1){}
|
|
template<typename RNG>
|
|
template<typename RNG>
|
|
- inline BigInt(RNG& rng, size_t length) : data(length, 0), signum(1){std::generate(data.begin(),data.end(), [&rng](){return rng();});}
|
|
|
|
|
|
+ inline BigInt(RNG& rng, size_t length) : data(length, 0), signum(1){auto it = data.begin();while(it != data.end())*(it++) = rng();}
|
|
std::deque<uint64_t>::iterator begin(){return data.begin();}
|
|
std::deque<uint64_t>::iterator begin(){return data.begin();}
|
|
std::deque<uint64_t>::iterator end(){return data.end();}
|
|
std::deque<uint64_t>::iterator end(){return data.end();}
|
|
std::deque<uint64_t>::reverse_iterator rbegin(){return data.rbegin();}
|
|
std::deque<uint64_t>::reverse_iterator rbegin(){return data.rbegin();}
|
|
@@ -60,6 +62,14 @@ struct BigInt{
|
|
std::deque<uint64_t>::const_iterator end()const{return data.end();}
|
|
std::deque<uint64_t>::const_iterator end()const{return data.end();}
|
|
std::deque<uint64_t>::const_reverse_iterator rbegin()const{return data.rbegin();}
|
|
std::deque<uint64_t>::const_reverse_iterator rbegin()const{return data.rbegin();}
|
|
std::deque<uint64_t>::const_reverse_iterator rend()const{return data.rend();}
|
|
std::deque<uint64_t>::const_reverse_iterator rend()const{return data.rend();}
|
|
|
|
+ BigInt& operator=(const BigInt& o){
|
|
|
|
+ data = o.data;
|
|
|
|
+ signum = o.signum;
|
|
|
|
+ }
|
|
|
|
+ BigInt& operator=(BigInt&& o){
|
|
|
|
+ data = std::move(o.data);
|
|
|
|
+ signum = o.signum;
|
|
|
|
+ }
|
|
uint64_t& operator[](size_t i){return data[i];}
|
|
uint64_t& operator[](size_t i){return data[i];}
|
|
const uint64_t& operator[](size_t i)const{return data[i];}
|
|
const uint64_t& operator[](size_t i)const{return data[i];}
|
|
size_t size()const{return data.size();}
|
|
size_t size()const{return data.size();}
|
|
@@ -276,9 +286,9 @@ struct BigInt{
|
|
|
|
|
|
inline BigInt& bitshiftLeft(int c){
|
|
inline BigInt& bitshiftLeft(int c){
|
|
if(c < 0)return bitshiftRight(-c);
|
|
if(c < 0)return bitshiftRight(-c);
|
|
- if((unsigned int)c >= size() * sizeof(uint64_t)){std::fill(begin(),end(),0);return *this;}
|
|
|
|
unsigned int sh = c % 64;
|
|
unsigned int sh = c % 64;
|
|
unsigned int jmp = c / 64;
|
|
unsigned int jmp = c / 64;
|
|
|
|
+ if((unsigned int)jmp >= size() * sizeof(uint64_t)){std::fill(begin(),end(),0);return *this;}
|
|
auto it1 = begin();
|
|
auto it1 = begin();
|
|
auto it2 = it1 + jmp;
|
|
auto it2 = it1 + jmp;
|
|
auto beforeEnd = end() - 1;
|
|
auto beforeEnd = end() - 1;
|
|
@@ -287,8 +297,8 @@ struct BigInt{
|
|
*it1 |= (*(it2 + 1) >> (64 - sh));
|
|
*it1 |= (*(it2 + 1) >> (64 - sh));
|
|
++it1;++it2;
|
|
++it1;++it2;
|
|
}
|
|
}
|
|
- ++it1;++it2;
|
|
|
|
*it1 = (*it2 << sh);
|
|
*it1 = (*it2 << sh);
|
|
|
|
+ ++it1;++it2;
|
|
while(it1 != end()){
|
|
while(it1 != end()){
|
|
*it1 = 0;
|
|
*it1 = 0;
|
|
++it1;
|
|
++it1;
|
|
@@ -298,9 +308,9 @@ struct BigInt{
|
|
|
|
|
|
inline BigInt& bitshiftRight(int c){
|
|
inline BigInt& bitshiftRight(int c){
|
|
if(c < 0)return bitshiftLeft(-c);
|
|
if(c < 0)return bitshiftLeft(-c);
|
|
- if((unsigned int)c >= size() * sizeof(uint64_t)){std::fill(begin(),end(),0);return *this;}
|
|
|
|
unsigned int sh = c % 64;
|
|
unsigned int sh = c % 64;
|
|
unsigned int jmp = c / 64;
|
|
unsigned int jmp = c / 64;
|
|
|
|
+ if((unsigned int)jmp >= size() * sizeof(uint64_t)){std::fill(begin(),end(),0);return *this;}
|
|
auto it1 = rbegin();
|
|
auto it1 = rbegin();
|
|
auto it2 = it1 + jmp;
|
|
auto it2 = it1 + jmp;
|
|
auto beforeRend = rend() - 1;
|
|
auto beforeRend = rend() - 1;
|
|
@@ -309,8 +319,8 @@ struct BigInt{
|
|
*it1 |= (*(it2 + 1) << (64 - sh));
|
|
*it1 |= (*(it2 + 1) << (64 - sh));
|
|
++it1;++it2;
|
|
++it1;++it2;
|
|
}
|
|
}
|
|
|
|
+ *it1 = (*it2 >> sh);
|
|
++it1;++it2;
|
|
++it1;++it2;
|
|
- *it1 = (*it2 << sh);
|
|
|
|
while(it1 != rend()){
|
|
while(it1 != rend()){
|
|
*it1 = 0;
|
|
*it1 = 0;
|
|
++it1;
|
|
++it1;
|
|
@@ -392,9 +402,8 @@ struct BigInt{
|
|
auto it2 = o.rbegin();
|
|
auto it2 = o.rbegin();
|
|
while(it1 != rend() && it2 != o.rend()){
|
|
while(it1 != rend() && it2 != o.rend()){
|
|
carry = __builtin_usubll_overflow(*it1 - carry, *it2, (unsigned long long*)(&(*it1)));
|
|
carry = __builtin_usubll_overflow(*it1 - carry, *it2, (unsigned long long*)(&(*it1)));
|
|
- carry |= ((*it1 - carry) == std::numeric_limits<uint64_t>::max());
|
|
|
|
- it1++;
|
|
|
|
- it2++;
|
|
|
|
|
|
+ if(!carry)carry = ((*it1 - carry) == std::numeric_limits<uint64_t>::max());
|
|
|
|
+ ++it1;++it2;
|
|
}
|
|
}
|
|
while(it1 != rend() && carry){
|
|
while(it1 != rend() && carry){
|
|
carry = __builtin_usubll_overflow(*it1, carry, (unsigned long long*)(&(*it1)));
|
|
carry = __builtin_usubll_overflow(*it1, carry, (unsigned long long*)(&(*it1)));
|
|
@@ -435,7 +444,19 @@ struct BigInt{
|
|
}
|
|
}
|
|
return s;
|
|
return s;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+ inline std::string bitString(){
|
|
|
|
+ auto it = begin();
|
|
|
|
+ std::string ret = "";
|
|
|
|
+ std::cout << size() << "; " << std::flush;
|
|
|
|
+ while(it != end()){
|
|
|
|
+ std::bitset<64> bits(*it);
|
|
|
|
+ for(unsigned int i = 0;i < 64;i++){
|
|
|
|
+ ret += chars.at(((*it) & (1ULL << (64 - i))) != 0);
|
|
|
|
+ }
|
|
|
|
+ ++it;
|
|
|
|
+ }
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
inline std::string toString(){
|
|
inline std::string toString(){
|
|
std::deque<char> c_str;
|
|
std::deque<char> c_str;
|
|
const uint64_t q = 1000000000000000000ULL;
|
|
const uint64_t q = 1000000000000000000ULL;
|