|
@@ -54,7 +54,7 @@ struct BigInt{
|
|
|
template<typename InputIterator>
|
|
|
inline BigInt(InputIterator begin, InputIterator end) : data(begin, end), signum(1){}
|
|
|
template<typename RNG>
|
|
|
- inline BigInt(RNG& rng, size_t length) : data(length, 0), signum(1){auto it = data.begin();while(it != data.end())*(it++) = rng();}
|
|
|
+ inline BigInt(RNG& rng, size_t length) : data(length, 0), signum(1){std::generate(data.begin(),data.end(), [&rng](){return rng();});}
|
|
|
std::deque<uint64_t>::iterator begin(){return data.begin();}
|
|
|
std::deque<uint64_t>::iterator end(){return data.end();}
|
|
|
std::deque<uint64_t>::reverse_iterator rbegin(){return data.rbegin();}
|
|
@@ -249,10 +249,11 @@ struct BigInt{
|
|
|
for(auto it = begin();it != end();it++)*it = 0;
|
|
|
}
|
|
|
|
|
|
- inline void trim(){
|
|
|
- while(data[0] == 0 && data.size() != 0){
|
|
|
+ inline BigInt& trim(){
|
|
|
+ while(data[0] == 0 && data.size() > 1){
|
|
|
data.pop_front();
|
|
|
}
|
|
|
+ return *this;
|
|
|
}
|
|
|
|
|
|
inline BigInt div(uint64_t d)const{
|
|
@@ -347,33 +348,75 @@ struct BigInt{
|
|
|
BigInt& operator<<=(int c){
|
|
|
return bitshiftLeft(c);
|
|
|
}
|
|
|
+
|
|
|
BigInt& operator>>=(int c){
|
|
|
return bitshiftRight(c);
|
|
|
}
|
|
|
+
|
|
|
+ BigInt& operator&=(const BigInt& o){
|
|
|
+ auto it1 = rbegin();
|
|
|
+ auto it2 = o.rbegin();
|
|
|
+ while(it1 != rend() && it2 != o.rend())
|
|
|
+ *(it1++) &= *(it2++);
|
|
|
+ return *this;
|
|
|
+ }
|
|
|
+ BigInt& operator|=(const BigInt& o){
|
|
|
+ auto it1 = rbegin();
|
|
|
+ auto it2 = o.rbegin();
|
|
|
+ while(it1 != rend() && it2 != o.rend())
|
|
|
+ *(it1++) |= *(it2++);
|
|
|
+ return *this;
|
|
|
+ }
|
|
|
+ BigInt& operator^=(const BigInt& o){
|
|
|
+ auto it1 = rbegin();
|
|
|
+ auto it2 = o.rbegin();
|
|
|
+ while(it1 != rend() && it2 != o.rend())
|
|
|
+ *(it1++) ^= *(it2++);
|
|
|
+ return *this;
|
|
|
+ }
|
|
|
+ BigInt operator&(const BigInt& o)const{
|
|
|
+ BigInt ret(*this);
|
|
|
+ ret &= o;
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ BigInt operator|(const BigInt& o)const{
|
|
|
+ BigInt ret(*this);
|
|
|
+ ret |= o;
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ BigInt operator^(const BigInt& o)const{
|
|
|
+ BigInt ret(*this);
|
|
|
+ ret ^= o;
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
int bitDifference(const BigInt& o){
|
|
|
- int pos1(-1),pos2(-1);
|
|
|
+ int pos1(0),pos2(0);
|
|
|
auto it1 = begin();
|
|
|
auto it2 = o.begin();
|
|
|
+ bool bitfound = false;
|
|
|
while(it1 != end()){
|
|
|
if(*it1 == 0)
|
|
|
pos1 += 64;
|
|
|
else{
|
|
|
pos1 += __builtin_clzll(*it1);
|
|
|
+ bitfound = true;
|
|
|
break;
|
|
|
}
|
|
|
++it1;
|
|
|
}
|
|
|
- if(pos1 == -1)pos1 = size() * 64;
|
|
|
- while(it2 != end()){
|
|
|
+ if(!bitfound)pos1 = size() * 64;
|
|
|
+ bitfound = false;
|
|
|
+ while(it2 != o.end()){
|
|
|
if(*it2 == 0)
|
|
|
pos2 += 64;
|
|
|
else{
|
|
|
pos2 += __builtin_clzll(*it2);
|
|
|
+ bitfound = true;
|
|
|
break;
|
|
|
}
|
|
|
++it2;
|
|
|
}
|
|
|
- if(pos1 == -1)pos1 = o.size() * 64;
|
|
|
+ if(!bitfound)pos2 = o.size() * 64;
|
|
|
int sizediff = ((signed int)size()) - ((signed int)o.size());
|
|
|
return pos2 - pos1 + sizediff * 64;
|
|
|
}
|
|
@@ -460,8 +503,17 @@ struct BigInt{
|
|
|
}
|
|
|
return *this;
|
|
|
}
|
|
|
- inline BigInt moda(){
|
|
|
-
|
|
|
+ inline BigInt& moda(const BigInt& o){
|
|
|
+ if(o > *this)return *this;
|
|
|
+ while(true){
|
|
|
+ BigInt mo = o;
|
|
|
+ int bd = bitDifference(o);
|
|
|
+ mo.bitshiftLeft(bd);
|
|
|
+ if(mo > *this)mo.bitshiftRight(1);
|
|
|
+ this->suba(mo);
|
|
|
+ if(*this < o)break;
|
|
|
+ }
|
|
|
+ return *this;
|
|
|
}
|
|
|
inline BigInt mult(const BigInt& o)const{
|
|
|
BigInt result(size() + o.size() + 1,0);
|
|
@@ -533,6 +585,7 @@ struct BigInt{
|
|
|
}
|
|
|
|
|
|
inline std::string toString(unsigned int base){
|
|
|
+ if(isZero())return std::string("0");
|
|
|
std::vector<char> c_str;
|
|
|
c_str.reserve(size() * (unsigned int)(64.0 * std::log(2) / std::log((double)base)));
|
|
|
BigInt diver = *this;
|