modify bigint snippet
This commit is contained in:
parent
ee1189f090
commit
1970f40ba0
|
|
@ -84,138 +84,153 @@ ls.add_snippets('cpp', {
|
||||||
'}',
|
'}',
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
s(
|
s('bigint', {
|
||||||
'bigint',
|
|
||||||
t {
|
t {
|
||||||
'const ll BASE = 1000000000;',
|
|
||||||
'const int BASE_DIGITS = 9;',
|
|
||||||
'',
|
|
||||||
'// By edhlii and GPT :>',
|
|
||||||
'struct BigInt {',
|
'struct BigInt {',
|
||||||
' vector<long long> digits;',
|
' string value;',
|
||||||
' BigInt() {}',
|
' bool negative;',
|
||||||
' BigInt(long long v) {',
|
' BigInt() : value("0"), negative(false) {}',
|
||||||
' while (v) {',
|
' BigInt(const string &s) { fromString(s); }',
|
||||||
' digits.push_back(v % BASE);',
|
' void fromString(const string &s) {',
|
||||||
' v /= BASE;',
|
' int i = 0;',
|
||||||
|
' negative = false;',
|
||||||
|
' value.clear();',
|
||||||
|
" if (s[i] == '-') {",
|
||||||
|
' negative = true;',
|
||||||
|
' i++;',
|
||||||
|
" } else if (s[i] == '+')",
|
||||||
|
' i++;',
|
||||||
|
" while (i < (int)s.size() && s[i] == '0')",
|
||||||
|
' i++;',
|
||||||
|
' value = s.substr(i);',
|
||||||
|
' if (value.empty())',
|
||||||
|
' value = "0", negative = false;',
|
||||||
' }',
|
' }',
|
||||||
|
' string toString() const {',
|
||||||
|
' return (negative && value != "0" ? "-" : "") + value;',
|
||||||
' }',
|
' }',
|
||||||
' BigInt(const string &s) { read(s); }',
|
' friend ostream &operator<<(ostream &os, const BigInt &b) {',
|
||||||
' void read(const string &s) {',
|
' return os << b.toString();',
|
||||||
' digits.clear();',
|
|
||||||
' int len = s.size();',
|
|
||||||
' for (int i = len; i > 0; i -= BASE_DIGITS) {',
|
|
||||||
' int start = max(0, i - BASE_DIGITS);',
|
|
||||||
' int length = i - start;',
|
|
||||||
' digits.push_back(stoll(s.substr(start, length)));',
|
|
||||||
' }',
|
' }',
|
||||||
' trim();',
|
' int absCompare(const BigInt &other) const {',
|
||||||
|
' if (value.size() != other.value.size())',
|
||||||
|
' return value.size() < other.value.size() ? -1 : 1;',
|
||||||
|
' return value.compare(other.value);',
|
||||||
' }',
|
' }',
|
||||||
' void trim() {',
|
' bool operator==(const BigInt &other) const {',
|
||||||
' while (!digits.empty() && digits.back() == 0)',
|
' return negative == other.negative && value == other.value;',
|
||||||
' digits.pop_back();',
|
|
||||||
' }',
|
|
||||||
' friend ostream &operator<<(ostream &out, const BigInt &a) {',
|
|
||||||
' if (a.digits.empty()) {',
|
|
||||||
' out << 0;',
|
|
||||||
' return out;',
|
|
||||||
' }',
|
|
||||||
' out << a.digits.back();',
|
|
||||||
' for (int i = a.digits.size() - 2; i >= 0; --i)',
|
|
||||||
" out << setw(BASE_DIGITS) << setfill('0') << a.digits[i];",
|
|
||||||
' return out;',
|
|
||||||
' }',
|
|
||||||
' BigInt operator+(const BigInt &other) const {',
|
|
||||||
' BigInt res;',
|
|
||||||
' long long carry = 0;',
|
|
||||||
' size_t n = max(digits.size(), other.digits.size());',
|
|
||||||
' for (size_t i = 0; i < n || carry; ++i) {',
|
|
||||||
' long long sum = carry;',
|
|
||||||
' if (i < digits.size())',
|
|
||||||
' sum += digits[i];',
|
|
||||||
' if (i < other.digits.size())',
|
|
||||||
' sum += other.digits[i];',
|
|
||||||
' res.digits.push_back(sum % BASE);',
|
|
||||||
' carry = sum / BASE;',
|
|
||||||
' }',
|
|
||||||
' return res;',
|
|
||||||
' }',
|
|
||||||
' BigInt operator-(const BigInt &other) const {',
|
|
||||||
' BigInt res = *this;',
|
|
||||||
' long long carry = 0;',
|
|
||||||
' for (size_t i = 0; i < other.digits.size() || carry; ++i) {',
|
|
||||||
' res.digits[i] -= carry + (i < other.digits.size() ? other.digits[i] : 0);',
|
|
||||||
' carry = res.digits[i] < 0;',
|
|
||||||
' if (carry)',
|
|
||||||
' res.digits[i] += BASE;',
|
|
||||||
' }',
|
|
||||||
' res.trim();',
|
|
||||||
' return res;',
|
|
||||||
' }',
|
|
||||||
' BigInt operator*(const BigInt &other) const {',
|
|
||||||
' BigInt res;',
|
|
||||||
' res.digits.resize(digits.size() + other.digits.size());',
|
|
||||||
' for (size_t i = 0; i < digits.size(); i++) {',
|
|
||||||
' long long carry = 0;',
|
|
||||||
' for (size_t j = 0; j < other.digits.size() || carry; j++) {',
|
|
||||||
' long long cur =',
|
|
||||||
' res.digits[i + j] +',
|
|
||||||
' digits[i] * (j < other.digits.size() ? other.digits[j] : 0) + carry;',
|
|
||||||
' res.digits[i + j] = cur % BASE;',
|
|
||||||
' carry = cur / BASE;',
|
|
||||||
' }',
|
|
||||||
' }',
|
|
||||||
' res.trim();',
|
|
||||||
' return res;',
|
|
||||||
' }',
|
' }',
|
||||||
' bool operator<(const BigInt &other) const {',
|
' bool operator<(const BigInt &other) const {',
|
||||||
' if (digits.size() != other.digits.size())',
|
' if (negative != other.negative)',
|
||||||
' return digits.size() < other.digits.size();',
|
' return negative;',
|
||||||
' for (int i = digits.size() - 1; i >= 0; i--) {',
|
' int cmp = absCompare(other);',
|
||||||
' if (digits[i] != other.digits[i])',
|
' return negative ? cmp > 0 : cmp < 0;',
|
||||||
' return digits[i] < other.digits[i];',
|
|
||||||
' }',
|
' }',
|
||||||
' return false;',
|
' bool operator>(const BigInt &other) const { return other < *this; }',
|
||||||
' }',
|
' BigInt operator+(const BigInt &other) const {',
|
||||||
' bool operator<=(const BigInt &other) const { return !(other < *this); }',
|
' if (negative == other.negative) {',
|
||||||
' pair<BigInt, BigInt> divmod(const BigInt &other) const {',
|
' return BigInt(add(value, other.value), negative);',
|
||||||
' BigInt quotient, remainder;',
|
|
||||||
' quotient.digits.resize(digits.size());',
|
|
||||||
' for (int i = digits.size() - 1; i >= 0; i--) {',
|
|
||||||
' remainder.digits.insert(remainder.digits.begin(), digits[i]);',
|
|
||||||
' remainder.trim();',
|
|
||||||
' int low = 0, high = BASE - 1, mid, curDigit = 0;',
|
|
||||||
' while (low <= high) {',
|
|
||||||
' mid = (low + high) / 2;',
|
|
||||||
' BigInt t = other * BigInt(mid);',
|
|
||||||
' if (t <= remainder) {',
|
|
||||||
' curDigit = mid;',
|
|
||||||
' low = mid + 1;',
|
|
||||||
' } else {',
|
' } else {',
|
||||||
' high = mid - 1;',
|
' int cmp = absCompare(other);',
|
||||||
|
' if (cmp == 0)',
|
||||||
|
' return BigInt("0");',
|
||||||
|
' if (cmp > 0)',
|
||||||
|
' return BigInt(sub(value, other.value), negative);',
|
||||||
|
' else',
|
||||||
|
' return BigInt(sub(other.value, value), other.negative);',
|
||||||
' }',
|
' }',
|
||||||
' }',
|
' }',
|
||||||
' quotient.digits[i] = curDigit;',
|
' BigInt operator-(const BigInt &other) const {',
|
||||||
' remainder = remainder - other * BigInt(curDigit);',
|
' BigInt negOther = other;',
|
||||||
|
' negOther.negative = !other.negative;',
|
||||||
|
' return *this + negOther;',
|
||||||
' }',
|
' }',
|
||||||
' quotient.trim();',
|
' BigInt operator*(const BigInt &other) const {',
|
||||||
' remainder.trim();',
|
" string result(value.size() + other.value.size(), '0');",
|
||||||
|
' for (int i = value.size() - 1; i >= 0; --i) {',
|
||||||
|
' int carry = 0;',
|
||||||
|
' for (int j = other.value.size() - 1; j >= 0; --j) {',
|
||||||
|
" int tmp = (value[i] - '0') * (other.value[j] - '0') +",
|
||||||
|
" (result[i + j + 1] - '0') + carry;",
|
||||||
|
" result[i + j + 1] = tmp % 10 + '0';",
|
||||||
|
' carry = tmp / 10;',
|
||||||
|
' }',
|
||||||
|
' result[i] += carry;',
|
||||||
|
' }',
|
||||||
|
' int i = 0;',
|
||||||
|
" while (i < (int)result.size() - 1 && result[i] == '0')",
|
||||||
|
' i++;',
|
||||||
|
' return BigInt(result.substr(i), negative != other.negative);',
|
||||||
|
' }',
|
||||||
|
' BigInt operator/(const BigInt &other) const {',
|
||||||
|
' return divmod(*this, other).first;',
|
||||||
|
' }',
|
||||||
|
' BigInt operator%(const BigInt &other) const {',
|
||||||
|
' return divmod(*this, other).second;',
|
||||||
|
' }',
|
||||||
|
'private:',
|
||||||
|
' BigInt(const string &s, bool neg) : value(s), negative(neg) {',
|
||||||
|
' if (value == "0")',
|
||||||
|
' negative = false;',
|
||||||
|
' }',
|
||||||
|
' static string add(const string &a, const string &b) {',
|
||||||
|
' string res;',
|
||||||
|
' int carry = 0, i = a.size() - 1, j = b.size() - 1;',
|
||||||
|
' while (i >= 0 || j >= 0 || carry) {',
|
||||||
|
' int sum = carry;',
|
||||||
|
" if (i >= 0) sum += a[i--] - '0';",
|
||||||
|
" if (j >= 0) sum += b[j--] - '0';",
|
||||||
|
" res += sum % 10 + '0';",
|
||||||
|
' carry = sum / 10;',
|
||||||
|
' }',
|
||||||
|
' reverse(res.begin(), res.end());',
|
||||||
|
' return res;',
|
||||||
|
' }',
|
||||||
|
' static string sub(const string &a, const string &b) {',
|
||||||
|
' string res;',
|
||||||
|
' int borrow = 0, i = a.size() - 1, j = b.size() - 1;',
|
||||||
|
' while (i >= 0) {',
|
||||||
|
" int diff = a[i] - '0' - (j >= 0 ? b[j--] - '0' : 0) - borrow;",
|
||||||
|
' if (diff < 0) diff += 10, borrow = 1;',
|
||||||
|
' else borrow = 0;',
|
||||||
|
" res += diff + '0';",
|
||||||
|
' i--;',
|
||||||
|
' }',
|
||||||
|
" while (res.size() > 1 && res.back() == '0')",
|
||||||
|
' res.pop_back();',
|
||||||
|
' reverse(res.begin(), res.end());',
|
||||||
|
' return res;',
|
||||||
|
' }',
|
||||||
|
' static pair<BigInt, BigInt> divmod(BigInt a, BigInt b) {',
|
||||||
|
' if (b.value == "0")',
|
||||||
|
' throw runtime_error("Division by zero");',
|
||||||
|
' BigInt quotient, remainder;',
|
||||||
|
' quotient.value.clear();',
|
||||||
|
' remainder = BigInt("0");',
|
||||||
|
' for (char digit : a.value) {',
|
||||||
|
' remainder = remainder * BigInt("10") + BigInt(string(1, digit));',
|
||||||
|
' int count = 0;',
|
||||||
|
' while (remainder > b || remainder == b) {',
|
||||||
|
' remainder = remainder - b;',
|
||||||
|
' count++;',
|
||||||
|
' }',
|
||||||
|
" quotient.value += count + '0';",
|
||||||
|
' }',
|
||||||
|
' int i = 0;',
|
||||||
|
" while (i < (int)quotient.value.size() - 1 && quotient.value[i] == '0')",
|
||||||
|
' i++;',
|
||||||
|
' quotient.value = quotient.value.substr(i);',
|
||||||
|
' quotient.negative = a.negative != b.negative;',
|
||||||
|
' remainder.negative = a.negative;',
|
||||||
|
' if (quotient.value == "0")',
|
||||||
|
' quotient.negative = false;',
|
||||||
|
' if (remainder.value == "0")',
|
||||||
|
' remainder.negative = false;',
|
||||||
' return {quotient, remainder};',
|
' return {quotient, remainder};',
|
||||||
' }',
|
' }',
|
||||||
' BigInt operator/(const BigInt &other) const { return divmod(other).first; }',
|
|
||||||
' BigInt operator%(const BigInt &other) const { return divmod(other).second; }',
|
|
||||||
' BigInt &operator+=(const BigInt &other) { return *this = *this + other; }',
|
|
||||||
' BigInt &operator-=(const BigInt &other) { return *this = *this - other; }',
|
|
||||||
' BigInt &operator*=(const BigInt &other) { return *this = *this * other; }',
|
|
||||||
' BigInt &operator/=(const BigInt &other) {',
|
|
||||||
' return *this = divmod(other).first;',
|
|
||||||
' }',
|
|
||||||
' BigInt &operator%=(const BigInt &other) {',
|
|
||||||
' return *this = divmod(other).second;',
|
|
||||||
' }',
|
|
||||||
'};',
|
'};',
|
||||||
}
|
},
|
||||||
),
|
}),
|
||||||
s('rollinghash', {
|
s('rollinghash', {
|
||||||
t {
|
t {
|
||||||
'struct RollingHash {',
|
'struct RollingHash {',
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue