292 lines
9.4 KiB
Lua
292 lines
9.4 KiB
Lua
-- print 'Custom C++ snippets loaded!'
|
|
|
|
local ls = require 'luasnip'
|
|
local s = ls.snippet
|
|
local t = ls.text_node
|
|
local i = ls.insert_node
|
|
local fmt = require('luasnip.extras.fmt').fmt
|
|
local rep = require('luasnip.extras').rep
|
|
|
|
ls.add_snippets('cpp', {
|
|
s('cpptemplate', {
|
|
t {
|
|
'#include <bits/stdc++.h>',
|
|
'#define fi first',
|
|
'#define se second',
|
|
'using namespace std;',
|
|
'typedef long long ll;',
|
|
'typedef unsigned long long ull;',
|
|
'const int N = 1000006;',
|
|
'const ll MOD = 1000000007;',
|
|
'',
|
|
'int main() {',
|
|
' ios_base::sync_with_stdio(false);',
|
|
' cin.tie(0);',
|
|
' cout.tie(0);',
|
|
'',
|
|
' cout << "edhlii\\n";',
|
|
'}',
|
|
},
|
|
}),
|
|
s('segtree', {
|
|
t {
|
|
'struct SegTree {',
|
|
' int n;',
|
|
' vector<int> tree;',
|
|
'',
|
|
' inline int combine(int a, int b) {',
|
|
' // TODO: chỉnh sửa hàm combine cho phù hợp (vd: min(a, b), max(a, b), a + b, ...)',
|
|
' return a + b;',
|
|
' }',
|
|
'',
|
|
' SegTree(const vector<int> &arr) {',
|
|
' n = arr.size();',
|
|
' tree.resize(n << 1);',
|
|
' for (int i = 0; i < n; ++i)',
|
|
' tree[i + n] = arr[i];',
|
|
' for (int i = n - 1; i > 0; --i)',
|
|
' tree[i] = combine(tree[i << 1], tree[i << 1 | 1]);',
|
|
' }',
|
|
'',
|
|
' inline void update(int pos, int val) {',
|
|
' pos += n;',
|
|
' tree[pos] = val;',
|
|
' for (pos >>= 1; pos; pos >>= 1)',
|
|
' tree[pos] = combine(tree[pos << 1], tree[pos << 1 | 1]);',
|
|
' }',
|
|
'',
|
|
' inline int query(int l, int r) {',
|
|
' int resL = 0, resR = 0; // TODO: chỉnh phần tử đơn vị phù hợp',
|
|
' l += n;',
|
|
' r += n;',
|
|
' while (l < r) {',
|
|
' if (l & 1)',
|
|
' resL = combine(resL, tree[l++]);',
|
|
' if (r & 1)',
|
|
' resR = combine(tree[--r], resR);',
|
|
' l >>= 1;',
|
|
' r >>= 1;',
|
|
' }',
|
|
' return combine(resL, resR);',
|
|
' }',
|
|
'};',
|
|
},
|
|
}),
|
|
s('binpow', {
|
|
t {
|
|
'll binpow(ll a, ll b, ll c) {',
|
|
' ll res = 1;',
|
|
' while (b != 0) {',
|
|
' if (b & 1) {',
|
|
' res = (res * a) % c;',
|
|
' }',
|
|
' b = b >> 1;',
|
|
' a = (a * a) % c;',
|
|
' }',
|
|
' return res;',
|
|
'}',
|
|
},
|
|
}),
|
|
s('bigint', {
|
|
t {
|
|
'struct BigInt {',
|
|
' string value;',
|
|
' bool negative;',
|
|
' BigInt() : value("0"), negative(false) {}',
|
|
' BigInt(const string &s) { fromString(s); }',
|
|
' void fromString(const string &s) {',
|
|
' 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;',
|
|
' }',
|
|
' friend ostream &operator<<(ostream &os, const BigInt &b) {',
|
|
' return os << b.toString();',
|
|
' }',
|
|
' 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);',
|
|
' }',
|
|
' bool operator==(const BigInt &other) const {',
|
|
' return negative == other.negative && value == other.value;',
|
|
' }',
|
|
' bool operator<(const BigInt &other) const {',
|
|
' if (negative != other.negative)',
|
|
' return negative;',
|
|
' int cmp = absCompare(other);',
|
|
' return negative ? cmp > 0 : cmp < 0;',
|
|
' }',
|
|
' bool operator>(const BigInt &other) const { return other < *this; }',
|
|
' BigInt operator+(const BigInt &other) const {',
|
|
' if (negative == other.negative) {',
|
|
' return BigInt(add(value, other.value), negative);',
|
|
' } else {',
|
|
' 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);',
|
|
' }',
|
|
' }',
|
|
' BigInt operator-(const BigInt &other) const {',
|
|
' BigInt negOther = other;',
|
|
' negOther.negative = !other.negative;',
|
|
' return *this + negOther;',
|
|
' }',
|
|
' BigInt operator*(const BigInt &other) const {',
|
|
" 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};',
|
|
' }',
|
|
'};',
|
|
},
|
|
}),
|
|
s('rollinghash', {
|
|
t {
|
|
'struct RollingHash {',
|
|
' using ll = long long;',
|
|
' ll base, mod;',
|
|
' vector<ll> power;',
|
|
' vector<ll> prefix_hash;',
|
|
' RollingHash(const string &s, ll base, ll mod) : base(base), mod(mod) {',
|
|
' int n = s.size();',
|
|
' power.resize(n + 1, 1);',
|
|
' prefix_hash.resize(n + 1, 0);',
|
|
' for (int i = 0; i < n; ++i) {',
|
|
' power[i + 1] = (__int128)power[i] * base % mod;',
|
|
' prefix_hash[i + 1] = ((__int128)prefix_hash[i] * base + s[i]) % mod;',
|
|
' }',
|
|
' }',
|
|
' ll get_hash(int l, int r) {',
|
|
' ll hash_r = prefix_hash[r + 1];',
|
|
' ll hash_l = (__int128)prefix_hash[l] * power[r - l + 1] % mod;',
|
|
' ll res = (hash_r - hash_l + mod) % mod;',
|
|
' return res;',
|
|
' }',
|
|
'};',
|
|
},
|
|
}),
|
|
s(
|
|
'fib',
|
|
fmt(
|
|
[[
|
|
pair<ll, ll> {}(ll {}) {{
|
|
if ({} == 0)
|
|
return {{0, 1}};
|
|
auto p = {}({} >> 1);
|
|
ll a = p.first;
|
|
ll b = p.second;
|
|
ll c = (a * ((2 * b % MOD - a + MOD) % MOD)) % MOD;
|
|
ll d = ((a * a) % MOD + (b * b) % MOD) % MOD;
|
|
if ({} & 1) {{
|
|
return {{d, (c + d) % MOD}};
|
|
}} else {{
|
|
return {{c, d}};
|
|
}}
|
|
}}
|
|
]],
|
|
{
|
|
i(1, 'fibonacci'), -- function name
|
|
i(2, 'n'), -- input variable
|
|
rep(2), -- reuse n
|
|
rep(1), -- reuse function name
|
|
rep(2), -- reuse n
|
|
rep(2), -- reuse n
|
|
}
|
|
)
|
|
),
|
|
})
|