|  | @@ -15,6 +15,11 @@
 | 
											
												
													
														|  |  #include <iostream>
 |  |  #include <iostream>
 | 
											
												
													
														|  |  const std::vector<char> chars = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
 |  |  const std::vector<char> chars = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
 | 
											
												
													
														|  |  const __uint128_t _m = ((__uint128_t)1) << 64;
 |  |  const __uint128_t _m = ((__uint128_t)1) << 64;
 | 
											
												
													
														|  | 
 |  | +std::uint64_t _mulx_u64(std::uint64_t a, std::uint64_t b, std::uint64_t* hi){
 | 
											
												
													
														|  | 
 |  | +	__uint128_t r = a * b;
 | 
											
												
													
														|  | 
 |  | +	*hi = (r >> 64);
 | 
											
												
													
														|  | 
 |  | +	return r;
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  |  template<typename T>
 |  |  template<typename T>
 | 
											
												
													
														|  |  inline int signum(T t){
 |  |  inline int signum(T t){
 | 
											
												
													
														|  |  	if(t < 0)return -1;
 |  |  	if(t < 0)return -1;
 | 
											
										
											
												
													
														|  | @@ -448,6 +453,9 @@ struct BigInt{
 | 
											
												
													
														|  |  		ret ^= o;
 |  |  		ret ^= o;
 | 
											
												
													
														|  |  		return ret;
 |  |  		return ret;
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  | 
 |  | +	inline BigInt& cut(size_t chunks){
 | 
											
												
													
														|  | 
 |  | +		while(size() > chunks)data.pop_front();
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  |  	inline int bitDifference(const BigInt& o){
 |  |  	inline int bitDifference(const BigInt& o){
 | 
											
												
													
														|  |  		int pos1(0),pos2(0);
 |  |  		int pos1(0),pos2(0);
 | 
											
												
													
														|  |  		auto it1 = begin();
 |  |  		auto it1 = begin();
 | 
											
										
											
												
													
														|  | @@ -536,8 +544,8 @@ struct BigInt{
 | 
											
												
													
														|  |  		while(it1 != rend() && it2 != o.rend()){
 |  |  		while(it1 != rend() && it2 != o.rend()){
 | 
											
												
													
														|  |  			carry = __builtin_uaddll_overflow(*it1, *it2 + carry, (unsigned long long*)(&(*it1)));
 |  |  			carry = __builtin_uaddll_overflow(*it1, *it2 + carry, (unsigned long long*)(&(*it1)));
 | 
											
												
													
														|  |  			carry |= (*it2 + carry) == 0 && *it2;
 |  |  			carry |= (*it2 + carry) == 0 && *it2;
 | 
											
												
													
														|  | -			it1++;
 |  | 
 | 
											
												
													
														|  | -			it2++;
 |  | 
 | 
											
												
													
														|  | 
 |  | +			++it1;
 | 
											
												
													
														|  | 
 |  | +			++it2;
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  |  		while(it1 != rend() && carry){
 |  |  		while(it1 != rend() && carry){
 | 
											
												
													
														|  |  			carry = __builtin_uaddll_overflow(*it1, carry, (unsigned long long*)(&(*it1)));
 |  |  			carry = __builtin_uaddll_overflow(*it1, carry, (unsigned long long*)(&(*it1)));
 | 
											
										
											
												
													
														|  | @@ -608,6 +616,28 @@ struct BigInt{
 | 
											
												
													
														|  |  			if(o == 1){t = t.mult(odd);t.moda(mod);return t;}
 |  |  			if(o == 1){t = t.mult(odd);t.moda(mod);return t;}
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  | 
 |  | +	inline BigInt multNew(const BigInt& o)const{
 | 
											
												
													
														|  | 
 |  | +		BigInt result(size() + o.size() + 1,0);
 | 
											
												
													
														|  | 
 |  | +		BigInt temp(size() + o.size() + 1,0);
 | 
											
												
													
														|  | 
 |  | +		int p = 0;
 | 
											
												
													
														|  | 
 |  | +		for(auto it1 = rbegin();it1 != rend();it1++){
 | 
											
												
													
														|  | 
 |  | +			auto it = temp.rbegin();
 | 
											
												
													
														|  | 
 |  | +			uint64_t carry = 0;
 | 
											
												
													
														|  | 
 |  | +			for(auto it2 = o.rbegin();it2 != o.rend();it2++){
 | 
											
												
													
														|  | 
 |  | +				uint64_t hi;
 | 
											
												
													
														|  | 
 |  | +				uint64_t lo = _mulx_u64(*it1, *it2, &hi);
 | 
											
												
													
														|  | 
 |  | +				bool ac = __builtin_uaddll_overflow(lo, carry, (unsigned long long*)(&(*(it++))));
 | 
											
												
													
														|  | 
 |  | +				carry = hi + ac;
 | 
											
												
													
														|  | 
 |  | +			}
 | 
											
												
													
														|  | 
 |  | +			if(carry)(*it) += carry;
 | 
											
												
													
														|  | 
 |  | +			temp.chunkshiftLeft(p++);
 | 
											
												
													
														|  | 
 |  | +			result.adda(temp);
 | 
											
												
													
														|  | 
 |  | +			temp.setZero();
 | 
											
												
													
														|  | 
 |  | +		}
 | 
											
												
													
														|  | 
 |  | +		result.trim();
 | 
											
												
													
														|  | 
 |  | +		return result;
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  | 
 |  | +	
 | 
											
												
													
														|  |  	inline BigInt mult(const BigInt& o)const{
 |  |  	inline BigInt mult(const BigInt& o)const{
 | 
											
												
													
														|  |  		BigInt result(size() + o.size() + 1,0);
 |  |  		BigInt result(size() + o.size() + 1,0);
 | 
											
												
													
														|  |  		BigInt temp(size() + o.size() + 1,0);
 |  |  		BigInt temp(size() + o.size() + 1,0);
 | 
											
										
											
												
													
														|  | @@ -701,4 +731,5 @@ namespace std{
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  |  	};
 |  |  	};
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  | 
 |  | +const static BigInt secure_prime("25517712857249265246309662191040714920292930135958602873503082695880945015180270627160886016284304866241119009429935511497986916016509065559298646199688497746399172174316028774533924795864096565081478741603241830675436336762053778667047857025632695617746551090247164369324008907433218665135569658200641651876344533506145721941113011977317356006176781796659698883765657005845351846184505291996942442336931455986790727248315517902731173678888064950798931396279140373592203530274617983159864665935475637811846793653407441533829095478201308785445059955697867933027578011378694502392722655274554801068451419037021634697683");
 | 
											
												
													
														|  |  #endif //BIGINT64_HPP
 |  |  #endif //BIGINT64_HPP
 |