backup
This commit is contained in:
parent
aaf37a497c
commit
4a333399ab
|
@ -1,3 +1,4 @@
|
|||
vim.cmd("set pumblend=15")
|
||||
vim.cmd("set expandtab")
|
||||
vim.cmd("set tabstop=4")
|
||||
vim.cmd("set softtabstop=4")
|
||||
|
@ -88,6 +89,15 @@ local plugins = {
|
|||
-- Additional lua configuration, makes nvim stuff amazing!
|
||||
'folke/neodev.nvim',
|
||||
},
|
||||
opts = {
|
||||
-- inlay_hints = { enabled = true, },
|
||||
-- codelens = { enabled = true, },
|
||||
},
|
||||
config = function(_, servers)
|
||||
for server, opts in pairs(servers) do
|
||||
require('lspconfig')[server].setup(opts)
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
"hrsh7th/nvim-cmp",
|
||||
|
@ -429,7 +439,7 @@ local plugins = {
|
|||
},
|
||||
{ 'Civitasv/cmake-tools.nvim' },
|
||||
{ 'p00f/cphelper.nvim' },
|
||||
{ "savq/melange-nvim" },
|
||||
{ "arielherself/melange-nvim"},
|
||||
{ 'hrsh7th/vim-vsnip' },
|
||||
{ 'octarect/telescope-menu.nvim' },
|
||||
{
|
||||
|
@ -444,8 +454,9 @@ local plugins = {
|
|||
},
|
||||
config = true
|
||||
},
|
||||
{ 'Exafunction/codeium.vim' },
|
||||
-- { 'Exafunction/codeium.vim' },
|
||||
{ "mistricky/codesnap.nvim", build = "make" },
|
||||
{ 'rmagatti/goto-preview' },
|
||||
}
|
||||
local opts = {
|
||||
}
|
||||
|
@ -606,6 +617,9 @@ lspconfig.rust_analyzer.setup {
|
|||
['rust-analyzer'] = {},
|
||||
},
|
||||
}
|
||||
lspconfig.lua_ls.setup {
|
||||
capabilities = capabilities
|
||||
}
|
||||
|
||||
-- Global mappings.
|
||||
-- See `:help vim.diagnostic.*` for documentation on any of the below functions
|
||||
|
@ -661,7 +675,6 @@ require("lsp_signature").setup({})
|
|||
|
||||
vim.keymap.set({'i', 'n', 'v', 'x'}, '<C-z>', '<Nop>', {noremap=true})
|
||||
vim.keymap.set({'i', 'n', 'v', 'x'}, '<C-c>', '<ESC>', {noremap=true})
|
||||
vim.keymap.set('i', '<C-v>', '<ESC>PA')
|
||||
vim.keymap.set('i', '<C-x>', '<ESC>ddi')
|
||||
vim.keymap.set('i', '<Home>', '<ESC>^i')
|
||||
vim.keymap.set('i', '<C-a>', '<ESC>ggVG')
|
||||
|
@ -873,265 +886,9 @@ require('usage-tracker').setup({
|
|||
telemetry_endpoint = "" -- you'll need to start the restapi for this feature
|
||||
})
|
||||
|
||||
local function lines(str)
|
||||
local result = {}
|
||||
for line in str:gmatch '[^\n]+' do
|
||||
table.insert(result, line)
|
||||
end
|
||||
return result
|
||||
end
|
||||
local ls = require('luasnip')
|
||||
local snip = ls.snippet
|
||||
local text = ls.text_node
|
||||
|
||||
local include_snippet = [[
|
||||
#pragma GCC optimize("Ofast")
|
||||
/////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Useful Macros
|
||||
* by subcrip
|
||||
* (requires C++17)
|
||||
*/
|
||||
|
||||
#include<bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
/* macro helpers */
|
||||
#define __NARGS(...) std::tuple_size<decltype(std::make_tuple(__VA_ARGS__))>::value
|
||||
#define __DECOMPOSE_S(a, x) auto x = a;
|
||||
#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a;
|
||||
constexpr void __() {}
|
||||
#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __()
|
||||
#define __as_typeof(container) decltype(container)::value_type
|
||||
|
||||
/* type aliases */
|
||||
using ll = int64_t;
|
||||
using ull = uint64_t;
|
||||
using pii = pair<int, int>;
|
||||
using pil = pair<int, ll>;
|
||||
using pli = pair<ll, int>;
|
||||
using pll = pair<ll, ll>;
|
||||
|
||||
/* constants */
|
||||
constexpr int INF = 0x3f3f3f3f;
|
||||
constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
|
||||
constexpr ll MDL = 1e9 + 7;
|
||||
constexpr ll PRIME = 998'244'353;
|
||||
constexpr ll MDL1 = 8784491;
|
||||
constexpr ll MDL2 = PRIME;
|
||||
|
||||
/* random */
|
||||
|
||||
mt19937 rd(chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now().time_since_epoch()).count());
|
||||
|
||||
/* bit-wise operations */
|
||||
#define lowbit(x) ((x) & -(x))
|
||||
#define popcount(x) (__builtin_popcountll(ll(x)))
|
||||
#define parity(x) (__builtin_parityll(ll(x)))
|
||||
#define msp(x) (63LL - __builtin_clzll(ll(x)))
|
||||
#define lsp(x) (__builtin_ctzll(ll(x)))
|
||||
|
||||
/* arithmetic operations */
|
||||
#define mod(x, y) ((((x) % (y)) + (y)) % (y))
|
||||
|
||||
/* fast pairs */
|
||||
#define upair ull
|
||||
#define umake(x, y) (ull(x) << 32 | (ull(y) & ((1ULL << 32) - 1)))
|
||||
#define u1(p) ((p) >> 32)
|
||||
#define u2(p) ((p) & ((1ULL << 32) - 1))
|
||||
#define ult std::less<upair>
|
||||
#define ugt std::greater<upair>
|
||||
|
||||
#define ipair ull
|
||||
#define imake(x, y) (umake(x, y))
|
||||
#define i1(p) (int(u1(ll(p))))
|
||||
#define i2(p) (ll(u2(p) << 32) >> 32)
|
||||
struct ilt {
|
||||
bool operator()(const ipair& a, const ipair& b) const {
|
||||
if (i1(a) == i1(b)) return i2(a) < i2(b);
|
||||
else return i1(a) < i1(b);
|
||||
}
|
||||
};
|
||||
struct igt {
|
||||
bool operator()(const ipair& a, const ipair& b) const {
|
||||
if (i1(a) == i1(b)) return i2(a) > i2(b);
|
||||
else return i1(a) > i1(b);
|
||||
}
|
||||
};
|
||||
|
||||
/* conditions */
|
||||
#define loop while (1)
|
||||
#define if_or(var, val) if (!(var == val)) var = val; else
|
||||
#define continue_or(var, val) __AS_PROCEDURE(if (var == val) continue; var = val;)
|
||||
#define break_or(var, val) __AS_PROCEDURE(if (var == val) break; var = val;)
|
||||
|
||||
/* hash */
|
||||
struct safe_hash {
|
||||
// https://codeforces.com/blog/entry/62393
|
||||
static uint64_t splitmix64(uint64_t x) {
|
||||
// http://xorshift.di.unimi.it/splitmix64.c
|
||||
x += 0x9e3779b97f4a7c15;
|
||||
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
|
||||
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
|
||||
return x ^ (x >> 31);
|
||||
}
|
||||
|
||||
size_t operator()(uint64_t x) const {
|
||||
static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
|
||||
return splitmix64(x + FIXED_RANDOM);
|
||||
}
|
||||
};
|
||||
|
||||
struct pair_hash {
|
||||
template <typename T, typename U>
|
||||
size_t operator()(const pair<T, U>& a) const {
|
||||
auto hash1 = safe_hash()(a.first);
|
||||
auto hash2 = safe_hash()(a.second);
|
||||
if (hash1 != hash2) {
|
||||
return hash1 ^ hash2;
|
||||
}
|
||||
return hash1;
|
||||
}
|
||||
};
|
||||
|
||||
/* build data structures */
|
||||
#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];)
|
||||
#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];)
|
||||
#define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);)
|
||||
#define sa(a) __AS_PROCEDURE(__typeof(a) sa(a.size() + 1); {int n = a.size(); for (int i = n - 1; i >= 0; --i) sa[i] = sa[i + 1] + a[i];};)
|
||||
#define adj(ch, n) __AS_PROCEDURE(vector<vector<int>> ch((n) + 1);)
|
||||
#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);)
|
||||
#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);)
|
||||
template <typename T, typename Iterator> pair<size_t, map<T, size_t>> discretize(Iterator __first, Iterator __last) {
|
||||
set<T> st(__first, __last);
|
||||
size_t N = 0;
|
||||
map<T, size_t> mp;
|
||||
for (auto&& x : st) mp[x] = ++N;
|
||||
return {N, mp};
|
||||
}
|
||||
template <typename T, typename Iterator> pair<size_t, unordered_map<T, size_t, safe_hash>> unordered_discretize(Iterator __first, Iterator __last) {
|
||||
set<T> st(__first, __last);
|
||||
size_t N = 0;
|
||||
unordered_map<T, size_t, safe_hash> mp;
|
||||
for (auto&& x : st) mp[x] = ++N;
|
||||
return {N, mp};
|
||||
}
|
||||
|
||||
/* io */
|
||||
#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL))
|
||||
template<typename T> void __read(T& x) { cin >> x; }
|
||||
template<typename T, typename... U> void __read(T& x, U&... args) { cin >> x; __read(args...); }
|
||||
#define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);)
|
||||
#define readvec(type, a, n) __AS_PROCEDURE(vector<type> a(n); for (int i = 0; i < (n); ++i) cin >> a[i];)
|
||||
#define putvec(a) __AS_PROCEDURE(for (auto&& x : a) cout << x << ' '; cout << endl;)
|
||||
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
|
||||
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
|
||||
template<typename T, typename U> ostream& operator<<(ostream& out, const pair<T, U>& p) {
|
||||
out << "{" << p.first << ", " << p.second << "}";
|
||||
return out;
|
||||
}
|
||||
template<typename Char, typename Traits, typename Tuple, std::size_t... Index>
|
||||
void print_tuple_impl(std::basic_ostream<Char, Traits>& os, const Tuple& t, std::index_sequence<Index...>) {
|
||||
using swallow = int[]; // guaranties left to right order
|
||||
(void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get<Index>(t)), 0)... };
|
||||
}
|
||||
template<typename Char, typename Traits, typename... Args>
|
||||
decltype(auto) operator<<(std::basic_ostream<Char, Traits>& os, const std::tuple<Args...>& t) {
|
||||
os << "{";
|
||||
print_tuple_impl(os, t, std::index_sequence_for<Args...>{});
|
||||
return os << "}";
|
||||
}
|
||||
template<typename T> ostream& operator<<(ostream& out, const vector<T>& vec) {
|
||||
for (auto&& i : vec) out << i << ' ';
|
||||
return out;
|
||||
}
|
||||
|
||||
/* pops */
|
||||
#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();)
|
||||
#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();)
|
||||
#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();)
|
||||
|
||||
/* math */
|
||||
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
|
||||
|
||||
void __exgcd(ll a, ll b, ll& x, ll& y) {
|
||||
if (b == 0) {
|
||||
x = 1, y = 0;
|
||||
return;
|
||||
}
|
||||
__exgcd(b, a % b, y, x);
|
||||
y -= a / b * x;
|
||||
}
|
||||
|
||||
ll inverse(ll a, ll b) {
|
||||
ll x, y;
|
||||
__exgcd(a, b, x, y);
|
||||
return mod(x, b);
|
||||
}
|
||||
|
||||
/* string algorithms */
|
||||
vector<int> calc_next(string t) { // pi function of t
|
||||
int n = (int)t.length();
|
||||
vector<int> pi(n);
|
||||
for (int i = 1; i < n; i++) {
|
||||
int j = pi[i - 1];
|
||||
while (j > 0 && t[i] != t[j]) j = pi[j - 1];
|
||||
if (t[i] == t[j]) j++;
|
||||
pi[i] = j;
|
||||
}
|
||||
return pi;
|
||||
}
|
||||
vector<int> calc_z(string t) { // z function of t
|
||||
int m = t.length();
|
||||
vector<int> z;
|
||||
z.push_back(m);
|
||||
pair<int, int> prev = {1, -1};
|
||||
for (int i = 1; i < m; ++i) {
|
||||
if (z[i - prev.first] + i <= prev.second) {
|
||||
z.push_back(z[i - prev.first]);
|
||||
} else {
|
||||
int j = max(i, prev.second + 1);
|
||||
while (j < m && t[j] == t[j - i]) ++j;
|
||||
z.push_back(j - i);
|
||||
prev = {i, j - 1};
|
||||
}
|
||||
}
|
||||
return z;
|
||||
}
|
||||
vector<int> kmp(string s, string t) { // find all t in s
|
||||
string cur = t + '#' + s;
|
||||
int sz1 = s.size(), sz2 = t.size();
|
||||
vector<int> v;
|
||||
vector<int> lps = calc_next(cur);
|
||||
for (int i = sz2 + 1; i <= sz1 + sz2; i++) {
|
||||
if (lps[i] == sz2) v.push_back(i - 2 * sz2);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
int period(string s) { // find the length of shortest recurring period
|
||||
int n = s.length();
|
||||
auto z = calc_z(s);
|
||||
for (int i = 1; i <= n / 2; ++i) {
|
||||
if (n % i == 0 && z[i] == n - i) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
/////////////////////////////////////////////////////////
|
||||
]]
|
||||
|
||||
ls.add_snippets(nil, {
|
||||
cpp = {
|
||||
snip({
|
||||
trig = 'include',
|
||||
namr = 'Useful Macros',
|
||||
dscr = 'Useful Macros',
|
||||
},{
|
||||
text(lines(include_snippet))
|
||||
})
|
||||
}
|
||||
})
|
||||
-- my snippets
|
||||
require('snippets')
|
||||
|
||||
require('neo-tree').setup {
|
||||
filesystem = {
|
||||
|
@ -1308,3 +1065,8 @@ require('codesnap').setup {
|
|||
code_font_family = "Fira Code",
|
||||
has_line_number = true,
|
||||
}
|
||||
|
||||
require('goto-preview').setup {
|
||||
default_mappings = true;
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
return {
|
||||
name = "c++ build (cp)",
|
||||
builder = function()
|
||||
-- Full path to current file (see :help expand())
|
||||
local file = vim.fn.expand("%:p")
|
||||
return {
|
||||
cmd = { "g++ -std=c++17 " .. file .. " -fsanitize=address -Ofast -Wall && ./a.out < std.in > std.out" },
|
||||
args = { file },
|
||||
components = { { "on_output_quickfix", open = true }, "default" },
|
||||
}
|
||||
end,
|
||||
condition = {
|
||||
filetype = { "cpp" },
|
||||
},
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
return [[
|
||||
template<typename T>
|
||||
struct BIT {
|
||||
int n;
|
||||
vector<T> c;
|
||||
BIT(size_t n) : n(n), c(n + 1) {}
|
||||
void add(size_t i, const T& k) {
|
||||
while (i <= n) {
|
||||
c[i] += k;
|
||||
i += lowbit(i);
|
||||
}
|
||||
}
|
||||
T getsum(size_t i) {
|
||||
T res = {};
|
||||
while (i) {
|
||||
res += c[i];
|
||||
i -= lowbit(i);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
]]
|
|
@ -0,0 +1,237 @@
|
|||
return [[
|
||||
#pragma GCC optimize("Ofast")
|
||||
/////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Useful Macros
|
||||
* by subcrip
|
||||
* (requires C++17)
|
||||
*/
|
||||
|
||||
#include<bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
/* macro helpers */
|
||||
#define __NARGS(...) std::tuple_size<decltype(std::make_tuple(__VA_ARGS__))>::value
|
||||
#define __DECOMPOSE_S(a, x) auto x = a;
|
||||
#define __DECOMPOSE_N(a, ...) auto [__VA_ARGS__] = a;
|
||||
constexpr void __() {}
|
||||
#define __AS_PROCEDURE(...) __(); __VA_ARGS__; __()
|
||||
#define __as_typeof(container) decltype(container)::value_type
|
||||
|
||||
/* type aliases */
|
||||
using ll = int64_t;
|
||||
using ull = uint64_t;
|
||||
using pii = pair<int, int>;
|
||||
using pil = pair<int, ll>;
|
||||
using pli = pair<ll, int>;
|
||||
using pll = pair<ll, ll>;
|
||||
|
||||
/* constants */
|
||||
constexpr int INF = 0x3f3f3f3f;
|
||||
constexpr ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
|
||||
constexpr ll MDL = 1e9 + 7;
|
||||
constexpr ll PRIME = 998'244'353;
|
||||
constexpr ll MDL1 = 8784491;
|
||||
constexpr ll MDL2 = PRIME;
|
||||
|
||||
/* random */
|
||||
|
||||
mt19937 rd(chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now().time_since_epoch()).count());
|
||||
|
||||
/* bit-wise operations */
|
||||
#define lowbit(x) ((x) & -(x))
|
||||
#define popcount(x) (__builtin_popcountll(ll(x)))
|
||||
#define parity(x) (__builtin_parityll(ll(x)))
|
||||
#define msp(x) (63LL - __builtin_clzll(ll(x)))
|
||||
#define lsp(x) (__builtin_ctzll(ll(x)))
|
||||
|
||||
/* arithmetic operations */
|
||||
#define mod(x, y) ((((x) % (y)) + (y)) % (y))
|
||||
|
||||
/* fast pairs */
|
||||
#define upair ull
|
||||
#define umake(x, y) (ull(x) << 32 | (ull(y) & ((1ULL << 32) - 1)))
|
||||
#define u1(p) ((p) >> 32)
|
||||
#define u2(p) ((p) & ((1ULL << 32) - 1))
|
||||
#define ult std::less<upair>
|
||||
#define ugt std::greater<upair>
|
||||
|
||||
#define ipair ull
|
||||
#define imake(x, y) (umake(x, y))
|
||||
#define i1(p) (int(u1(ll(p))))
|
||||
#define i2(p) (ll(u2(p) << 32) >> 32)
|
||||
struct ilt {
|
||||
bool operator()(const ipair& a, const ipair& b) const {
|
||||
if (i1(a) == i1(b)) return i2(a) < i2(b);
|
||||
else return i1(a) < i1(b);
|
||||
}
|
||||
};
|
||||
struct igt {
|
||||
bool operator()(const ipair& a, const ipair& b) const {
|
||||
if (i1(a) == i1(b)) return i2(a) > i2(b);
|
||||
else return i1(a) > i1(b);
|
||||
}
|
||||
};
|
||||
|
||||
/* conditions */
|
||||
#define loop while (1)
|
||||
#define if_or(var, val) if (!(var == val)) var = val; else
|
||||
#define continue_or(var, val) __AS_PROCEDURE(if (var == val) continue; var = val;)
|
||||
#define break_or(var, val) __AS_PROCEDURE(if (var == val) break; var = val;)
|
||||
|
||||
/* hash */
|
||||
struct safe_hash {
|
||||
// https://codeforces.com/blog/entry/62393
|
||||
static uint64_t splitmix64(uint64_t x) {
|
||||
// http://xorshift.di.unimi.it/splitmix64.c
|
||||
x += 0x9e3779b97f4a7c15;
|
||||
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
|
||||
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
|
||||
return x ^ (x >> 31);
|
||||
}
|
||||
|
||||
size_t operator()(uint64_t x) const {
|
||||
static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
|
||||
return splitmix64(x + FIXED_RANDOM);
|
||||
}
|
||||
};
|
||||
|
||||
struct pair_hash {
|
||||
template <typename T, typename U>
|
||||
size_t operator()(const pair<T, U>& a) const {
|
||||
auto hash1 = safe_hash()(a.first);
|
||||
auto hash2 = safe_hash()(a.second);
|
||||
if (hash1 != hash2) {
|
||||
return hash1 ^ hash2;
|
||||
}
|
||||
return hash1;
|
||||
}
|
||||
};
|
||||
|
||||
/* build data structures */
|
||||
#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];)
|
||||
#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];)
|
||||
#define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);)
|
||||
#define sa(a) __AS_PROCEDURE(__typeof(a) sa(a.size() + 1); {int n = a.size(); for (int i = n - 1; i >= 0; --i) sa[i] = sa[i + 1] + a[i];};)
|
||||
#define adj(ch, n) __AS_PROCEDURE(vector<vector<int>> ch((n) + 1);)
|
||||
#define edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v), ch[v].push_back(u);)
|
||||
#define Edge(ch, u, v) __AS_PROCEDURE(ch[u].push_back(v);)
|
||||
template <typename T, typename Iterator> pair<size_t, map<T, size_t>> discretize(Iterator __first, Iterator __last) {
|
||||
set<T> st(__first, __last);
|
||||
size_t N = 0;
|
||||
map<T, size_t> mp;
|
||||
for (auto&& x : st) mp[x] = ++N;
|
||||
return {N, mp};
|
||||
}
|
||||
template <typename T, typename Iterator> pair<size_t, unordered_map<T, size_t, safe_hash>> unordered_discretize(Iterator __first, Iterator __last) {
|
||||
set<T> st(__first, __last);
|
||||
size_t N = 0;
|
||||
unordered_map<T, size_t, safe_hash> mp;
|
||||
for (auto&& x : st) mp[x] = ++N;
|
||||
return {N, mp};
|
||||
}
|
||||
|
||||
/* io */
|
||||
#define untie __AS_PROCEDURE(ios_base::sync_with_stdio(0), cin.tie(NULL))
|
||||
template<typename T> void __read(T& x) { cin >> x; }
|
||||
template<typename T, typename... U> void __read(T& x, U&... args) { cin >> x; __read(args...); }
|
||||
#define read(type, ...) __AS_PROCEDURE(type __VA_ARGS__; __read(__VA_ARGS__);)
|
||||
#define readvec(type, a, n) __AS_PROCEDURE(vector<type> a(n); for (int i = 0; i < (n); ++i) cin >> a[i];)
|
||||
#define putvec(a) __AS_PROCEDURE(for (auto&& x : a) cout << x << ' '; cout << endl;)
|
||||
#define debug(x) __AS_PROCEDURE(cerr << #x" = " << (x) << endl;)
|
||||
#define debugvec(a) __AS_PROCEDURE(cerr << #a" = "; for (auto&& x : a) cerr << x << ' '; cerr << endl;)
|
||||
template<typename T, typename U> ostream& operator<<(ostream& out, const pair<T, U>& p) {
|
||||
out << "{" << p.first << ", " << p.second << "}";
|
||||
return out;
|
||||
}
|
||||
template<typename Char, typename Traits, typename Tuple, std::size_t... Index>
|
||||
void print_tuple_impl(std::basic_ostream<Char, Traits>& os, const Tuple& t, std::index_sequence<Index...>) {
|
||||
using swallow = int[]; // guaranties left to right order
|
||||
(void)swallow { 0, (void(os << (Index == 0 ? "" : ", ") << std::get<Index>(t)), 0)... };
|
||||
}
|
||||
template<typename Char, typename Traits, typename... Args>
|
||||
decltype(auto) operator<<(std::basic_ostream<Char, Traits>& os, const std::tuple<Args...>& t) {
|
||||
os << "{";
|
||||
print_tuple_impl(os, t, std::index_sequence_for<Args...>{});
|
||||
return os << "}";
|
||||
}
|
||||
template<typename T> ostream& operator<<(ostream& out, const vector<T>& vec) {
|
||||
for (auto&& i : vec) out << i << ' ';
|
||||
return out;
|
||||
}
|
||||
|
||||
/* pops */
|
||||
#define poptop(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.top(); q.pop();)
|
||||
#define popback(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.back(); q.pop_back();)
|
||||
#define popfront(q, ...) __AS_PROCEDURE(auto [__VA_ARGS__] = q.front();q.pop_front();)
|
||||
|
||||
/* math */
|
||||
constexpr inline int lg2(ll x) { return x == 0 ? -1 : sizeof(ll) * 8 - 1 - __builtin_clzll(x); }
|
||||
|
||||
void __exgcd(ll a, ll b, ll& x, ll& y) {
|
||||
if (b == 0) {
|
||||
x = 1, y = 0;
|
||||
return;
|
||||
}
|
||||
__exgcd(b, a % b, y, x);
|
||||
y -= a / b * x;
|
||||
}
|
||||
|
||||
ll inverse(ll a, ll b) {
|
||||
ll x, y;
|
||||
__exgcd(a, b, x, y);
|
||||
return mod(x, b);
|
||||
}
|
||||
|
||||
/* string algorithms */
|
||||
vector<int> calc_next(string t) { // pi function of t
|
||||
int n = (int)t.length();
|
||||
vector<int> pi(n);
|
||||
for (int i = 1; i < n; i++) {
|
||||
int j = pi[i - 1];
|
||||
while (j > 0 && t[i] != t[j]) j = pi[j - 1];
|
||||
if (t[i] == t[j]) j++;
|
||||
pi[i] = j;
|
||||
}
|
||||
return pi;
|
||||
}
|
||||
vector<int> calc_z(string t) { // z function of t
|
||||
int m = t.length();
|
||||
vector<int> z;
|
||||
z.push_back(m);
|
||||
pair<int, int> prev = {1, -1};
|
||||
for (int i = 1; i < m; ++i) {
|
||||
if (z[i - prev.first] + i <= prev.second) {
|
||||
z.push_back(z[i - prev.first]);
|
||||
} else {
|
||||
int j = max(i, prev.second + 1);
|
||||
while (j < m && t[j] == t[j - i]) ++j;
|
||||
z.push_back(j - i);
|
||||
prev = {i, j - 1};
|
||||
}
|
||||
}
|
||||
return z;
|
||||
}
|
||||
vector<int> kmp(string s, string t) { // find all t in s
|
||||
string cur = t + '#' + s;
|
||||
int sz1 = s.size(), sz2 = t.size();
|
||||
vector<int> v;
|
||||
vector<int> lps = calc_next(cur);
|
||||
for (int i = sz2 + 1; i <= sz1 + sz2; i++) {
|
||||
if (lps[i] == sz2) v.push_back(i - 2 * sz2);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
int period(string s) { // find the length of shortest recurring period
|
||||
int n = s.length();
|
||||
auto z = calc_z(s);
|
||||
for (int i = 1; i <= n / 2; ++i) {
|
||||
if (n % i == 0 && z[i] == n - i) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
/////////////////////////////////////////////////////////
|
||||
]]
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
return [[
|
||||
namespace Exgcd {
|
||||
template <typename T> T abs(T x) { return x < 0 ? -x : x; }
|
||||
|
||||
template <typename T>
|
||||
struct exgcd_solution_t {
|
||||
T x, y, gcd;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct diophantine_solution_t {
|
||||
exgcd_solution_t<T> x_min, y_min;
|
||||
T range;
|
||||
};
|
||||
|
||||
// solve `ax + by = gcd(a, b)`
|
||||
template <typename T>
|
||||
optional<exgcd_solution_t<T>> exgcd(T a, T b) {
|
||||
if (a < 0 || b < 0 || a == 0 && b == 0) return nullopt;
|
||||
T x, y, g;
|
||||
function<void(T, T)> __exgcd = [&__exgcd, &x, &y, &g] (T a, T b) -> void {
|
||||
if (b == 0) {
|
||||
g = a, x = 1, y = 0;
|
||||
} else {
|
||||
__exgcd(b, a % b);
|
||||
swap(x, y);
|
||||
y -= a / b * x;
|
||||
}
|
||||
};
|
||||
__exgcd(a, b);
|
||||
return {{ x, y, g }};
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
optional<T> inverse(T a, T b) {
|
||||
auto raw = exgcd(a, b);
|
||||
if (raw == nullopt || raw.value().gcd != 1) {
|
||||
return nullopt;
|
||||
} else {
|
||||
return mod(raw.value().x, b);
|
||||
}
|
||||
}
|
||||
|
||||
// solve { x = a_i (mod n_i) } if n_i's are coprime
|
||||
template <typename T>
|
||||
optional<T> crt(const vector<pair<T, T>>& equations) {
|
||||
T prod = 1;
|
||||
for (auto&& [a, n] : equations) {
|
||||
prod *= n;
|
||||
}
|
||||
T res = 0;
|
||||
for (auto&& [a, n] : equations) {
|
||||
T m = prod / n;
|
||||
auto m_rev = inverse(m, n);
|
||||
if (m_rev == nullopt) return nullopt;
|
||||
res = mod(res + a * mod(m * m_rev.value(), prod), prod);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// find minimal non-negative integral solutions of `ax + by = c`. It's not guaranteed that the other variable is non-negative.
|
||||
template <typename T>
|
||||
optional<diophantine_solution_t<T>> diophantine(T a, T b, T c, bool force_positive = false) {
|
||||
if (a < 0 || b < 0 || a == 0 && b == 0) return nullopt;
|
||||
auto raw = exgcd(a, b).value();
|
||||
if (c % raw.gcd) {
|
||||
return nullopt;
|
||||
} else {
|
||||
T x = raw.x * c / raw.gcd, y = raw.y * c / raw.gcd;
|
||||
T kx = force_positive ? (x <= 0 ? (-x) * raw.gcd / b + 1 : 1 - (x + b / raw.gcd - 1) * raw.gcd / b) : (x <= 0 ? ((-x) + b / raw.gcd - 1) * raw.gcd / b : (- x * raw.gcd / b));
|
||||
T ky = force_positive ? (y <= 0 ? (- 1 - (-y) * raw.gcd / a) : (y + a / raw.gcd - 1) * raw.gcd / a - 1) : (y <= 0 ? (- ((-y) + a / raw.gcd - 1) * raw.gcd / a) : y * raw.gcd / a);
|
||||
return {{ { x + b * kx / raw.gcd , y - a * kx / raw.gcd , raw.gcd }, { x + b * ky / raw.gcd , y - a * ky / raw.gcd, raw.gcd }, abs(kx - ky) + 1 }};
|
||||
}
|
||||
}
|
||||
|
||||
// find the minimal non-negative integral solution of `ax = b (mod n)`
|
||||
template <typename T>
|
||||
optional<T> congruential(T a, T b, T n) {
|
||||
if (a == 0) {
|
||||
if (b != 0) return nullopt;
|
||||
return 0;
|
||||
}
|
||||
if (a < 0 && a != LLONG_MIN && b != LLONG_MIN) a = -a, b = -b;
|
||||
auto sol = diophantine(a, n, b);
|
||||
if (sol == nullopt) {
|
||||
return nullopt;
|
||||
} else {
|
||||
return sol.value().x_min.x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
]]
|
|
@ -0,0 +1,176 @@
|
|||
return [[
|
||||
// @link https://www.acwing.com/file_system/file/content/whole/index/content/8807719/
|
||||
// Everything starts from 1
|
||||
|
||||
namespace treap_link {
|
||||
template <typename T> class prev {
|
||||
public:
|
||||
T operator()(const T& a) {
|
||||
return a - 1;
|
||||
}
|
||||
};
|
||||
template <typename T> class next {
|
||||
public:
|
||||
T operator()(const T& a) {
|
||||
return a + 1;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <typename T, typename Compare = less<T>,
|
||||
typename Prev = treap_link::prev<T>,
|
||||
typename Next = treap_link::next<T>>
|
||||
class treap {
|
||||
|
||||
#define lson fhq[u].l
|
||||
#define rson fhq[u].r
|
||||
private:
|
||||
using size_type = size_t;
|
||||
using value_type = T;
|
||||
using reference = value_type&;
|
||||
using const_reference = const reference;
|
||||
|
||||
struct Node {
|
||||
int key;
|
||||
size_type l, r, size;
|
||||
value_type val;
|
||||
};
|
||||
Compare __compare;
|
||||
Prev __prev;
|
||||
Next __next;
|
||||
vector<Node> fhq;
|
||||
size_type cnt, root;
|
||||
size_type x, y, z;
|
||||
size_type _size;
|
||||
|
||||
void pushup(size_type u) {
|
||||
fhq[u].size = fhq[lson].size + fhq[rson].size + 1;
|
||||
}
|
||||
|
||||
size_type node(value_type val) {
|
||||
if (cnt + 1 >= fhq.size()) {
|
||||
fhq.push_back({});
|
||||
}
|
||||
fhq[++cnt].val = val;
|
||||
fhq[cnt].key = rand();
|
||||
fhq[cnt].size = 1;
|
||||
return cnt;
|
||||
}
|
||||
|
||||
void split(size_type u, value_type val, size_type &x, size_type &y) {
|
||||
if (!u) x = y = 0;
|
||||
else {
|
||||
if (!__compare(val, fhq[u].val)) x = u, split(rson, val, rson, y);
|
||||
else y = u, split(lson, val, x, lson);
|
||||
pushup(u);
|
||||
}
|
||||
}
|
||||
|
||||
size_type merge(size_type x, size_type y) {
|
||||
if (!x || !y) return x + y;
|
||||
if (fhq[x].key <= fhq[y].key) {
|
||||
fhq[x].r = merge(fhq[x].r, y);
|
||||
pushup(x);
|
||||
return x;
|
||||
} else {
|
||||
fhq[y].l = merge(x, fhq[y].l);
|
||||
pushup(y);
|
||||
return y;
|
||||
}
|
||||
}
|
||||
|
||||
value_type askNum(size_type u, size_type rank) {
|
||||
if (fhq[lson].size + 1 == rank) return fhq[u].val;
|
||||
if (fhq[lson].size >= rank) return askNum(lson, rank);
|
||||
else return askNum(rson, rank - fhq[lson].size - 1);
|
||||
}
|
||||
|
||||
public:
|
||||
treap(Compare __compare = std::less<T>(),
|
||||
Prev __prev = treap_link::prev<T>(),
|
||||
Next __next = treap_link::next<T>()) :
|
||||
fhq(1), cnt(0), root(0), _size(0),
|
||||
__compare(__compare), __prev(__prev), __next(__next) {}
|
||||
treap(size_type n, Compare __compare = std::less<T>(),
|
||||
Prev __prev = treap_link::prev<T>(),
|
||||
Next __next = treap_link::next<T>()) :
|
||||
fhq(1), cnt(0), root(0), _size(0) {
|
||||
fhq.reserve(n + 1);
|
||||
}
|
||||
|
||||
template<typename _InputIterator,
|
||||
typename = std::_RequireInputIter<_InputIterator>>
|
||||
treap(_InputIterator __first, _InputIterator __last)
|
||||
: fhq(1), cnt(0), root(0), _size(0) {
|
||||
__try {
|
||||
for (; __first != __last; ++__first) {
|
||||
insert(*__first);
|
||||
}
|
||||
} __catch(...) {
|
||||
clear();
|
||||
__throw_exception_again;
|
||||
}
|
||||
}
|
||||
|
||||
void clear() {
|
||||
_size = root = cnt = 0;
|
||||
fill(fhq.begin(), fhq.end(), Node());
|
||||
}
|
||||
|
||||
void insert(value_type val) {
|
||||
++_size;
|
||||
split(root, val, x, y);
|
||||
root = merge(merge(x, node(val)), y);
|
||||
}
|
||||
|
||||
void remove(value_type val) {
|
||||
assert(contains(val));
|
||||
--_size;
|
||||
split(root, val, x, z);
|
||||
split(x, __prev(val), x, y);
|
||||
y = merge(fhq[y].l, fhq[y].r);
|
||||
root = merge(merge(x, y), z);
|
||||
}
|
||||
|
||||
size_type index_of(value_type val) {
|
||||
split(root, __prev(val), x, y);
|
||||
size_type res = fhq[x].size + 1;
|
||||
root = merge(x, y);
|
||||
return res;
|
||||
}
|
||||
|
||||
value_type at(size_type rank) {
|
||||
assert(rank > 0 && rank <= _size);
|
||||
return askNum(root, rank);
|
||||
}
|
||||
|
||||
value_type prev_element(value_type val) {
|
||||
split(root, __prev(val), x, y);
|
||||
size_type u = x;
|
||||
while (rson) u = rson;
|
||||
root = merge(x, y);
|
||||
return fhq[u].val;
|
||||
}
|
||||
|
||||
value_type next_element(value_type val) {
|
||||
split(root, val, x, y);
|
||||
size_type u = y;
|
||||
while (lson) u = lson;
|
||||
root = merge(x, y);
|
||||
return fhq[u].val;
|
||||
}
|
||||
|
||||
bool contains(value_type val) {
|
||||
size_type idx = index_of(val);
|
||||
return idx <= _size && at(idx) == val;
|
||||
}
|
||||
|
||||
size_type size() {
|
||||
return _size;
|
||||
}
|
||||
|
||||
#undef lson
|
||||
#undef rson
|
||||
};
|
||||
|
||||
]]
|
|
@ -0,0 +1,55 @@
|
|||
return [[
|
||||
static vector<ll> power1, power2;
|
||||
static const ll b = rd();
|
||||
static const ll INV1 = inverse(b, MDL1);
|
||||
static const ll INV2 = inverse(b, MDL2);
|
||||
template <typename _Tp, typename _Sequence = deque<_Tp>>
|
||||
struct hash_deque {
|
||||
using hash_type = pll;
|
||||
ll hash1, hash2;
|
||||
_Sequence seq;
|
||||
size_t size() {
|
||||
return seq.size();
|
||||
}
|
||||
void push_back(const _Tp& x) {
|
||||
hash1 = mod(mod(hash1 * b, MDL1) + mod(x, MDL1), MDL1);
|
||||
hash2 = mod(mod(hash2 * b, MDL2) + mod(x, MDL2), MDL2);
|
||||
seq.push_back(x);
|
||||
}
|
||||
void push_front(const _Tp& x) {
|
||||
size_t length = size();
|
||||
hash1 = mod(hash1 + mod(mod(x, MDL1) * power1[length], MDL1), MDL1);
|
||||
hash2 = mod(hash2 + mod(mod(x, MDL2) * power2[length], MDL2), MDL2);
|
||||
seq.push_front(x);
|
||||
}
|
||||
void pop_back() {
|
||||
_Tp e = seq.back(); seq.pop_back();
|
||||
hash1 = mod(mod(hash1 - mod(e, MDL1), MDL1) * INV1, MDL1);
|
||||
hash2 = mod(mod(hash2 - mod(e, MDL2), MDL2) * INV2, MDL2);
|
||||
}
|
||||
void pop_front() {
|
||||
_Tp e = seq.front(); seq.pop_front();
|
||||
int length = seq.size();
|
||||
hash1 = mod(hash1 - mod(e * power1[length], MDL1), MDL1);
|
||||
hash2 = mod(hash2 - mod(e * power2[length], MDL2), MDL2);
|
||||
}
|
||||
hash_type hash() {
|
||||
return {hash1, hash2};
|
||||
}
|
||||
void clear() {
|
||||
hash1 = hash2 = 0;
|
||||
seq.clear();
|
||||
}
|
||||
hash_deque(size_t maxn) {
|
||||
clear();
|
||||
int c1 = 1, c2 = 1;
|
||||
for (int i = power1.size(); i < maxn; ++i) {
|
||||
power1.push_back(c1);
|
||||
power2.push_back(c2);
|
||||
c1 = mod(c1 * b, MDL1);
|
||||
c2 = mod(c2 * b, MDL2);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
]]
|
|
@ -0,0 +1,72 @@
|
|||
return [[
|
||||
static vector<MLL<MDL1>> power1;
|
||||
static vector<MLL<MDL2>> power2;
|
||||
static const ll b = rd();
|
||||
template <typename _Tp>
|
||||
struct hash_vec {
|
||||
using hash_type = pll;
|
||||
MLL<MDL1> hash1;
|
||||
MLL<MDL2> hash2;
|
||||
vector<_Tp> seq;
|
||||
size_t size() {
|
||||
return seq.size();
|
||||
}
|
||||
void push_back(const _Tp& x) {
|
||||
hash1 = hash1 * b + x;
|
||||
hash2 = hash2 * b + x;
|
||||
seq.push_back(x);
|
||||
}
|
||||
void push_front(const _Tp& x) {
|
||||
size_t length = size();
|
||||
hash1 += x * power1[length];
|
||||
hash2 += x * power2[length];
|
||||
seq.push_front(x);
|
||||
}
|
||||
void pop_back() {
|
||||
_Tp e = seq.back(); seq.pop_back();
|
||||
hash1 = (hash1 - e) / b;
|
||||
hash2 = (hash2 - e) / b;
|
||||
}
|
||||
void pop_front() {
|
||||
_Tp e = seq.front(); seq.pop_front();
|
||||
int length = seq.size();
|
||||
hash1 -= e * power1[length];
|
||||
hash2 -= e * power2[length];
|
||||
}
|
||||
void set(size_t pos, const _Tp& value) {
|
||||
int length = seq.size();
|
||||
int old_value = seq[pos];
|
||||
hash1 += (value - old_value) * power1[length - 1 - pos];
|
||||
hash2 += (value - old_value) * power2[length - 1 - pos];
|
||||
seq[pos] = value;
|
||||
}
|
||||
const _Tp& operator[](size_t pos) {
|
||||
return seq[pos];
|
||||
}
|
||||
hash_type hash() {
|
||||
return {hash1.val, hash2.val};
|
||||
}
|
||||
void clear() {
|
||||
hash1 = 0;
|
||||
hash2 = 0;
|
||||
seq.clear();
|
||||
}
|
||||
hash_vec(size_t maxn) {
|
||||
clear();
|
||||
MLL<MDL1> c1 = 1;
|
||||
MLL<MDL2> c2 = 1;
|
||||
for (int i = power1.size(); i < maxn; ++i) {
|
||||
power1.push_back(c1);
|
||||
power2.push_back(c2);
|
||||
c1 *= b;
|
||||
c2 *= b;
|
||||
}
|
||||
}
|
||||
hash_vec(size_t maxn, const _Tp& init_value) : hash_vec(maxn) {
|
||||
for (size_t i = 0; i != maxn; ++i) {
|
||||
push_back(init_value);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
]]
|
|
@ -0,0 +1,181 @@
|
|||
local ls = require('luasnip')
|
||||
local snip = ls.snippet
|
||||
local text = ls.text_node
|
||||
|
||||
|
||||
local function lines(str)
|
||||
local result = {}
|
||||
for line in str:gmatch '[^\n]+' do
|
||||
table.insert(result, line)
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
local cpp_include = require('snippets.cpp-include')
|
||||
ls.add_snippets(nil, {
|
||||
cpp = {
|
||||
snip({
|
||||
trig = 'include',
|
||||
namr = 'cpp-include',
|
||||
dscr = 'Useful Macros',
|
||||
},{
|
||||
text(lines(cpp_include))
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
local segtree_generic = require('snippets.segtree-generic')
|
||||
ls.add_snippets(nil, {
|
||||
cpp = {
|
||||
snip({
|
||||
trig = 'segtree',
|
||||
namr = 'segtree_generic',
|
||||
dscr = 'Segment Tree with Lazy Propagation',
|
||||
},{
|
||||
text(lines(segtree_generic))
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
local fhq_treap = require('snippets.fhq-treap')
|
||||
ls.add_snippets(nil, {
|
||||
cpp = {
|
||||
snip({
|
||||
trig = 'treap',
|
||||
namr = 'fhq_treap',
|
||||
dscr = 'FHQ Treap',
|
||||
},{
|
||||
text(lines(fhq_treap))
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
local fhq_treap = require('snippets.fhq-treap')
|
||||
ls.add_snippets(nil, {
|
||||
cpp = {
|
||||
snip({
|
||||
trig = 'treap',
|
||||
namr = 'fhq_treap',
|
||||
dscr = 'FHQ Treap',
|
||||
},{
|
||||
text(lines(fhq_treap))
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
local bit = require('snippets.bit')
|
||||
ls.add_snippets(nil, {
|
||||
cpp = {
|
||||
snip({
|
||||
trig = 'bit',
|
||||
namr = 'bit',
|
||||
dscr = 'Bit-Indexed Tree',
|
||||
},{
|
||||
text(lines(bit))
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
local quick_union = require('snippets.quick-union')
|
||||
ls.add_snippets(nil, {
|
||||
cpp = {
|
||||
snip({
|
||||
trig = 'quick_union',
|
||||
namr = 'quick_union',
|
||||
dscr = 'Union Find',
|
||||
},{
|
||||
text(lines(quick_union))
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
local sparse_table = require('snippets.sparse-table')
|
||||
ls.add_snippets(nil, {
|
||||
cpp = {
|
||||
snip({
|
||||
trig = 'sparse_table',
|
||||
namr = 'sparse_table',
|
||||
dscr = 'Sparse Table',
|
||||
},{
|
||||
text(lines(sparse_table))
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
local hash_deque = require('snippets.hash-deque')
|
||||
ls.add_snippets(nil, {
|
||||
cpp = {
|
||||
snip({
|
||||
trig = 'hash_deque',
|
||||
namr = 'hash_deque',
|
||||
dscr = 'Hashable Deque',
|
||||
},{
|
||||
text(lines(hash_deque))
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
local hash_vec = require('snippets.hash-vec')
|
||||
ls.add_snippets(nil, {
|
||||
cpp = {
|
||||
snip({
|
||||
trig = 'hash_vec',
|
||||
namr = 'hash_vec',
|
||||
dscr = 'Hashable Vector',
|
||||
},{
|
||||
text(lines(hash_vec))
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
local exgcd = require('snippets.exgcd')
|
||||
ls.add_snippets(nil, {
|
||||
cpp = {
|
||||
snip({
|
||||
trig = 'exgcd',
|
||||
namr = 'exgcd',
|
||||
dscr = 'Extended GCD and Related',
|
||||
},{
|
||||
text(lines(exgcd))
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
local lpf = require('snippets.lpf')
|
||||
ls.add_snippets(nil, {
|
||||
cpp = {
|
||||
snip({
|
||||
trig = 'lpf',
|
||||
namr = 'lpf',
|
||||
dscr = 'Least Prime Factor',
|
||||
},{
|
||||
text(lines(lpf))
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
local pollard_rho = require('snippets.pollard-rho')
|
||||
ls.add_snippets(nil, {
|
||||
cpp = {
|
||||
snip({
|
||||
trig = 'pollard_rho',
|
||||
namr = 'pollard_rho',
|
||||
dscr = 'Pollard-Rho',
|
||||
},{
|
||||
text(lines(pollard_rho))
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
local tarjan = require('snippets.tarjan')
|
||||
ls.add_snippets(nil, {
|
||||
cpp = {
|
||||
snip({
|
||||
trig = 'tarjan',
|
||||
namr = 'tarjan',
|
||||
dscr = 'Tarjan and Related',
|
||||
},{
|
||||
text(lines(tarjan))
|
||||
})
|
||||
}
|
||||
})
|
|
@ -0,0 +1,22 @@
|
|||
return [[
|
||||
constexpr int N = 1e7 + 10;
|
||||
|
||||
int lpf[N];
|
||||
|
||||
void era(int n) {
|
||||
lpf[0] = lpf[1] = -1;
|
||||
for (int i = 2; i <= n; ++i) lpf[i] = i;
|
||||
for (int i = 2; i <= n; ++i) {
|
||||
if (lpf[i] == i) {
|
||||
if ((ll)i * i > n) continue;
|
||||
for (int j = i * i; j <= n; j += i) {
|
||||
if (lpf[j] == j) {
|
||||
lpf[j] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
]]
|
|
@ -0,0 +1,91 @@
|
|||
return [[
|
||||
vector<tuple<int, int, ll>> decompose(ll x) {
|
||||
vector<tuple<int, int, ll>> res;
|
||||
for (int i = 2; i * i <= x; i++) {
|
||||
if (x % i == 0) {
|
||||
int cnt = 0;
|
||||
ll pw = 1;
|
||||
while (x % i == 0) ++cnt, x /= i, pw *= i;
|
||||
res.emplace_back(i, cnt, pw);
|
||||
}
|
||||
}
|
||||
if (x != 1) {
|
||||
res.emplace_back(x, 1, x);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
struct pollard_rho {
|
||||
ll max_factor;
|
||||
|
||||
pollard_rho() : max_factor(0) { srand(time(NULL)); }
|
||||
|
||||
ll quick_pow(ll x, ll p, ll mod) {
|
||||
ll ans = 1;
|
||||
while (p) {
|
||||
if (p & 1) ans = (__int128)ans * x % mod;
|
||||
x = (__int128)x * x % mod;
|
||||
p >>= 1;
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
bool Miller_Rabin(ll p) {
|
||||
if (p < 2) return 0;
|
||||
if (p == 2) return 1;
|
||||
if (p == 3) return 1;
|
||||
ll d = p - 1, r = 0;
|
||||
while (!(d & 1)) ++r, d >>= 1;
|
||||
for (ll k = 0; k < 10; ++k) {
|
||||
ll a = rand() % (p - 2) + 2;
|
||||
ll x = quick_pow(a, d, p);
|
||||
if (x == 1 || x == p - 1) continue;
|
||||
for (int i = 0; i < r - 1; ++i) {
|
||||
x = (__int128)x * x % p;
|
||||
if (x == p - 1) break;
|
||||
}
|
||||
if (x != p - 1) return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
ll Pollard_Rho(ll x) {
|
||||
ll s = 0, t = 0;
|
||||
ll c = (ll)rand() % (x - 1) + 1;
|
||||
int step = 0, goal = 1;
|
||||
ll val = 1;
|
||||
for (goal = 1;; goal *= 2, s = t, val = 1) {
|
||||
for (step = 1; step <= goal; ++step) {
|
||||
t = ((__int128)t * t + c) % x;
|
||||
val = (__int128)val * abs(t - s) % x;
|
||||
if ((step % 127) == 0) {
|
||||
ll d = gcd(val, x);
|
||||
if (d > 1) return d;
|
||||
}
|
||||
}
|
||||
ll d = gcd(val, x);
|
||||
if (d > 1) return d;
|
||||
}
|
||||
}
|
||||
|
||||
void fac(ll x) {
|
||||
if (x <= max_factor || x < 2) return;
|
||||
if (Miller_Rabin(x)) {
|
||||
max_factor = max(max_factor, x);
|
||||
return;
|
||||
}
|
||||
ll p = x;
|
||||
while (p >= x) p = Pollard_Rho(x);
|
||||
while ((x % p) == 0) x /= p;
|
||||
fac(x), fac(p);
|
||||
}
|
||||
|
||||
// find greatest prime factor of `x`
|
||||
ll solve(ll x) {
|
||||
max_factor = 0;
|
||||
fac(x);
|
||||
return max_factor;
|
||||
}
|
||||
};
|
||||
|
||||
]]
|
|
@ -0,0 +1,31 @@
|
|||
return [[
|
||||
class quick_union {
|
||||
private:
|
||||
vector<size_t> c, sz;
|
||||
public:
|
||||
quick_union(size_t n) : c(n), sz(n) {
|
||||
iota(c.begin(), c.end(), 0);
|
||||
sz.assign(n, 1);
|
||||
}
|
||||
|
||||
size_t query(size_t i) {
|
||||
if (c[i] != i) c[i] = query(c[i]);
|
||||
return c[i];
|
||||
}
|
||||
|
||||
void merge(size_t i, size_t j) {
|
||||
if (connected(i, j)) return;
|
||||
sz[query(j)] += sz[query(i)];
|
||||
c[query(i)] = query(j);
|
||||
}
|
||||
|
||||
bool connected(size_t i, size_t j) {
|
||||
return query(i) == query(j);
|
||||
}
|
||||
|
||||
size_t query_size(size_t i) {
|
||||
return sz[query(i)];
|
||||
}
|
||||
};
|
||||
|
||||
]]
|
|
@ -0,0 +1,128 @@
|
|||
return [[
|
||||
|
||||
template<typename Addable_Info_t, typename Tag_t, typename Sequence = std::vector<Addable_Info_t>> class segtree {
|
||||
private:
|
||||
using size_type = uint64_t;
|
||||
using info_type = Addable_Info_t;
|
||||
using tag_type = Tag_t;
|
||||
size_type _max;
|
||||
vector<info_type> d;
|
||||
vector<tag_type> b;
|
||||
|
||||
void pull(size_type p) {
|
||||
d[p] = d[p * 2] + d[p * 2 + 1];
|
||||
}
|
||||
|
||||
void push(size_type p, size_type left_len, size_type right_len) {
|
||||
d[p * 2].apply(b[p], left_len), d[p * 2 + 1].apply(b[p], right_len);
|
||||
b[p * 2].apply(b[p]), b[p * 2 + 1].apply(b[p]);
|
||||
b[p] = tag_type();
|
||||
}
|
||||
|
||||
void set(size_type s, size_type t, size_type p, size_type x, const info_type& c) {
|
||||
if (s == t) {
|
||||
d[p] = c;
|
||||
return;
|
||||
}
|
||||
size_type m = s + (t - s >> 1);
|
||||
if (s != t) push(p, m - s + 1, t - m);
|
||||
if (x <= m) set(s, m, p * 2, x, c);
|
||||
else set(m + 1, t, p * 2 + 1, x, c);
|
||||
d[p] = d[p * 2] + d[p * 2 + 1];
|
||||
}
|
||||
|
||||
void range_apply(size_type s, size_type t, size_type p, size_type l, size_type r, const tag_type& c) {
|
||||
if (l <= s && t <= r) {
|
||||
d[p].apply(c, t - s + 1);
|
||||
b[p].apply(c);
|
||||
return;
|
||||
}
|
||||
size_type m = s + (t - s >> 1);
|
||||
push(p, m - s + 1, t - m);
|
||||
if (l <= m) range_apply(s, m, p * 2, l, r, c);
|
||||
if (r > m) range_apply(m + 1, t, p * 2 + 1, l, r, c);
|
||||
pull(p);
|
||||
}
|
||||
|
||||
info_type range_query(size_type s, size_type t, size_type p, size_type l, size_type r) {
|
||||
if (l <= s && t <= r) {
|
||||
return d[p];
|
||||
}
|
||||
size_type m = s + (t - s >> 1);
|
||||
info_type res = {};
|
||||
push(p, m - s + 1, t - m);
|
||||
if (l <= m) res = res + range_query(s, m, p * 2, l, r);
|
||||
if (r > m) res = res + range_query(m + 1, t, p * 2 + 1, l, r);
|
||||
return res;
|
||||
}
|
||||
|
||||
void build(const Sequence& a, size_type s, size_type t, size_type p) {
|
||||
if (s == t) {
|
||||
d[p] = a[s];
|
||||
return;
|
||||
}
|
||||
int m = s + (t - s >> 1);
|
||||
build(a, s, m, p * 2);
|
||||
build(a, m + 1, t, p * 2 + 1);
|
||||
pull(p);
|
||||
}
|
||||
public:
|
||||
segtree(size_type __max) : d(4 * __max), b(4 * __max), _max(__max - 1) {}
|
||||
segtree(const Sequence& a) : segtree(a.size()) {
|
||||
build(a, {}, _max, 1);
|
||||
}
|
||||
|
||||
void set(size_type i, const info_type& c) {
|
||||
set({}, _max, 1, i, c);
|
||||
}
|
||||
|
||||
void range_apply(size_type l, size_type r, const tag_type& c) {
|
||||
range_apply({}, _max, 1, l, r, c);
|
||||
}
|
||||
|
||||
void apply(size_type i, const tag_type& c) {
|
||||
range_apply(i, i, c);
|
||||
}
|
||||
|
||||
info_type range_query(size_type l, size_type r) {
|
||||
return range_query({}, _max, 1, l, r);
|
||||
}
|
||||
|
||||
info_type query(size_type i) {
|
||||
return range_query(i, i);
|
||||
}
|
||||
|
||||
Sequence serialize() {
|
||||
Sequence res = {};
|
||||
for (size_type i = 0; i <= _max; ++i) {
|
||||
res.push_back(query(i));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
const vector<info_type>& get_d() {
|
||||
return d;
|
||||
}
|
||||
};
|
||||
|
||||
struct Tag {
|
||||
ll val = -1;
|
||||
void apply(const Tag& rhs) {
|
||||
if (rhs.val != -1)
|
||||
val = rhs.val;
|
||||
}
|
||||
};
|
||||
|
||||
struct Info {
|
||||
ll val = 0;
|
||||
void apply(const Tag& rhs, size_t len) {
|
||||
if (rhs.val != -1)
|
||||
val = rhs.val * len;
|
||||
}
|
||||
};
|
||||
|
||||
Info operator+(const Info &a, const Info &b) {
|
||||
return {a.val + b.val};
|
||||
}
|
||||
|
||||
]]
|
|
@ -0,0 +1,25 @@
|
|||
return [[
|
||||
template<typename _Tp, typename _Op = function<_Tp(const _Tp&, const _Tp&)>> struct sparse_table {
|
||||
_Op op;
|
||||
vector<vector<_Tp>> st;
|
||||
template <typename ReverseIterator>
|
||||
sparse_table(ReverseIterator __first, ReverseIterator __last, _Op&& __operation) {
|
||||
op = __operation;
|
||||
int n = distance(__first, __last);
|
||||
st = vector<vector<_Tp>>(n, vector<_Tp>(int(log2(n) + 1)));
|
||||
int i = n - 1;
|
||||
for (auto it = __first; it != __last; ++it) {
|
||||
st[i][0] = *it;
|
||||
for (int j = 1; i + (1 << j) <= n; ++j) {
|
||||
st[i][j] = op(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
|
||||
}
|
||||
i -= 1;
|
||||
}
|
||||
}
|
||||
_Tp query(size_t __start, size_t __end) {
|
||||
int s = lg2(__end - __start + 1);
|
||||
return op(st[__start][s], st[__end - (1 << s) + 1][s]);
|
||||
}
|
||||
};
|
||||
|
||||
]]
|
|
@ -0,0 +1,71 @@
|
|||
return [=[
|
||||
namespace tarjan {
|
||||
// Returns the mapping between vertices and their affiliated sccs.
|
||||
vector<int> scc(const vector<vector<int>>& ch) {
|
||||
int n = ch.size();
|
||||
int cnt = 0, scn = 0;
|
||||
vector<int> dfn(n), low(n), vis(n), st;
|
||||
vector<int> br(n);
|
||||
auto tarjan = [&] (auto tarjan, int v) -> void {
|
||||
dfn[v]=low[v]=++cnt;
|
||||
st.push_back(v);
|
||||
vis[v]=1;
|
||||
for(const auto&u:ch[v])
|
||||
if(!dfn[u]) tarjan(tarjan, u),low[v]=min(low[v],low[u]);
|
||||
else if(vis[u])low[v]=min(low[v],dfn[u]);
|
||||
if(dfn[v]==low[v]){
|
||||
++scn;
|
||||
int u;
|
||||
do u=st.back(), st.pop_back(),vis[u]=0,br[u]=scn; while(u!=v);
|
||||
}
|
||||
};
|
||||
for (int i = 0; i < n; ++i) {
|
||||
if (!dfn[i]) {
|
||||
tarjan(tarjan, i);
|
||||
}
|
||||
}
|
||||
return br;
|
||||
}
|
||||
|
||||
// This method can eliminate redundant edges or self-loops
|
||||
vector<vector<int>> build_scc(const vector<vector<int>>& ch) {
|
||||
int n = ch.size();
|
||||
auto br = scc(ch);
|
||||
int cnt = *max_element(br.begin(), br.end());
|
||||
vector<unordered_set<int, safe_hash>> rb(cnt + 1);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
for (auto&& u : ch[i]) {
|
||||
if (br[i] != br[u]) rb[br[i]].emplace(br[u]);
|
||||
}
|
||||
}
|
||||
vector<vector<int>> res(cnt + 1);
|
||||
for (int i = 1; i <= cnt; ++i) {
|
||||
res[i] = vector<int>(rb[i].begin(), rb[i].end());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// This method can eliminate redundant edges or self-loops
|
||||
// return form: (scc size, children of scc)
|
||||
vector<pair<size_t, vector<int>>> build_scc_with_size(const vector<vector<int>>& ch) {
|
||||
int n = ch.size();
|
||||
auto br = scc(ch);
|
||||
int cnt = *max_element(br.begin(), br.end());
|
||||
vector<unordered_set<int, safe_hash>> rb(cnt + 1);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
for (auto&& u : ch[i]) {
|
||||
if (br[i] != br[u]) rb[br[i]].emplace(br[u]);
|
||||
}
|
||||
}
|
||||
vector<pair<size_t, vector<int>>> res(cnt + 1);
|
||||
for (int i = 1; i <= cnt; ++i) {
|
||||
res[i].second = vector<int>(rb[i].begin(), rb[i].end());
|
||||
}
|
||||
for (int i = 1; i <= n; ++i) {
|
||||
res[br[i]].first += 1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
]=]
|
Loading…
Reference in New Issue