├── base_convert.cpp ├── berlekamp_massey.cpp ├── big_int.cpp ├── bitvec.cpp ├── calc_mertens.cpp ├── dominator_tree.cpp ├── dsu.cpp ├── dynamic_cht.cpp ├── edmonds_matching.cpp ├── egcd.cpp ├── factorizer.cpp ├── fast_allocator.cpp ├── fenwick.cpp ├── fenwick2d.cpp ├── fft.cpp ├── first_in_range.cpp ├── fwht.cpp ├── geometry.cpp ├── grid_iterator.cpp ├── hash_table.cpp ├── lca_sparse.cpp ├── lichao.cpp ├── line.cpp ├── matching_dinic.cpp ├── matching_kuhn.cpp ├── matrix.cpp ├── max_flow_dinic.cpp ├── max_flow_dinic_scaling.cpp ├── min_cost_flow.cpp ├── min_queue.cpp ├── mint.cpp ├── mint14.cpp ├── nim_prod.cpp ├── nim_prod_slow.cpp ├── ntt.cpp ├── old ├── fft.cpp ├── segtree.cpp ├── segtree_max_modify_equal.cpp ├── segtree_max_modify_sum.cpp ├── segtree_sum_max_modify_equal.cpp ├── segtree_sum_max_modify_sum.cpp ├── segtree_sum_max_modify_sum_equal.cpp ├── segtree_sum_modify_sum.cpp └── suffix_array_nlogn.cpp ├── point.cpp ├── point3d.cpp ├── pow_mod.cpp ├── pow_no_mod.cpp ├── precursive.cpp ├── prefix_function.cpp ├── prime_count.cpp ├── prime_count_slow.cpp ├── print_int128.cpp ├── random.cpp ├── ranges.cpp ├── rational.cpp ├── scc.cpp ├── segtree.cpp ├── segtree_.cpp ├── segtree_beats.cpp ├── segtree_lazy.cpp ├── sieve.cpp ├── small_vec.cpp ├── sparse_table.cpp ├── static_pointer.cpp ├── subset_convolution.cpp ├── suffix_array.cpp ├── suffix_tree.cpp ├── tensor.cpp ├── tools ├── gen.cpp ├── macro_map.h ├── print.cpp └── sublime │ ├── calculate.py │ └── insert_code.py ├── treap.cpp ├── treap_array.cpp ├── treap_array_persistent.cpp ├── tree_to_line_save_max.cpp ├── variable_mint.cpp ├── y_combinator.cpp └── z_function.cpp /bitvec.cpp: -------------------------------------------------------------------------------- 1 | struct bitvec { 2 | using value_type = uint64_t; 3 | const static int word_len = __builtin_popcountll(~(value_type)0); 4 | 5 | vector data; 6 | value_type last_mask; 7 | int n; 8 | 9 | bitvec(int n = 1, value_type initial_value = 0) : n(n) { 10 | data.assign((n + word_len - 1) / word_len, 0); 11 | data[0] = initial_value; 12 | last_mask = (~(value_type)0) >> (data.size() * word_len - n); 13 | } 14 | 15 | int size() const { 16 | return n; 17 | } 18 | 19 | int count() const { 20 | int result = 0; 21 | for (value_type v : data) 22 | result += __builtin_popcountll(v); 23 | return result; 24 | } 25 | 26 | struct bit_reference { 27 | value_type *val; 28 | int bit; 29 | 30 | bit_reference(value_type &val, int bit) : val(&val), bit(bit) {} 31 | 32 | bit_reference &operator = (value_type v) { 33 | (*val) = ((*val) & ~((value_type)1 << bit)); 34 | (*val) ^= ((v & 1) << bit); 35 | return *this; 36 | } 37 | 38 | operator bool() const { 39 | return ((*val) >> bit) & 1; 40 | } 41 | }; 42 | 43 | bit_reference operator[](size_t ind) { 44 | return bit_reference(data[ind / word_len], ind % word_len); 45 | } 46 | 47 | bitvec &operator &= (const bitvec &other) { 48 | for (int i = 0; i < data.size(); ++i) 49 | data[i] &= other.data[i]; 50 | return *this; 51 | } 52 | bitvec operator & (const bitvec &other) const { 53 | bitvec res = *this; 54 | return res &= other; 55 | } 56 | 57 | bitvec &operator ^= (const bitvec &other) { 58 | for (int i = 0; i < data.size(); ++i) 59 | data[i] ^= other.data[i]; 60 | data.back() &= last_mask; 61 | return *this; 62 | } 63 | bitvec operator ^ (const bitvec &other) const { 64 | bitvec res = *this; 65 | return res ^= other; 66 | } 67 | 68 | bitvec &operator |= (const bitvec &other) { 69 | for (int i = 0; i < data.size(); ++i) 70 | data[i] |= other.data[i]; 71 | data.back() &= last_mask; 72 | return *this; 73 | } 74 | bitvec operator | (const bitvec &other) const { 75 | bitvec res = *this; 76 | return res |= other; 77 | } 78 | 79 | bitvec &operator >>= (int value) { 80 | if (value == 0) return *this; 81 | if (value < 0) return *this >>= (-value); 82 | 83 | int whole = value / word_len; 84 | if (whole) { 85 | for (int i = whole; i < data.size(); ++i) { 86 | data[i - whole] = data[i]; 87 | } 88 | for (int i = (int)data.size() - whole; i < data.size(); ++i) 89 | data[i] = 0; 90 | } 91 | 92 | int rem = value % word_len; 93 | if (rem) { 94 | for (int i = 0; i < data.size(); ++i) { 95 | if (i != 0) data[i - 1] |= (data[i] << (word_len - rem)); 96 | data[i] >>= rem; 97 | } 98 | } 99 | 100 | return *this; 101 | } 102 | bitvec operator >> (int value) const { 103 | auto res = *this; 104 | return res >>= value; 105 | } 106 | 107 | bitvec &operator <<= (int value) { 108 | if (value == 0) return *this; 109 | if (value < 0) return *this >>= (-value); 110 | 111 | int whole = value / word_len; 112 | if (whole) { 113 | for (int i = (int)data.size() - 1; i >= whole; --i) { 114 | data[i] = data[i - whole]; 115 | } 116 | for (int i = 0; i < whole; ++i) 117 | data[i] = 0; 118 | } 119 | 120 | int rem = value % word_len; 121 | if (rem) { 122 | for (int i = (int)data.size() - 1; i >= 0; --i) { 123 | if (i + 1 != data.size()) data[i + 1] |= (data[i] >> (word_len - rem)); 124 | data[i] <<= rem; 125 | } 126 | } 127 | 128 | data.back() &= last_mask; 129 | 130 | return *this; 131 | } 132 | bitvec operator << (int value) const { 133 | auto res = *this; 134 | return res <<= value; 135 | } 136 | }; 137 | -------------------------------------------------------------------------------- /calc_mertens.cpp: -------------------------------------------------------------------------------- 1 | // calculates mertens function M(n), where 2 | // M(n) = sum_{i=1..n} mobius(n), where 3 | // mobius(n) = 4 | // 1, if n has even number of primes 5 | // -1, if n has odd number of primes 6 | // 0, if n is divisible by a square 7 | ll calc_mertens(ll n) { 8 | ll y = n / (ll)pow(n, 0.33); 9 | 10 | vector mu(y + 1, -1); mu[0] = 0; mu[1] = 1; 11 | { 12 | vector isp(y + 1, true); isp[0] = isp[1] = false; 13 | vector mn(y + 1); 14 | for (int i = 2; i * i <= y; ++i) 15 | if (isp[i]) 16 | for (int j = i * i; j <= y; j += i) 17 | isp[j] = false, mn[j] = i; 18 | for (int i = 2; i <= y; ++i) 19 | if (!isp[i]) 20 | mu[i] = -mu[i / mn[i]]; 21 | for (int i = 2; i * i <= y; ++i) 22 | if (isp[i]) 23 | for (int j = i * i; j <= y; j += i * i) 24 | mu[j] = 0; 25 | } 26 | for (int i = 1; i < mu.size(); ++i) 27 | mu[i] += mu[i - 1]; 28 | 29 | vector v; 30 | v.reserve((int)sqrt(n) * 2 + 20); 31 | ll sq; 32 | { 33 | ll k = 1; 34 | for (; k * k <= n; ++k) { 35 | v.pb(k); 36 | } 37 | --k; 38 | sq = k; 39 | if (k * k == n) --k; 40 | for (; k >= 1; --k) { 41 | v.pb(n / k); 42 | } 43 | } 44 | vector s(v.size(), 0); 45 | auto geti = [&](ll x) { 46 | if (x <= sq) return (int)x - 1; 47 | else return (int)(v.size() - (n / x)); 48 | }; 49 | 50 | for (int i = 0; i < v.size(); ++i) { 51 | if (v[i] <= y) { 52 | s[i] = mu[v[i]]; 53 | continue; 54 | } 55 | ll sq = sqrt(v[i]); 56 | assert(sq * sq <= v[i] && (sq + 1) * (sq + 1) > v[i]); 57 | ll mid = v[i] / sq; 58 | s[i] = 1; 59 | for (ll j = 2; j <= mid; ++j) { 60 | s[i] -= s[geti(v[i] / j)]; 61 | } 62 | for (ll k = 1; k < v[i] / mid; ++k) { 63 | s[i] -= s[geti(k)] * (v[i] / k - v[i] / (k + 1)); 64 | } 65 | } 66 | return s.back(); 67 | } 68 | -------------------------------------------------------------------------------- /dominator_tree.cpp: -------------------------------------------------------------------------------- 1 | vector> dominator_tree(vector> g, int root) { 2 | int n = g.size(); 3 | vector p(n); 4 | for (int i = 0; i < n; ++i) { 5 | p[i] = i; 6 | } 7 | swap(p[root], p[0]); 8 | swap(g[0], g[root]); 9 | for (int i = 0; i < n; ++i) { 10 | for (int j = 0; j < g[i].size(); ++j) { 11 | g[i][j] = p[g[i][j]]; 12 | } 13 | } 14 | vector> tree(n); 15 | vector> bucket(n); 16 | vector sdom(n), dom(n), par(n), label(n), dsu(n); 17 | vector> gi(n); 18 | vector arr(n, -1), rev(n); 19 | int tm = 0; 20 | 21 | function ask = [&](int u, int x) { 22 | if (u == dsu[u]) return x ? -1 : u; 23 | int v = ask(dsu[u], x + 1); 24 | if (v < 0) return u; 25 | if (sdom[label[dsu[u]]] < sdom[label[u]]) 26 | label[u] = label[dsu[u]]; 27 | dsu[u] = v; 28 | return x ? v : label[u]; 29 | }; 30 | auto un = [&](int u, int v) { 31 | dsu[v] = u; 32 | }; 33 | 34 | function dfs = [&](int v) { 35 | arr[v] = tm; 36 | rev[tm] = v; 37 | label[tm] = sdom[tm] = dsu[tm] = tm; 38 | ++tm; 39 | for (int k : g[v]) { 40 | if (arr[k] == -1) { 41 | dfs(k); 42 | par[arr[k]] = arr[v]; 43 | } 44 | gi[arr[k]].pb(arr[v]); 45 | } 46 | }; 47 | dfs(0); 48 | assert(tm == n); // connected 49 | 50 | for (int i = n - 1; i >= 0; --i) { 51 | for (int j : gi[i]) { 52 | sdom[i] = min(sdom[i], sdom[ask(j, 0)]); 53 | } 54 | if (i != 0) bucket[sdom[i]].pb(i); 55 | for (int w : bucket[i]) { 56 | int v = ask(w, 0); 57 | if (sdom[v] == sdom[w]) dom[w] = sdom[w]; 58 | else dom[w] = v; 59 | } 60 | if (i != 0) un(par[i], i); 61 | } 62 | for (int i = 1; i < n; ++i) { 63 | if (dom[i] != sdom[i]) 64 | dom[i] = dom[dom[i]]; 65 | tree[rev[dom[i]]].pb(rev[i]); 66 | tree[rev[i]].pb(rev[dom[i]]); 67 | } 68 | 69 | swap(tree[root], tree[0]); 70 | for (int i = 0; i < tree.size(); ++i) { 71 | for (int j = 0; j < tree[i].size(); ++j) { 72 | tree[i][j] = p[tree[i][j]]; 73 | } 74 | } 75 | 76 | return tree; 77 | } 78 | -------------------------------------------------------------------------------- /dsu.cpp: -------------------------------------------------------------------------------- 1 | struct DSU { 2 | vector rk; 3 | vector p; 4 | int n; 5 | 6 | DSU(int n = 1) : n(n) { 7 | reset(n); 8 | } 9 | 10 | void reset(int n) { 11 | p.resize(n); 12 | iota(p.begin(), p.end(), 0); 13 | rk.assign(n, 1); 14 | } 15 | 16 | int par(int v) { 17 | return v == p[v] ? v : p[v] = par(p[v]); 18 | } 19 | 20 | bool un(int u, int v) { 21 | u = par(u); 22 | v = par(v); 23 | if (u == v) return false; 24 | if (rk[u] > rk[v]) swap(u, v); 25 | p[u] = v; 26 | rk[v] += rk[u]; 27 | return true; 28 | } 29 | 30 | bool check(int u, int v) { 31 | return par(u) == par(v); 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /edmonds_matching.cpp: -------------------------------------------------------------------------------- 1 | vector> edmonds(vector>& g) { 2 | int n = g.size(); 3 | vector match(n, -1); 4 | vector p(n); 5 | vector u(n); 6 | vector ulca(n); 7 | vector q(n + 5, -1); 8 | vector base(n); 9 | vector blossom(n); 10 | int ql = 0, qr = 0; 11 | 12 | auto lca = [&](int a, int b) { 13 | ulca.assign(n, false); 14 | while (true) { 15 | a = base[a]; 16 | ulca[a] = true; 17 | if (match[a] == -1) 18 | break; 19 | a = p[match[a]]; 20 | } 21 | while (true) { 22 | b = base[b]; 23 | if (ulca[b]) return b; 24 | b = p[match[b]]; 25 | } 26 | return -1; 27 | }; 28 | 29 | auto mark_path = [&](int v, int b, int k) { 30 | while (base[v] != b) { 31 | blossom[base[v]] = true; 32 | blossom[base[match[v]]] = true; 33 | p[v] = k; 34 | k = match[v]; 35 | v = p[match[v]]; 36 | } 37 | }; 38 | 39 | auto find_path = [&](int root) { 40 | p.assign(n, -1); 41 | u.assign(n, false); 42 | for (int i = 0; i < n; ++i) 43 | base[i] = i; 44 | ql = qr = 0; 45 | q[qr++] = root; 46 | u[root] = true; 47 | while (ql < qr) { 48 | int v = q[ql++]; 49 | for (auto k : g[v]) { 50 | if (base[v] == base[k] || match[v] == k) { 51 | continue; 52 | } else if (k == root || match[k] != -1 && p[match[k]] != -1) { 53 | blossom.assign(n, false); 54 | int b = lca(v, k); 55 | mark_path(v, b, k); 56 | mark_path(k, b, v); 57 | for (int i = 0; i < n; ++i) { 58 | if (blossom[base[i]]) { 59 | base[i] = b; 60 | if (!u[i]) { 61 | u[i] = true; 62 | q[qr++] = i; 63 | } 64 | } 65 | } 66 | } else if (p[k] == -1) { 67 | p[k] = v; 68 | if (match[k] == -1) 69 | return k; 70 | k = match[k]; 71 | u[k] = true; 72 | q[qr++] = k; 73 | } 74 | } 75 | } 76 | return -1; 77 | }; 78 | 79 | for (int i = 0; i < n; ++i) { 80 | if (match[i] == -1) { 81 | int v = find_path(i); 82 | while (v != -1) { 83 | match[v] = p[v]; 84 | int k = match[p[v]]; 85 | match[p[v]] = v; 86 | v = k; 87 | } 88 | } 89 | } 90 | vector> ans; 91 | for (int i = 0; i < n; ++i) 92 | if (match[i] > i) 93 | ans.eb(i, match[i]); 94 | return ans; 95 | } 96 | -------------------------------------------------------------------------------- /egcd.cpp: -------------------------------------------------------------------------------- 1 | // finds x and y such that a * x + b * y = c 2 | template 3 | pair egcd(T a, T b, T c) { 4 | if (a == 0) { 5 | // b * y = c 6 | assert(c % b == 0); 7 | return {0, c / b}; 8 | } 9 | // a * x + b * y = c 10 | // a * x + (b % a + (b/a) * a) * y = c 11 | // a * (x + (b/a) * y) + (b % a) * y = c 12 | auto [y0, x0] = egcd(b % a, a, c); 13 | T y = y0; 14 | T x = x0 - (b / a) * y; 15 | return {x, y}; 16 | } 17 | -------------------------------------------------------------------------------- /factorizer.cpp: -------------------------------------------------------------------------------- 1 | struct Factorizer { 2 | // Factorizer factorizer(prec_n, sp_bound, rng_seed); 3 | // prec_n is the bound for sieve (inclusive) 4 | // all numbers will first be checked on primes <= sp_bound (if prec_n >= sp_bound) 5 | // factorization for one number ~1e18 takes ~13ms 6 | 7 | vector min_prime; 8 | vector primes; 9 | int prec_n; 10 | int sp_bound; 11 | 12 | Factorizer(int prec_n = 100, int sp_bound = 100, int64_t rng_seed = -1) : 13 | prec_n(max(prec_n, 3)), 14 | sp_bound(sp_bound), 15 | rng(rng_seed != -1 ? rng_seed : chrono::steady_clock::now().time_since_epoch().count()) { 16 | min_prime.assign(prec_n + 1, -1); 17 | for (int i = 2; i <= prec_n; ++i) { 18 | if (min_prime[i] == -1) { 19 | min_prime[i] = i; 20 | primes.push_back(i); 21 | } 22 | int k = min_prime[i]; 23 | for (int j : primes) { 24 | if (j * i > prec_n) break; 25 | min_prime[i * j] = j; 26 | if (j == k) break; 27 | } 28 | } 29 | } 30 | 31 | bool is_prime(int64_t n, bool check_small = true) { 32 | if (n <= prec_n) 33 | return min_prime[n] == n; 34 | 35 | if (check_small) { 36 | for (int p : primes) { 37 | if (p > sp_bound || (int64_t)p * p > n) break; 38 | if (n % p == 0) return false; 39 | } 40 | } 41 | 42 | int s = 0; 43 | int64_t d = n - 1; 44 | while (d % 2 == 0) { 45 | ++s; 46 | d >>= 1; 47 | } 48 | for (int64_t a : {2, 325, 9375, 28178, 450775, 9780504, 1795265022}) { 49 | if (a >= n) break; 50 | int64_t x = mpow_long(a, d, n); 51 | if (x == 1 || x == n - 1) 52 | continue; 53 | bool composite = true; 54 | for (int i = 0; i < s - 1; ++i) { 55 | x = mul_mod(x, x, n); 56 | if (x == 1) 57 | return false; 58 | if (x == n - 1) { 59 | composite = false; 60 | break; 61 | } 62 | } 63 | if (composite) 64 | return false; 65 | } 66 | return true; 67 | } 68 | 69 | vector> factorize(int64_t n, bool check_small = true) { 70 | vector> res; 71 | if (check_small) { 72 | for (int p : primes) { 73 | if (p > sp_bound) break; 74 | if ((int64_t)p * p > n) break; 75 | if (n % p == 0) { 76 | res.emplace_back(p, 0); 77 | while (n % p == 0) { 78 | n /= p; 79 | res.back().second++; 80 | } 81 | } 82 | } 83 | } 84 | 85 | if (n == 1) return res; 86 | if (is_prime(n, false)) { 87 | res.emplace_back(n, 1); 88 | return res; 89 | } 90 | 91 | if (n <= prec_n) { 92 | while (n != 1) { 93 | int d = min_prime[n]; 94 | if (res.empty() || res.back().first != d) 95 | res.emplace_back(d, 0); 96 | res.back().second++; 97 | n /= d; 98 | } 99 | return res; 100 | } 101 | 102 | int64_t d = get_divisor(n); 103 | auto a = factorize(d, false); 104 | for (auto &[div, cnt] : a) { 105 | cnt = 0; 106 | while (n % div == 0) { 107 | n /= div; 108 | ++cnt; 109 | } 110 | } 111 | auto b = factorize(n, false); 112 | 113 | int ia = 0, ib = 0; 114 | while (ia < a.size() || ib < b.size()) { 115 | bool choosea; 116 | if (ia == a.size()) choosea = false; 117 | else if (ib == b.size()) choosea = true; 118 | else if (a[ia].first <= b[ib].first) choosea = true; 119 | else choosea = false; 120 | 121 | res.push_back(choosea ? a[ia++] : b[ib++]); 122 | } 123 | return res; 124 | } 125 | 126 | private: 127 | mt19937_64 rng; 128 | int64_t rnd(int64_t l, int64_t r) { 129 | return uniform_int_distribution(l, r)(rng); 130 | } 131 | 132 | int64_t mpow_long(int64_t a, int64_t p, int64_t mod) { 133 | int64_t res = 1; 134 | while (p) { 135 | if (p & 1) res = mul_mod(res, a, mod); 136 | p >>= 1; 137 | a = mul_mod(a, a, mod); 138 | } 139 | return res; 140 | } 141 | 142 | int64_t mul_mod(int64_t a, int64_t b, int64_t mod) { 143 | int64_t res = a * b - mod * (int64_t)((long double)1 / mod * a * b); 144 | if (res < 0) res += mod; 145 | if (res >= mod) res -= mod; 146 | return res; 147 | } 148 | 149 | int64_t get_divisor(int64_t n) { 150 | auto f = [&](int64_t x) -> int64_t { 151 | int64_t res = mul_mod(x, x, n) + 1; 152 | if (res == n) res = 0; 153 | return res; 154 | }; 155 | 156 | while (true) { 157 | int64_t x = rnd(1, n - 1); 158 | int64_t y = f(x); 159 | while (x != y) { 160 | int64_t d = gcd(n, abs(x - y)); 161 | if (d == 0) 162 | break; 163 | else if (d != 1) 164 | return d; 165 | x = f(x); 166 | y = f(f(y)); 167 | } 168 | } 169 | } 170 | }; 171 | -------------------------------------------------------------------------------- /fast_allocator.cpp: -------------------------------------------------------------------------------- 1 | const int MEMSIZE = 1e9; // in bytes 2 | char memory[MEMSIZE]; 3 | int memorypos; 4 | inline void * operator new(size_t n){ 5 | if (memorypos + n >= MEMSIZE) { 6 | memorypos = MEMSIZE / 3; 7 | } 8 | char * ret = memory + memorypos; 9 | memorypos += n; 10 | return (void *)ret; 11 | } 12 | inline void operator delete(void *){} 13 | inline void operator delete(void *, size_t){} -------------------------------------------------------------------------------- /fenwick.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct fenwick { 3 | vector tree; 4 | int n; 5 | int K; 6 | 7 | fenwick(int n = 0) : n(n) { 8 | tree.assign(n, 0); 9 | K = 0; 10 | while ((1 << K) <= n) 11 | ++K; 12 | } 13 | 14 | void add(int i, T k) { 15 | for (; i < n; i = (i | (i + 1))) 16 | tree[i] += k; 17 | } 18 | 19 | T ask(int r) { 20 | T res = 0; 21 | for (; r >= 0; r = (r & (r + 1)) - 1) 22 | res += tree[r]; 23 | return res; 24 | } 25 | 26 | T ask(int l, int r) { 27 | if (l > r) return 0; 28 | return ask(r) - ask(l - 1); 29 | } 30 | 31 | // find first i such that sum[0..i] >= x 32 | int lower_bound(T x) { 33 | int cur = 0; 34 | T cur_sum = 0; 35 | for (int k = K - 1; k >= 0; --k) { 36 | int ind = cur | ((1 << k) - 1); 37 | if (ind >= n) continue; 38 | if (cur_sum + tree[ind] >= x) continue; 39 | cur_sum += tree[ind]; 40 | cur |= (1 << k); 41 | } 42 | return cur; 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /fenwick2d.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct fenwick2d { 3 | vector> tree; 4 | int n, m; 5 | 6 | fenwick2d(int n = 0, int m = 0) : n(n), m(m) { 7 | tree.assign(n, vector(m, 0)); 8 | } 9 | 10 | void add(int ii1, int ii2, T k) { 11 | for (int i1 = ii1; i1 < n; i1 = (i1 | (i1 + 1))) 12 | for (int i2 = ii2; i2 < m; i2 = (i2 | (i2 + 1))) 13 | tree[i1][i2] += k; 14 | } 15 | 16 | T ask(int rr1, int rr2) { 17 | T res = 0; 18 | for (int r1 = rr1; r1 >= 0; r1 = (r1 & (r1 + 1)) - 1) 19 | for (int r2 = rr2; r2 >= 0; r2 = (r2 & (r2 + 1)) - 1) 20 | res += tree[r1][r2]; 21 | return res; 22 | } 23 | 24 | T ask(int l1, int r1, int l2, int r2) { 25 | if (l1 > r1 || l2 > r2) return 0; 26 | return ask(r1, r2) - ask(l1 - 1, r2) - ask(r1, l2 - 1) + ask(l1 - 1, l2 - 1); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /fft.cpp: -------------------------------------------------------------------------------- 1 | namespace fft { 2 | // TODO: square 3 | 4 | using dbl = double; // works for max value (max(a)*max(b)*n) up to 1e14 (multiply_mod with n up to 1e5) 5 | // using dbl = long double; // works for max value (max(a)*max(b)*n) up to 1e17 6 | const dbl PI = acosl(-1.0l); 7 | 8 | struct Complex { 9 | dbl x, y; 10 | Complex(dbl x = 0, dbl y = 0) : x(x), y(y) {} 11 | Complex conj() const { 12 | return Complex(x, -y); 13 | } 14 | }; 15 | 16 | Complex operator * (const Complex &a, const Complex &b) { return Complex(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x); } 17 | void operator /= ( Complex &a, int n) { a.x /= n; a.y /= n; } 18 | Complex operator / (const Complex &a, int n) { return Complex(a.x / n, a.y / n); } 19 | Complex operator + (const Complex &a, const Complex &b) { return Complex(a.x + b.x, a.y + b.y); } 20 | Complex operator - (const Complex &a, const Complex &b) { return Complex(a.x - b.x, a.y - b.y); } 21 | 22 | string to_string ( const Complex &x) { return (string)"(" + std::to_string(x.x) + ", " + std::to_string(x.y) + ")"; }; 23 | ostream& operator << (ostream &o, const Complex &x) { return o << to_string(x); } 24 | 25 | vector buf1; 26 | vector buf2; 27 | 28 | vector w = {1, 1}; 29 | vector reversed = {0}; 30 | 31 | void update_n(int n) { 32 | assert((n & (n - 1)) == 0); 33 | int cur = reversed.size(); 34 | if (n <= cur) return; 35 | reversed.resize(n); 36 | w.resize(n + 1); 37 | while (cur < n) { 38 | for (int i = 0; i < cur; ++i) 39 | reversed[i] <<= 1; 40 | for (int i = cur; i < (cur << 1); ++i) 41 | reversed[i] = reversed[i - cur] ^ 1; 42 | for (int i = (cur << 1) - 2; i > 0; i -= 2) 43 | w[i] = w[i / 2]; 44 | for (int i = 1; i < (cur << 1); i += 2) 45 | w[i] = Complex(cos(PI * i / cur), sin(PI * i / cur)); 46 | cur *= 2; 47 | } 48 | w.back() = 1; 49 | } 50 | 51 | void fft_internal(vector &v, int from, int n, bool inv) { 52 | update_n(n); 53 | int N = reversed.size(); 54 | 55 | int d = __lg(N) - __lg(n); 56 | 57 | for (int i = 1; i < n; ++i) 58 | if (i < (reversed[i] >> d)) 59 | swap(v[from + i], v[from + (reversed[i] >> d)]); 60 | 61 | for (int ln = 1; ln < n; ln <<= 1) { 62 | int step = (inv ? -N : N) / (ln * 2); 63 | for (int i = 0; i < n; i += (ln << 1)) { 64 | int ind = (inv ? N : 0); 65 | for (int j = 0; j < ln; ++j) { 66 | Complex y = v[from + i + j + ln] * w[ind]; 67 | ind += step; 68 | v[from + i + j + ln] = v[from + i + j] - y; 69 | v[from + i + j] = v[from + i + j] + y; 70 | } 71 | } 72 | } 73 | 74 | if (inv) 75 | for (int i = 0; i < n; ++i) 76 | v[from + i] /= n; 77 | } 78 | 79 | vector fft(const vector &v, int n = -1) { 80 | if (n == -1) { 81 | n = 1; 82 | while (n < v.size()) n <<= 1; 83 | } 84 | assert(v.size() <= n); 85 | buf1.assign(n, {0, 0}); 86 | for (int i = 0; i < v.size(); ++i) 87 | buf1[i].x = v[i]; 88 | fft_internal(buf1, 0, n, false); 89 | return vector(buf1.begin(), buf1.end()); 90 | } 91 | 92 | vector fft(const vector &v) { 93 | assert(!v.empty() && (v.size() & (v.size() - 1)) == 0); 94 | buf1.resize(v.size()); 95 | for (int i = 0; i < v.size(); ++i) 96 | buf1[i] = v[i]; 97 | fft_internal(buf1, 0, buf1.size(), true); 98 | vector result(v.size()); 99 | for (int i = 0; i < result.size(); ++i) 100 | result[i] = llround(buf1[i].x); 101 | return result; 102 | } 103 | 104 | vector multiply(const vector &a, const vector &b) { 105 | if (a.empty() || b.empty()) return {}; 106 | int n = 2; 107 | while (n < a.size() + b.size() - 1) n <<= 1; 108 | 109 | buf1.assign(n, {0, 0}); 110 | 111 | for (int i = 0; i < a.size(); ++i) 112 | buf1[i].x = a[i]; 113 | for (int i = 0; i < b.size(); ++i) 114 | buf1[i].y = b[i]; 115 | 116 | fft_internal(buf1, 0, n, false); 117 | 118 | for (int i = 0; i <= (n >> 1); ++i) { 119 | // a --fft--> a1 + a2*i 120 | // b --fft--> b1 + b2*i 121 | // fact: FFT(a)[k] = FFT(a)[n - k].conj() 122 | // using this we can get formulas for FFT(a) and FFT(b) from FFT(a+bi) 123 | 124 | int j = (n - i) & (n - 1); 125 | 126 | auto v = (buf1[i] + buf1[j].conj()) * (buf1[i] - buf1[j].conj()) / 4; 127 | swap(v.x, v.y); 128 | 129 | buf1[i] = v.conj(); 130 | buf1[j] = v; 131 | } 132 | 133 | fft_internal(buf1, 0, n, true); 134 | 135 | vector result(a.size() + b.size() - 1); 136 | for (int i = 0; i < result.size(); ++i) 137 | result[i] = llround(buf1[i].x); 138 | return result; 139 | } 140 | 141 | vector multiply_mod(const vector &a, const vector &b, int mod) { 142 | if (a.empty() || b.empty()) return {}; 143 | int n = 2; 144 | while (n < a.size() + b.size() - 1) n <<= 1; 145 | 146 | buf1.assign(n * 2, {0, 0}); 147 | for (int i = 0; i < a.size(); ++i) { 148 | buf1[i].x = a[i] & ((1 << 15) - 1); 149 | buf1[i].y = a[i] >> 15; 150 | } 151 | buf2.assign(n * 2, {0, 0}); 152 | for (int i = 0; i < b.size(); ++i) { 153 | buf2[i].x = b[i] & ((1 << 15) - 1); 154 | buf2[i].y = b[i] >> 15; 155 | } 156 | 157 | fft_internal(buf1, 0, n, false); 158 | fft_internal(buf2, 0, n, false); 159 | 160 | for (int i = 0; i <= (n >> 1); ++i) { 161 | int j = (n - i) & (n - 1); 162 | 163 | Complex as = (buf1[i] + buf1[j].conj()) / 2; 164 | Complex bs = (buf2[i] + buf2[j].conj()) / 2; 165 | Complex al = (buf1[i] - buf1[j].conj()) / 2; 166 | Complex bl = (buf2[i] - buf2[j].conj()) / 2; 167 | 168 | Complex asbs = as * bs; 169 | Complex albs = al * bs; 170 | Complex asbl = as * bl; swap(asbl.x, asbl.y); 171 | Complex albl = al * bl; swap(albl.x, albl.y); 172 | 173 | buf1[i] = asbs + albl.conj(); 174 | buf1[j] = asbs.conj() - albl; 175 | 176 | buf2[i] = asbl.conj() + albs; 177 | buf2[j] = asbl - albs.conj(); 178 | } 179 | 180 | fft_internal(buf1, 0, n, true); 181 | fft_internal(buf2, 0, n, true); 182 | 183 | vector result(a.size() + b.size() - 1); 184 | for (int i = 0; i < result.size(); ++i) { 185 | long long asbs = llround(buf1[i].x); 186 | long long albl = llround(buf1[i].y); 187 | long long asbl = llround(buf2[i].x); 188 | long long albs = llround(buf2[i].y); 189 | result[i] = (((albl % mod) << 30) + (((asbl + albs) % mod) << 15) + asbs) % mod; 190 | } 191 | return result; 192 | } 193 | 194 | } // fft 195 | -------------------------------------------------------------------------------- /first_in_range.cpp: -------------------------------------------------------------------------------- 1 | // returns minimal x such that a*x+b \in [l; r] % mod 2 | // l and r don't have to be in [0, mod) (see first couple of lines for understanding) 3 | // O(log(mod)) 4 | ll first_in_range(ll a, ll b, ll l, ll r, ll mod, ll no_solution_return = 4e18) { 5 | r -= b; l -= b; 6 | ll dif = r - l; 7 | if (dif >= mod) return 0; 8 | if (dif < 0) return no_solution_return; 9 | l = (l % mod + mod) % mod; 10 | r = (r % mod + mod) % mod; 11 | 12 | ll g = gcd(a, mod); 13 | const ll inf = 4e18; 14 | 15 | auto get_inv = [&](ll a, ll mod) -> ll { 16 | ll b = mod, x = 0, y = 1; 17 | while (a != 0) { 18 | ll k = b / a; 19 | b -= k * a; x -= k * y; 20 | swap(a, b); swap(x, y); 21 | } 22 | x %= mod; 23 | if (x < 0) x += mod; 24 | return x; 25 | }; 26 | 27 | auto solve_internal = [&](ll mod, ll l, ll r, ll a) -> ll { 28 | if (a == 0) return (l == 0 ? 0 : inf); 29 | a /= g; 30 | mod /= g; 31 | r /= g; 32 | l = (l + g - 1) / g; 33 | if (l > r) return inf; 34 | if (mod == 1) return 0; 35 | 36 | a = get_inv(a, mod); 37 | ll b = l * a % mod; 38 | ll k = r - l; 39 | 40 | ll b0 = b; 41 | ll mod0 = mod; 42 | ll ainv = get_inv(a, mod); 43 | 44 | auto get_steps = [&](ll t, ll ia, ll b, ll m) -> ll { 45 | return (t - b + m) % m * ia % m; 46 | }; 47 | 48 | while (true) { 49 | if (a == 0) return b; 50 | if (a < mod - a) { 51 | ll b1 = (b < a ? b : ((b - mod) % a + a) % a); 52 | 53 | if (get_steps(b1, ainv, b0, mod0) > k) return b; 54 | 55 | ll a1 = ((-mod) % a + a) % a; 56 | ll m1 = a; 57 | 58 | a = a1; 59 | b = b1; 60 | mod = m1; 61 | } else { 62 | ll a1 = a % (mod - a); 63 | ll b1 = b % (mod - a); 64 | ll m1 = mod - a; 65 | 66 | ll steps = get_steps(b1, ainv, b0, mod0); 67 | if (steps > k) { 68 | ll div = steps - get_steps(b1 + m1, ainv, b0, mod0); 69 | return b1 + m1 * ((steps - k + div - 1) / div); 70 | } 71 | 72 | a = a1; 73 | b = b1; 74 | mod = m1; 75 | } 76 | } 77 | }; 78 | 79 | ll res; 80 | if (l <= r) { 81 | res = solve_internal(mod, l, r, a); 82 | } else { 83 | res = min(solve_internal(mod, 0, r, a), solve_internal(mod, l, mod - 1, a)); 84 | } 85 | if (res == inf) res = no_solution_return; 86 | return res; 87 | } 88 | -------------------------------------------------------------------------------- /fwht.cpp: -------------------------------------------------------------------------------- 1 | // usage: auto c = fwht::fwht(a, b, fwht::AND); 2 | // just transformation: fwht::fwht(a, inv, fwht::AND); 3 | namespace fwht { 4 | 5 | enum Type { 6 | XOR, 7 | NXOR, 8 | AND, 9 | OR, 10 | }; 11 | 12 | template 13 | void fwht(vector &v, bool inv = false, Type tp = XOR) { 14 | assert((v.size() & (v.size() - 1)) == 0); 15 | for (int step = 1; step < v.size(); step <<= 1) { 16 | for (int i = 0; i < v.size(); i += step * 2) { 17 | for (int j = 0; j < step; ++j) { 18 | T a = v[i + j], b = v[i + j + step]; 19 | if (tp == Type::XOR) { 20 | v[i + j] = a + b; 21 | v[i + j + step] = a - b; 22 | } else if (tp == Type::NXOR) { 23 | v[i + j] = -a + b; 24 | v[i + j + step] = a + b; 25 | } else if (tp == Type::AND) { 26 | v[i + j] = (inv ? b - a : b); 27 | v[i + j + step] = (inv ? a : a + b); 28 | } else if (tp == Type::OR) { 29 | v[i + j] = (inv ? b : a + b); 30 | v[i + j + step] = (inv ? a - b : a); 31 | } 32 | } 33 | } 34 | } 35 | if (inv && (tp == Type::XOR || tp == Type::NXOR)) { 36 | T val = 1; 37 | for (int j = 1; j < v.size(); j <<= 1) 38 | val *= 2; 39 | for (int i = 0; i < v.size(); ++i) { 40 | v[i] /= val; 41 | } 42 | } 43 | } 44 | 45 | template 46 | vector fwht(vector a, vector b, Type tp = XOR) { 47 | fwht(a, false, tp); 48 | fwht(b, false, tp); 49 | for (int i = 0; i < a.size(); ++i) 50 | a[i] *= b[i]; 51 | fwht(a, true, tp); 52 | return a; 53 | } 54 | 55 | }; 56 | -------------------------------------------------------------------------------- /grid_iterator.cpp: -------------------------------------------------------------------------------- 1 | namespace grid_iterator_ns { 2 | const array, 8> dirs = {{{0, 1}, {1, 0}, {0, -1}, {-1, 0}, {1, 1}, {-1, -1}, {1, -1}, {-1, 1}}}; 3 | struct GridIterator { 4 | int n, m; 5 | GridIterator(int n, int m) : n(n), m(m) {} 6 | 7 | template 8 | struct NeighbourIteratorContainer { 9 | int i, j, n, m; 10 | NeighbourIteratorContainer(int i, int j, int n, int m) : i(i), j(j), n(n), m(m) {} 11 | 12 | struct NeighbourIterator { 13 | int cur; 14 | int i, j, n, m; 15 | NeighbourIterator(int cur, int i, int j, int n, int m) : cur(cur), i(i), j(j), n(n), m(m) { 16 | skip_to_first_allowed(); 17 | } 18 | 19 | void skip_to_first_allowed() { 20 | while (cur < N && 21 | (i + dirs[cur].first < 0 || i + dirs[cur].first >= n || 22 | j + dirs[cur].second < 0 || j + dirs[cur].second >= m)) { 23 | ++cur; 24 | } 25 | } 26 | 27 | NeighbourIterator& operator ++ () { 28 | ++cur; 29 | skip_to_first_allowed(); 30 | return *this; 31 | } 32 | 33 | pair operator * () const { return {i + dirs[cur].first, j + dirs[cur].second}; } 34 | 35 | bool operator == (const NeighbourIterator& other) const { return cur == other.cur; } 36 | }; 37 | 38 | auto begin() const { return NeighbourIterator(0, i, j, n, m); } 39 | auto end() const { return NeighbourIterator(N, i, j, n, m); } 40 | 41 | auto collect() const { 42 | vector> result; 43 | for (auto it = begin(); it != end(); ++it) result.push_back(*it); 44 | return result; 45 | } 46 | }; 47 | 48 | template 49 | auto iterate(int i, int j) const { 50 | static_assert(N == 4 || N == 8, "you can remove this, but make sure you understand what you are doing"); 51 | return NeighbourIteratorContainer(i, j, n, m); 52 | } 53 | }; 54 | } 55 | using grid_iterator_ns::GridIterator; 56 | -------------------------------------------------------------------------------- /hash_table.cpp: -------------------------------------------------------------------------------- 1 | struct hash_my { 2 | size_t operator()(int x) const { 3 | x = ((x >> 16) ^ x) * 0x119de1f3; 4 | x = ((x >> 16) ^ x) * 0x119de1f3; 5 | x = (x >> 16) ^ x; 6 | return x; 7 | } 8 | 9 | size_t operator()(long long x) const { 10 | x = (x ^ (x >> 30)) * (0xbf58476d1ce4e5b9ll); 11 | x = (x ^ (x >> 27)) * (0x94d049bb133111ebll); 12 | x = x ^ (x >> 31); 13 | return x; 14 | } 15 | 16 | template 17 | size_t operator()(const pair &p) const { 18 | long long h1 = (*this)(p.first); 19 | long long h2 = (*this)(p.second); 20 | return (*this)(h1 ^ (h2 << 32) ^ (h2 >> 32)); 21 | } 22 | }; 23 | 24 | template 25 | struct static_hash_table { 26 | static_assert(__builtin_popcount(N) == 1, "N must be a power of 2"); 27 | array, N> data; 28 | array state; 29 | Hash hasher; 30 | 31 | const static char STATE_EMPTY = 0; 32 | const static char STATE_FILLED = 1; 33 | const static char STATE_REMOVED = 2; 34 | 35 | static_hash_table() { 36 | state.fill(STATE_EMPTY); 37 | } 38 | 39 | int find_ind(const Key &k) const { 40 | int ind = hasher(k) & (N - 1); 41 | while (state[ind] != STATE_EMPTY) { 42 | if (state[ind] == STATE_FILLED && data[ind].first == k) return ind; 43 | ind = (ind + 1) & (N - 1); 44 | } 45 | return -1; 46 | } 47 | 48 | void emplace(const Key &k, const Value &v) { 49 | (*this)[k] = v; 50 | } 51 | 52 | Value &operator[](const Key &k) { 53 | int ind = hasher(k) & (N - 1); 54 | int rem = -1; 55 | while (state[ind] != STATE_EMPTY) { 56 | if (state[ind] == STATE_FILLED && data[ind].first == k) { 57 | return data[ind].second; 58 | } 59 | if (rem == -1 && state[ind] == STATE_REMOVED) rem = ind; 60 | ind = (ind + 1) & (N - 1); 61 | } 62 | if (rem != -1) ind = rem; 63 | data[ind].first = k; 64 | data[ind].second = Value(); 65 | state[ind] = STATE_FILLED; 66 | return data[ind].second; 67 | } 68 | 69 | void erase(const Key &k) { 70 | int ind = find_ind(k); 71 | if (ind != -1) { 72 | state[ind] = STATE_REMOVED; 73 | } 74 | } 75 | 76 | int count(const Key &k) const { 77 | return find_ind(k) != -1; 78 | } 79 | }; 80 | -------------------------------------------------------------------------------- /lca_sparse.cpp: -------------------------------------------------------------------------------- 1 | vector lca_ind; 2 | vector> lca_sparse; 3 | vector lca_p2; 4 | vector lca_depth; 5 | void build_lca_sparse(vector>& g, int root = 0) { 6 | int n = g.size(); 7 | vector euler; 8 | lca_ind.resize(n); 9 | lca_depth.assign(n, -1); 10 | function dfs = [&](int v, int depth) { 11 | lca_ind[v] = euler.size(); 12 | euler.pb(v); 13 | lca_depth[v] = depth; 14 | for (auto k : g[v]) { 15 | if (lca_depth[k] == -1) { 16 | dfs(k, depth + 1); 17 | euler.pb(v); 18 | } 19 | } 20 | }; 21 | dfs(root, 0); 22 | int m = euler.size(); 23 | int log = 1; 24 | while ((1 << log) < m) 25 | ++log; 26 | lca_sparse.resize(log); 27 | lca_sparse[0].resize(m); 28 | lca_p2.resize(m + 1); 29 | int pp2 = 0; 30 | for (int i = 1; i < lca_p2.size(); ++i) { 31 | if (1 << (pp2 + 1) <= i) 32 | ++pp2; 33 | lca_p2[i] = pp2; 34 | } 35 | lca_p2[0] = 0; 36 | for (int i = 0; i < m; ++i) 37 | lca_sparse[0][i] = euler[i]; 38 | for (int i = 1; i < log; ++i) { 39 | lca_sparse[i].assign(m, 0); 40 | for (int j = 0; j < m - (1 << (i - 1)); ++j) { 41 | int v1 = lca_sparse[i - 1][j], v2 = lca_sparse[i - 1][j + (1 << (i - 1))]; 42 | if (lca_depth[v1] < lca_depth[v2]) 43 | lca_sparse[i][j] = v1; 44 | else 45 | lca_sparse[i][j] = v2; 46 | } 47 | } 48 | } 49 | 50 | int get_lca(int u, int v) { 51 | if (u == v) 52 | return u; 53 | u = lca_ind[u]; 54 | v = lca_ind[v]; 55 | if (u > v) 56 | swap(u, v); 57 | int v1 = lca_sparse[lca_p2[v - u + 1]][u], v2 = lca_sparse[lca_p2[v - u + 1]][v - (1 << lca_p2[v - u + 1]) + 1]; 58 | if (lca_depth[v1] < lca_depth[v2]) 59 | return v1; 60 | else 61 | return v2; 62 | } 63 | 64 | int dist(int u, int v) { 65 | return lca_depth[u] + lca_depth[v] - 2 * lca_depth[get_lca(u, v)]; 66 | } 67 | -------------------------------------------------------------------------------- /lichao.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct LiChao { 3 | static const T INF = std::numeric_limits::max() / 2 - 5; 4 | int n; 5 | vector> tree; 6 | 7 | LiChao(int _n) : n(max(_n, 1)) { 8 | int nn = (1 << __lg(n)) * 4; 9 | tree.assign(nn, {0, -INF}); 10 | } 11 | 12 | void add(T k, T b) { 13 | add_inner({k, b}, 0, 0, n - 1); 14 | } 15 | 16 | void add_inner(pair line, int i, int l, int r) { 17 | while (l <= r) { 18 | T curl = tree[i].first * l + tree[i].second; 19 | T curr = tree[i].first * r + tree[i].second; 20 | T mel = line.first * l + line.second; 21 | T mer = line.first * r + line.second; 22 | if (curl >= mel && curr >= mer) { 23 | break; 24 | } 25 | if (curl <= mel && curr <= mer) { 26 | tree[i] = line; 27 | break; 28 | } 29 | assert(line.first != tree[i].first); 30 | int m = (l + r) / 2; 31 | T cur = tree[i].first * m + tree[i].second; 32 | T me = line.first * m + line.second; 33 | if (me > cur) { 34 | swap(line, tree[i]); 35 | } 36 | if ((me <= cur && mer > curr) || (me > cur && mer < curr)) { 37 | l = m + 1; 38 | i = i * 2 + 2; 39 | } else { 40 | r = m; 41 | i = i * 2 + 1; 42 | } 43 | } 44 | } 45 | 46 | void add_segment(T k, T b, int l, int r) { 47 | l = max(l, 0); 48 | r = min(r, n - 1); 49 | add_segment_inner({k, b}, l, r, 0, 0, n - 1); 50 | } 51 | 52 | void add_segment_inner(pair line, int l, int r, int i, int vl, int vr) { 53 | if (l > vr || r < vl) { 54 | return; 55 | } 56 | if (l <= vl && vr <= r) { 57 | add_inner(line, i, vl, vr); 58 | return; 59 | } 60 | int m = (vl + vr) / 2; 61 | add_segment_inner(line, l, r, i * 2 + 1, vl, m); 62 | add_segment_inner(line, l, r, i * 2 + 2, m + 1, vr); 63 | } 64 | 65 | T ask(int x) { 66 | T ans = -INF; 67 | int i = 0; 68 | int l = 0; 69 | int r = n - 1; 70 | while (true) { 71 | int m = (l + r) / 2; 72 | ans = max(ans, tree[i].first * x + tree[i].second); 73 | if (l == r) break; 74 | if (x <= m) { 75 | r = m; 76 | i = i * 2 + 1; 77 | } else { 78 | l = m + 1; 79 | i = i * 2 + 2; 80 | } 81 | } 82 | return ans; 83 | } 84 | }; 85 | -------------------------------------------------------------------------------- /line.cpp: -------------------------------------------------------------------------------- 1 | struct line { 2 | long double a, b, c; 3 | line() {} 4 | line(long double a, long double b, long double c): a(a), b(b), c(c) {} 5 | line(point m, point n) { 6 | a = n.y - m.y; 7 | b = m.x - n.x; 8 | c = -a * m.x - b * m.y; 9 | } 10 | point intersect(line l) { 11 | return point((b * l.c - c * l.b) / (a * l.b - b * l.a), (a * l.c - c * l.a) / (b * l.a - a * l.b)); 12 | } 13 | long double dist(point p) { 14 | return abs(a * p.x + b * p.y + c) / sqrt(a * a + b * b); 15 | } 16 | }; 17 | 18 | string to_string(line& l) { 19 | string ans = ""; 20 | if (l.a != 0) { 21 | ans += to_string(l.a) + "x "; 22 | if (l.b != 0) { 23 | if (l.b > 0) ans += "+"; 24 | else ans += "-"; 25 | ans += " " + to_string(abs(l.b)) + "y "; 26 | } 27 | } 28 | else ans += to_string(l.b) + "y "; 29 | if (l.c != 0) { 30 | if (l.c > 0) ans += "+"; 31 | else ans += "-"; 32 | ans += " " + to_string(abs(l.c)) + " "; 33 | } 34 | ans += "= 0"; 35 | return ans; 36 | } 37 | ostream& operator << (ostream &o, const line &l) { 38 | return o << to_string(l); 39 | } 40 | -------------------------------------------------------------------------------- /matching_dinic.cpp: -------------------------------------------------------------------------------- 1 | auto find_matching_dinic(vector>& g_main, vector& a) { 2 | int n = g_main.size(); 3 | vector> g(n + 2); 4 | vector e; 5 | vector can; 6 | vector in_a(n, false); 7 | auto add = [&](int i, int j) { 8 | g[i].push_back(e.size()); 9 | e.push_back(j); 10 | can.push_back(true); 11 | g[j].push_back(e.size()); 12 | e.push_back(i); 13 | can.push_back(false); 14 | }; 15 | for (auto u : a) { 16 | in_a[u] = true; 17 | for (auto v : g_main[u]) 18 | add(u, v); 19 | } 20 | int s = n, t = n + 1; 21 | for (int u = 0; u < n; ++u) { 22 | if (in_a[u]) 23 | add(s, u); 24 | else 25 | add(u, t); 26 | } 27 | n += 2; 28 | int flow = 0; 29 | vector layer(n, -5); 30 | vector q(n + 10); 31 | int ql, qr; 32 | vector ptr(n, 0); 33 | vector to(n); 34 | for (int i = 0; i < n; ++i) { 35 | layer.assign(n, -5); 36 | ptr.assign(n, 0); 37 | ql = 0; 38 | qr = 1; 39 | q[0] = s; 40 | layer[s] = 0; 41 | while (ql < qr) { 42 | int v = q[ql++]; 43 | for (auto k : g[v]) { 44 | if (can[k] && layer[e[k]] == -5) { 45 | layer[e[k]] = layer[v] + 1; 46 | q[qr++] = e[k]; 47 | } 48 | } 49 | } 50 | if (layer[t] == -5) 51 | break; 52 | int prev_flow = flow; 53 | while (true) { 54 | function go = [&](int v) -> bool { 55 | if (v == t) 56 | return true; 57 | while (ptr[v] < g[v].size()) { 58 | if (layer[v] + 1 == layer[e[g[v][ptr[v]]]] && can[g[v][ptr[v]]]) { 59 | int x = go(e[g[v][ptr[v]]]); 60 | if (x) { 61 | can[g[v][ptr[v]]] = false; 62 | can[g[v][ptr[v]]^1] = true; 63 | return true; 64 | } else { 65 | ++ptr[v]; 66 | } 67 | } else { 68 | ++ptr[v]; 69 | } 70 | } 71 | return false; 72 | }; 73 | if (!go(s)) 74 | break; 75 | ++flow; 76 | } 77 | if (flow == prev_flow) 78 | break; 79 | } 80 | // return flow; // if need only size 81 | vector> res; 82 | for (auto i : a) { 83 | for (auto k : g[i]) { 84 | if (e[k] != s && !can[k]) 85 | res.emplace_back(i, e[k]); 86 | } 87 | } 88 | return res; 89 | } 90 | -------------------------------------------------------------------------------- /matching_kuhn.cpp: -------------------------------------------------------------------------------- 1 | bool matching_dfs(int v, vector>& g, vector& from, vector& u) { 2 | u[v] = true; 3 | for (auto k : g[v]) { 4 | if (from[k] == -1 || (!u[from[k]] && matching_dfs(from[k], g, from, u))) { 5 | from[k] = v; 6 | return true; 7 | } 8 | } 9 | return false; 10 | } 11 | 12 | vector> find_matching(vector>& g, vector a) { 13 | bool rev = false; 14 | if (2 * a.size() > g.size()) { 15 | rev = true; 16 | vector has(g.size(), false); 17 | for (auto v : a) 18 | has[v] = true; 19 | a.clear(); 20 | a.reserve(g.size() - a.size()); 21 | for (int i = 0; i < g.size(); ++i) 22 | if (!has[i]) 23 | a.push_back(i); 24 | } 25 | vector u(g.size(), false); 26 | vector from(g.size(), -1); 27 | for (auto v : a) 28 | if (matching_dfs(v, g, from, u)) 29 | u.assign(g.size(), false); 30 | vector> result; 31 | for (int v = 0; v < from.size(); ++v) { 32 | if (from[v] != -1) { 33 | if (rev) result.emplace_back(v, from[v]); 34 | else result.emplace_back(from[v], v); 35 | } 36 | } 37 | return result; 38 | } 39 | 40 | void dominating_set_dfs(int v, vector>& g, vector& with, vector& u, 41 | vector& take) { 42 | u[v] = true; 43 | for (auto k : g[v]) { 44 | take[k] = true; 45 | if (!u[with[k]]) 46 | dominating_set_dfs(with[k], g, with, u, take); 47 | } 48 | } 49 | 50 | vector find_dominating_set(vector>& g, vector& a) { 51 | auto matching = find_matching(g, a); 52 | vector with(g.size(), -1); 53 | for (auto edge : matching) { 54 | with[edge.first] = edge.second; 55 | with[edge.second] = edge.first; 56 | } 57 | vector u(g.size(), false); 58 | vector take(g.size(), false); 59 | for (auto v : a) 60 | if (with[v] == -1) 61 | dominating_set_dfs(v, g, with, u, take); 62 | for (auto e : matching) 63 | if (!take[e.second]) 64 | take[e.first] = true; 65 | vector result(matching.size()); 66 | for (int i = 0; i < matching.size(); ++i) { 67 | if (take[matching[i].second]) result[i] = matching[i].second; 68 | else result[i] = matching[i].first; 69 | } 70 | return result; 71 | } 72 | 73 | vector find_independent_set(vector>& g, vector& a) { 74 | vector result; 75 | vector u(g.size(), false); 76 | for (auto v : find_dominating_set(g, a)) 77 | u[v] = true; 78 | for (int i = 0; i < g.size(); ++i) 79 | if (!u[i]) 80 | result.push_back(i); 81 | return result; 82 | } 83 | -------------------------------------------------------------------------------- /matrix.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct Matrix { 3 | array, N> m; 4 | 5 | Matrix() { 6 | for (int i = 0; i < N; ++i) { 7 | for (int j = 0; j < N; ++j) { 8 | m[i][j] = 0; 9 | } 10 | } 11 | } 12 | Matrix(std::initializer_list> s) { 13 | int i = 0; 14 | for (auto it = s.begin(); it != s.end(); ++it) { 15 | int j = 0; 16 | for (auto it2 = it->begin(); it2 != it->end(); ++it2) { 17 | m[i][j] = *it2; 18 | ++j; 19 | } 20 | ++i; 21 | } 22 | } 23 | 24 | static Matrix E() { 25 | Matrix e; 26 | for (int i = 0; i < N; ++i) { 27 | e[i][i] = 1; 28 | } 29 | return e; 30 | } 31 | 32 | array &operator[](int i) { 33 | return m[i]; 34 | } 35 | 36 | const array &operator[](int i) const { 37 | return m[i]; 38 | } 39 | 40 | Matrix operator * (const Matrix &b) const { 41 | Matrix c; 42 | for (int i = 0; i < N; ++i) { 43 | for (int j = 0; j < N; ++j) { 44 | for (int k = 0; k < N; ++k) { 45 | c[i][k] += m[i][j] * b[j][k]; 46 | } 47 | } 48 | } 49 | return c; 50 | } 51 | 52 | Matrix &operator *= (const Matrix &other) { 53 | *this = (*this) * other; 54 | return *this; 55 | } 56 | 57 | Matrix &operator *= (const T &x) { 58 | for (int i = 0; i < N; ++i) { 59 | for (int j = 0; j < N; ++j) { 60 | m[i][j] *= x; 61 | } 62 | } 63 | return *this; 64 | } 65 | Matrix operator * (const T &x) const { 66 | Matrix a = *this; 67 | a *= x; 68 | return a; 69 | } 70 | 71 | Matrix &operator /= (const T &x) { 72 | T inv = T(1) / x; 73 | for (int i = 0; i < N; ++i) { 74 | for (int j = 0; j < N; ++j) { 75 | m[i][j] *= inv; 76 | } 77 | } 78 | return *this; 79 | } 80 | Matrix operator / (const T &x) const { 81 | Matrix a = *this; 82 | a /= x; 83 | return a; 84 | } 85 | 86 | Matrix &operator += (const Matrix &other) { 87 | for (int i = 0; i < N; ++i) { 88 | for (int j = 0; j < N; ++j) { 89 | m[i][j] += other[i][j]; 90 | } 91 | } 92 | return *this; 93 | } 94 | Matrix operator + (const Matrix &other) const { 95 | Matrix a = *this; 96 | a += other; 97 | return a; 98 | } 99 | 100 | Matrix &operator -= (const Matrix &other) { 101 | for (int i = 0; i < N; ++i) { 102 | for (int j = 0; j < N; ++j) { 103 | m[i][j] -= other[i][j]; 104 | } 105 | } 106 | return *this; 107 | } 108 | Matrix operator - (const Matrix &other) const { 109 | Matrix a = *this; 110 | a -= other; 111 | return a; 112 | } 113 | }; 114 | 115 | template 116 | Matrix pow(Matrix m, ll p) { 117 | Matrix res = Matrix::E(); 118 | while (p) { 119 | if (p & 1) res *= m; 120 | m *= m; 121 | p >>= 1; 122 | } 123 | return res; 124 | } 125 | -------------------------------------------------------------------------------- /max_flow_dinic.cpp: -------------------------------------------------------------------------------- 1 | struct dinic_edge { 2 | int from, to; 3 | long long mx; 4 | }; 5 | 6 | long long max_flow_dinic(vector>> g_main, int s, int t) { 7 | int n = g_main.size(); 8 | vector> g(n); 9 | vector e; 10 | for (int u = 0; u < n; ++u) { 11 | for (auto pr : g_main[u]) { 12 | int v = pr.first; 13 | long long w = pr.second; 14 | g[u].push_back(e.size()); 15 | e.push_back({u, v, w}); 16 | g[v].push_back(e.size()); 17 | e.push_back({v, u, 0}); 18 | } 19 | } 20 | long long flow = 0; 21 | vector layer(n, -5); 22 | vector q(n + 10); 23 | int ql, qr; 24 | vector ptr(n, 0); 25 | for (int i = 0; i < n; ++i) { 26 | layer.assign(n, -5); 27 | ptr.assign(n, 0); 28 | ql = 0; 29 | qr = 1; 30 | q[0] = s; 31 | layer[s] = 0; 32 | while (ql < qr) { 33 | int v = q[ql++]; 34 | for (auto k : g[v]) { 35 | if (e[k].mx > 0 && layer[e[k].to] == -5) { 36 | layer[e[k].to] = layer[v] + 1; 37 | q[qr++] = e[k].to; 38 | } 39 | } 40 | } 41 | if (layer[t] == -5) 42 | break; 43 | long long prev_flow = flow; 44 | while (true) { 45 | function go = [&](int v, long long now) -> long long { 46 | if (v == t) 47 | return now; 48 | while (ptr[v] < g[v].size()) { 49 | if (layer[v] + 1 == layer[e[g[v][ptr[v]]].to] && e[g[v][ptr[v]]].mx > 0) { 50 | long long next = min(now, e[g[v][ptr[v]]].mx); 51 | long long x = go(e[g[v][ptr[v]]].to, next); 52 | if (x > 0) { 53 | e[g[v][ptr[v]]].mx -= x; 54 | e[g[v][ptr[v]]^1].mx += x; 55 | return x; 56 | } else { 57 | ++ptr[v]; 58 | } 59 | } else { 60 | ++ptr[v]; 61 | } 62 | } 63 | return 0; 64 | }; 65 | long long el_flow = go(s, 1e9l * 1e9l * 4l); 66 | if (el_flow == 0) 67 | break; 68 | flow += el_flow; 69 | } 70 | if (flow == prev_flow) 71 | break; 72 | } 73 | return flow; 74 | } 75 | -------------------------------------------------------------------------------- /max_flow_dinic_scaling.cpp: -------------------------------------------------------------------------------- 1 | struct dinic_edge { 2 | int from, to; 3 | long long mx; 4 | }; 5 | 6 | long long max_flow_dinic(vector>> g_main, int s, int t) { 7 | int n = g_main.size(); 8 | vector> g(n); 9 | vector e; 10 | long long maxw = 0; 11 | for (int u = 0; u < n; ++u) { 12 | for (auto pr : g_main[u]) { 13 | int v = pr.first; 14 | long long w = pr.second; 15 | maxw = max(w, maxw); 16 | g[u].push_back(e.size()); 17 | e.push_back({u, v, w}); 18 | g[v].push_back(e.size()); 19 | e.push_back({v, u, 0}); 20 | } 21 | } 22 | long long flow = 0; 23 | vector layer(n, -5); 24 | vector q(n + 10); 25 | int ql, qr; 26 | vector ptr(n, 0); 27 | while (maxw != 0) { 28 | for (int i = 0; i < n; ++i) { 29 | layer.assign(n, -5); 30 | ptr.assign(n, 0); 31 | ql = 0; 32 | qr = 1; 33 | q[0] = s; 34 | layer[s] = 0; 35 | while (ql < qr) { 36 | int v = q[ql++]; 37 | for (auto k : g[v]) { 38 | if (e[k].mx >= maxw && layer[e[k].to] == -5) { 39 | layer[e[k].to] = layer[v] + 1; 40 | q[qr++] = e[k].to; 41 | } 42 | } 43 | } 44 | if (layer[t] == -5) 45 | break; 46 | long long prev_flow = flow; 47 | while (true) { 48 | function go = [&](int v, long long now) -> long long { 49 | if (v == t) 50 | return now; 51 | while (ptr[v] < g[v].size()) { 52 | if (layer[v] + 1 == layer[e[g[v][ptr[v]]].to] && e[g[v][ptr[v]]].mx >= maxw) { 53 | long long next = min(now, e[g[v][ptr[v]]].mx); 54 | long long x = go(e[g[v][ptr[v]]].to, next); 55 | if (x > 0) { 56 | e[g[v][ptr[v]]].mx -= x; 57 | e[g[v][ptr[v]]^1].mx += x; 58 | return x; 59 | } else { 60 | ++ptr[v]; 61 | } 62 | } else { 63 | ++ptr[v]; 64 | } 65 | } 66 | return 0; 67 | }; 68 | long long el_flow = go(s, 1e9l * 1e9l * 4l); 69 | if (el_flow == 0) 70 | break; 71 | flow += el_flow; 72 | } 73 | if (flow == prev_flow) 74 | break; 75 | } 76 | maxw /= 2; 77 | } 78 | return flow; 79 | } 80 | -------------------------------------------------------------------------------- /min_cost_flow.cpp: -------------------------------------------------------------------------------- 1 | using COST_T = long long; 2 | struct mfmc_edge { 3 | int from, to; 4 | long long mx; 5 | long long cost; // for 1 flow 6 | }; 7 | 8 | pair max_flow_min_cost(vector>>> g_main, int s, int t, ll k = -1) { 9 | int n = g_main.size(); 10 | vector> g(n); 11 | vector e; 12 | for (int u = 0; u < n; ++u) { 13 | for (auto p : g_main[u]) { 14 | int v = p.first; 15 | ll w = p.second.first, c = p.second.second; 16 | g[u].push_back(e.size()); 17 | e.push_back({u, v, w, c}); // !!! may need to change c to c/w !!! 18 | g[v].push_back(e.size()); 19 | e.push_back({v, u, 0, -c}); 20 | } 21 | } 22 | const ll inf = 1e18l * 4; 23 | vector p(n, inf); 24 | p[s] = 0; 25 | vector par(n, -1); 26 | for (int i = 0; i < n; ++i) { 27 | bool change = false; 28 | for (int j = 0; j < e.size(); ++j) { 29 | auto edge = e[j]; 30 | if (edge.mx > 0 && p[edge.from] != inf) { 31 | if (p[edge.to] > p[edge.from] + edge.cost) { 32 | p[edge.to] = p[edge.from] + edge.cost; 33 | par[edge.to] = j; 34 | change = true; 35 | } 36 | } 37 | } 38 | if (!change) 39 | break; 40 | } 41 | pair ans = {0, 0}; 42 | vector d = p; 43 | while (true) { 44 | if (par[t] == -1) 45 | break; 46 | if (ans.first == k) 47 | break; 48 | int v = t; 49 | ll flow = (k == -1 ? (ll)4e18 : k - ans.first), cost = 0; 50 | while (v != s) { 51 | flow = min(flow, e[par[v]].mx); 52 | cost += e[par[v]].cost; 53 | v = e[par[v]].from; 54 | } 55 | v = t; 56 | while (v != s) { 57 | e[par[v]].mx -= flow; 58 | e[par[v]^1].mx += flow; 59 | v = e[par[v]].from; 60 | } 61 | ans.first += flow; 62 | ans.second += cost * flow; 63 | par.assign(n, -1); 64 | d.assign(n, inf); 65 | d[s] = 0; 66 | priority_queue, vector>, greater>> pq; 67 | pq.push({0, s}); 68 | while (!pq.empty()) { 69 | int v = pq.top().second; 70 | ll ds = pq.top().first; 71 | pq.pop(); 72 | if (ds > d[v]) 73 | continue; 74 | for (auto i : g[v]) { 75 | if (e[i].mx > 0 && d[e[i].to] > d[v] + e[i].cost + p[e[i].from] - p[e[i].to]) { 76 | d[e[i].to] = d[v] + e[i].cost + p[e[i].from] - p[e[i].to]; 77 | par[e[i].to] = i; 78 | pq.push({d[e[i].to], e[i].to}); 79 | } 80 | } 81 | } 82 | for (int i = 0; i < n; ++i) { 83 | if (d[v] == inf || p[v] == inf) 84 | p[v] = inf; 85 | else 86 | p[v] += d[v]; 87 | } 88 | } 89 | return ans; 90 | } 91 | -------------------------------------------------------------------------------- /min_queue.cpp: -------------------------------------------------------------------------------- 1 | // use std::greater to make max_queue 2 | // to use min_stack2, set needed array size in min_stack2 and change 3 | // [min_stack s1, s2;] to [min_stack2 s1, s2;] 4 | template> 5 | struct min_queue { 6 | struct min_stack { 7 | vector> v; 8 | 9 | void push(const T &x) { 10 | if (v.empty()) { 11 | v.eb(x, x); 12 | return; 13 | } 14 | const T &was = v.back().first; 15 | v.eb((Comp()(x, was) ? x : was), x); 16 | } 17 | 18 | void pop() { 19 | v.pop_back(); 20 | } 21 | 22 | T extract() { 23 | auto res = v.back().second; 24 | v.pop_back(); 25 | return res; 26 | } 27 | 28 | T get_min() const { 29 | return v.back().first; 30 | } 31 | 32 | T top() const { 33 | return v.back().second; 34 | } 35 | 36 | bool empty() const { 37 | return v.empty(); 38 | } 39 | 40 | int size() const { 41 | return v.size(); 42 | } 43 | 44 | void clear() { 45 | v.clear(); 46 | } 47 | }; 48 | struct min_stack2 { 49 | array, 12345> v; 50 | int iv = 0; 51 | 52 | void push(const T &x) { 53 | if (iv == 0) { 54 | v[iv++] = make_pair(x, x); 55 | return; 56 | } 57 | const T &was = v[iv - 1].first; 58 | v[iv++] = make_pair((Comp()(x, was) ? x : was), x); 59 | } 60 | 61 | void pop() { 62 | --iv; 63 | } 64 | 65 | T extract() { 66 | auto res = v[iv - 1].second; 67 | --iv; 68 | return res; 69 | } 70 | 71 | T get_min() const { 72 | return v[iv - 1].first; 73 | } 74 | 75 | T top() const { 76 | return v[iv - 1].second; 77 | } 78 | 79 | bool empty() const { 80 | return iv == 0; 81 | } 82 | 83 | int size() const { 84 | return iv; 85 | } 86 | 87 | void clear() { 88 | iv = 0; 89 | } 90 | }; 91 | 92 | min_stack s1, s2; 93 | void push(const T &x) { 94 | s2.push(x); 95 | } 96 | 97 | void pop() { 98 | if (s1.empty()) { 99 | while (!s2.empty()) 100 | s1.push(s2.extract()); 101 | } 102 | s1.pop(); 103 | } 104 | 105 | T front() { 106 | if (s1.empty()) { 107 | while (!s2.empty()) 108 | s1.push(s2.extract()); 109 | } 110 | return s1.top(); 111 | } 112 | 113 | T get_min() const { 114 | if (s1.empty()) return s2.get_min(); 115 | else if (s2.empty()) return s1.get_min(); 116 | T a = s1.get_min(); 117 | T b = s2.get_min(); 118 | return (Comp()(a, b) ? a : b); 119 | } 120 | 121 | bool empty() const { 122 | return s1.empty() && s2.empty(); 123 | } 124 | 125 | int size() const { 126 | return s1.size() + s2.size(); 127 | } 128 | 129 | void clear() { 130 | s1.clear(); 131 | s2.clear(); 132 | } 133 | }; 134 | 135 | template 136 | ostream &operator << (ostream &o, const min_queue &q) { 137 | o << "["; 138 | bool first = true; 139 | for (int i = (int)q.s1.size() - 1; i >= 0; --i) { 140 | if (!first) 141 | o << ", "; 142 | o << q.s1.v[i].second; 143 | first = false; 144 | } 145 | o << " | "; 146 | for (int i = 0; i < q.s2.size(); ++i) { 147 | if (!first) 148 | o << ", "; 149 | o << q.s2.v[i].second; 150 | first = false; 151 | } 152 | return o; 153 | } 154 | -------------------------------------------------------------------------------- /mint.cpp: -------------------------------------------------------------------------------- 1 | namespace mint_ns { 2 | template 3 | struct Modular { 4 | using value_type = decltype(P); 5 | value_type value; 6 | 7 | Modular(long long k = 0) : value(norm(k)) {} 8 | 9 | friend Modular

& operator += ( Modular

& n, const Modular

& m) { n.value += m.value; if (n.value >= P) n.value -= P; return n; } 10 | friend Modular

operator + (const Modular

& n, const Modular

& m) { Modular

r = n; return r += m; } 11 | 12 | friend Modular

& operator -= ( Modular

& n, const Modular

& m) { n.value -= m.value; if (n.value < 0) n.value += P; return n; } 13 | friend Modular

operator - (const Modular

& n, const Modular

& m) { Modular

r = n; return r -= m; } 14 | friend Modular

operator - (const Modular

& n) { return Modular

(-n.value); } 15 | 16 | friend Modular

& operator *= ( Modular

& n, const Modular

& m) { n.value = n.value * 1ll * m.value % P; return n; } 17 | friend Modular

operator * (const Modular

& n, const Modular

& m) { Modular

r = n; return r *= m; } 18 | 19 | friend Modular

& operator /= ( Modular

& n, const Modular

& m) { return n *= m.inv(); } 20 | friend Modular

operator / (const Modular

& n, const Modular

& m) { Modular

r = n; return r /= m; } 21 | 22 | Modular

& operator ++ ( ) { return *this += 1; } 23 | Modular

& operator -- ( ) { return *this -= 1; } 24 | Modular

operator ++ (int) { Modular

r = *this; *this += 1; return r; } 25 | Modular

operator -- (int) { Modular

r = *this; *this -= 1; return r; } 26 | 27 | friend bool operator == (const Modular

& n, const Modular

& m) { return n.value == m.value; } 28 | friend bool operator != (const Modular

& n, const Modular

& m) { return n.value != m.value; } 29 | 30 | explicit operator int() const { return value; } 31 | explicit operator bool() const { return value; } 32 | explicit operator long long() const { return value; } 33 | 34 | constexpr static value_type mod() { return P; } 35 | 36 | value_type norm(long long k) { 37 | if (!(-P <= k && k < P)) k %= P; 38 | if (k < 0) k += P; 39 | return k; 40 | } 41 | 42 | Modular

inv() const { 43 | value_type a = value, b = P, x = 0, y = 1; 44 | while (a != 0) { value_type k = b / a; b -= k * a; x -= k * y; swap(a, b); swap(x, y); } 45 | return Modular

(x); 46 | } 47 | }; 48 | template Modular

pow(Modular

m, long long p) { 49 | Modular

r(1); 50 | while (p) { 51 | if (p & 1) r *= m; 52 | m *= m; 53 | p >>= 1; 54 | } 55 | return r; 56 | } 57 | 58 | template ostream& operator << (ostream& o, const Modular

& m) { return o << m.value; } 59 | template istream& operator >> (istream& i, Modular

& m) { long long k; i >> k; m.value = m.norm(k); return i; } 60 | template string to_string(const Modular

& m) { return to_string(m.value); } 61 | 62 | using Mint = Modular<1000000007>; 63 | // using Mint = Modular<998244353>; 64 | // using Mint = long double; 65 | 66 | vector f, fi; 67 | void init_C(int n) { 68 | f.assign(n, 1); fi.assign(n, 1); 69 | for (int i = 2; i < n; ++i) f[i] = f[i - 1] * i; 70 | fi.back() = Mint(1) / f.back(); 71 | for (int i = n - 2; i >= 0; --i) fi[i] = fi[i + 1] * (i + 1); 72 | } 73 | Mint C(int n, int k) { 74 | if (k < 0 || k > n) return 0; 75 | else return f[n] * fi[k] * fi[n - k]; 76 | } 77 | } 78 | using namespace mint_ns; 79 | -------------------------------------------------------------------------------- /mint14.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct Modular { 3 | using value_type = decltype(P); 4 | value_type value; 5 | 6 | Modular(ll k = 0) : value(norm(k)) {} 7 | 8 | Modular& operator += (const Modular& m) { value += m.value; if (value >= P) value -= P; return *this; } 9 | Modular operator + (const Modular& m) const { Modular r = *this; return r += m; } 10 | 11 | Modular& operator -= (const Modular& m) { value -= m.value; if (value < 0) value += P; return *this; } 12 | Modular operator - (const Modular& m) const { Modular r = *this; return r -= m; } 13 | Modular operator - () const { return Modular(-value); } 14 | 15 | Modular& operator *= (const Modular &m) { value = value * 1ll * m.value % P; return *this; } 16 | Modular operator * (const Modular& m) const { Modular r = *this; return r *= m; } 17 | 18 | Modular& operator /= (const Modular &m) { return *this *= m.inv(); } 19 | Modular operator / (const Modular& m) const { Modular r = *this; return r /= m; } 20 | 21 | Modular& operator ++ () { return *this += 1; } 22 | Modular& operator -- () { return *this -= 1; } 23 | Modular operator ++ (int) { Modular r = *this; *this += 1; return r; } 24 | Modular operator -- (int) { Modular r = *this; *this -= 1; return r; } 25 | 26 | bool operator == (const Modular& m) const { return value == m.value; } 27 | bool operator != (const Modular& m) const { return value != m.value; } 28 | 29 | value_type norm(ll k) { 30 | if (!(-P <= k && k < P)) k %= P; 31 | if (k < 0) k += P; 32 | return k; 33 | } 34 | 35 | Modular inv() const { 36 | value_type a = value, b = P, x = 0, y = 1; 37 | while (a != 0) { value_type k = b / a; b -= k * a; x -= k * y; swap(a, b); swap(x, y); } 38 | return Modular

(x); 39 | } 40 | }; 41 | 42 | template Modular

pow(Modular

m, ll p) { 43 | Modular

r(1); 44 | while (p) { 45 | if (p & 1) r *= m; 46 | m *= m; 47 | p >>= 1; 48 | } 49 | return r; 50 | } 51 | 52 | template ostream& operator << (ostream& o, const Modular

&m) { return o << m.value; } 53 | template istream& operator >> (istream& i, Modular

&m) { ll k; i >> k; m.value = m.norm(k); return i; } 54 | template string to_string(const Modular

& m) { return to_string(m.value); } 55 | 56 | using Mint = Modular<1000000007>; 57 | // using Mint = Modular<998244353>; 58 | // using Mint = long double; 59 | -------------------------------------------------------------------------------- /nim_prod.cpp: -------------------------------------------------------------------------------- 1 | struct bit_prod_t { 2 | // B=8 requires 32MB, B=4 requires 0.5 MB, time and space complexity of precalc is 4^B * 64^2 / B^2 3 | const static int B = 8; 4 | const static int BM = (uint64_t(1) << B) - 1; 5 | array, 64 / B>, 1 << B>, 64 / B> v = {}; 6 | bit_prod_t() { 7 | array, 64> bp = {}; 8 | for (int i = 0; i < 64; ++i) { 9 | for (int j = 0; j < 64; ++j) { 10 | if (!(i & j)) { 11 | bp[i][j] = uint64_t(1) << (i | j); 12 | } else { 13 | // square(2^2^a) = 2^2^a ^ 2^(2^a-1) 14 | int a = (i & j) & -(i & j); 15 | bp[i][j] = bp[i ^ a][j] ^ bp[(i ^ a) | (a - 1)][(j ^ a) | (i & (a - 1))]; 16 | } 17 | } 18 | } 19 | array lg = {}; 20 | for (int i = 0; i < B; ++i) 21 | lg[1 << i] = i; 22 | for (uint64_t b1 = 0; b1 < 64 / B; ++b1) { 23 | for (uint64_t i = 0; i < (1 << B); ++i) { 24 | for (uint64_t b2 = 0; b2 < 64 / B; ++b2) { 25 | for (uint64_t j = 0; j < (1 << B); ++j) { 26 | if (i == 0 || j == 0) { 27 | v[b1][i][b2][j] = 0; 28 | continue; 29 | } 30 | if ((j & (j - 1)) == 0) { 31 | if ((i & (i - 1)) == 0) { 32 | v[b1][i][b2][j] = bp[lg[i] + b1 * B][lg[j] + b2 * B]; 33 | } else { 34 | uint64_t a = i & -i; 35 | v[b1][i][b2][j] = v[b1][i ^ a][b2][j] ^ v[b1][a][b2][j]; 36 | } 37 | } else { 38 | uint64_t a = j & -j; 39 | v[b1][i][b2][j] = v[b1][i][b2][j ^ a] ^ v[b1][i][b2][a]; 40 | } 41 | } 42 | } 43 | } 44 | } 45 | } 46 | 47 | const auto &operator [] (int i) const { 48 | return v[i]; 49 | } 50 | } bit_prod; 51 | 52 | uint64_t nim_prod(uint64_t a, uint64_t b) { 53 | uint64_t res = 0; 54 | for (int i = 0, ib = 0; (ib < 64) && (a >> ib); ++i, ib += bit_prod_t::B) 55 | for (int j = 0, jb = 0; (jb < 64) && (b >> jb); ++j, jb += bit_prod_t::B) 56 | res ^= bit_prod[i][(a >> ib) & bit_prod_t::BM][j][(b >> jb) & bit_prod_t::BM]; 57 | return res; 58 | } 59 | -------------------------------------------------------------------------------- /nim_prod_slow.cpp: -------------------------------------------------------------------------------- 1 | constexpr struct bit_prod_t { 2 | array, 64> v = {}; 3 | constexpr bit_prod_t() { 4 | for (int i = 0; i < 64; ++i) { 5 | for (int j = 0; j < 64; ++j) { 6 | if (!(i & j)) { 7 | v[i][j] = uint64_t(1) << (i | j); 8 | } else { 9 | // square(2^2^a) = 2^2^a ^ 2^(2^a-1) 10 | int a = (i & j) & -(i & j); 11 | v[i][j] = v[i ^ a][j] ^ v[(i ^ a) | (a - 1)][(j ^ a) | (i & (a - 1))]; 12 | } 13 | } 14 | } 15 | } 16 | 17 | const array &operator [] (int i) const { 18 | return v[i]; 19 | } 20 | } bit_prod; 21 | 22 | uint64_t nim_prod(uint64_t a, uint64_t b) { 23 | uint64_t res = 0; 24 | for (int i = 0; (i < 64) && (a >> i); ++i) 25 | if ((a >> i) & 1) 26 | for (int j = 0; (j < 64) && (b >> j); ++j) 27 | if ((b >> j) & 1) 28 | res ^= bit_prod[i][j]; 29 | return res; 30 | } 31 | -------------------------------------------------------------------------------- /ntt.cpp: -------------------------------------------------------------------------------- 1 | namespace ntt { 2 | // TODO: square 3 | 4 | Mint g = 0; // set to something, or leave at 0 to calculate at runtime, g^(max power of 2 in mod-1) == 1 5 | int maxn = -1; 6 | 7 | vector buf1; 8 | vector buf2; 9 | 10 | vector reversed = {0}; 11 | 12 | void init_g() { 13 | int phi = (int)Mint(-1); // mod - 1 14 | maxn = 1; 15 | while ((phi & 1) == 0) { 16 | maxn <<= 1; 17 | phi >>= 1; 18 | } 19 | 20 | if (g == 0) { 21 | while (true) { 22 | Mint v = pow(g, maxn / 2); 23 | if (v != 1 && v * v == 1) 24 | break; 25 | ++g; 26 | } 27 | } 28 | 29 | assert(pow(g, maxn) == 1 && pow(g, maxn / 2) != 1); 30 | } 31 | 32 | void update_n(int n) { 33 | if (maxn == -1) 34 | init_g(); 35 | assert(n <= maxn); 36 | assert((n & (n - 1)) == 0); 37 | int cur = reversed.size(); 38 | if (n <= cur) return; 39 | reversed.resize(n); 40 | while (cur < n) { 41 | for (int i = 0; i < cur; ++i) 42 | reversed[i] <<= 1; 43 | for (int i = cur; i < (cur << 1); ++i) 44 | reversed[i] = reversed[i - cur] ^ 1; 45 | cur *= 2; 46 | } 47 | } 48 | 49 | void ntt_internal(vector &v, int from, int n, bool inv) { 50 | update_n(n); 51 | int N = reversed.size(); 52 | 53 | int d = __lg(N) - __lg(n); 54 | 55 | for (int i = 1; i < n; ++i) 56 | if (i < (reversed[i] >> d)) 57 | swap(v[from + i], v[from + (reversed[i] >> d)]); 58 | 59 | for (int ln = 1; ln < n; ln <<= 1) { 60 | Mint ww; 61 | ww = pow(g, maxn / (ln * 2)); 62 | if (inv) 63 | ww = Mint(1) / ww; 64 | for (int i = 0; i < n; i += (ln << 1)) { 65 | Mint w = 1; 66 | for (int j = 0; j < ln; ++j) { 67 | Mint y = v[from + i + j + ln] * w; 68 | w *= ww; 69 | v[from + i + j + ln] = v[from + i + j] - y; 70 | v[from + i + j] = v[from + i + j] + y; 71 | } 72 | } 73 | } 74 | 75 | if (inv) { 76 | Mint ni = Mint(1) / n; 77 | for (int i = 0; i < n; ++i) 78 | v[from + i] *= ni; 79 | } 80 | } 81 | 82 | vector ntt(const vector &v, int n = -1) { 83 | if (n == -1) { 84 | n = 1; 85 | while (n < v.size()) n <<= 1; 86 | } 87 | assert(v.size() <= n); 88 | buf1.assign(n, 0); 89 | for (int i = 0; i < v.size(); ++i) 90 | buf1[i] = v[i]; 91 | ntt_internal(buf1, 0, n, false); 92 | return buf1; 93 | } 94 | 95 | vector ntti(const vector &v) { 96 | assert(!v.empty() && (v.size() & (v.size() - 1)) == 0); 97 | buf1.resize(v.size()); 98 | for (int i = 0; i < v.size(); ++i) 99 | buf1[i] = v[i]; 100 | ntt_internal(buf1, 0, buf1.size(), true); 101 | return buf1; 102 | } 103 | 104 | vector multiply(const vector &a, const vector &b) { 105 | if (a.empty() || b.empty()) return {}; 106 | int n = 2; 107 | while (n < a.size() + b.size() - 1) n <<= 1; 108 | 109 | buf1.assign(n, 0); 110 | for (int i = 0; i < a.size(); ++i) 111 | buf1[i] = a[i]; 112 | 113 | buf2.assign(n, 0); 114 | for (int i = 0; i < b.size(); ++i) 115 | buf2[i] = b[i]; 116 | 117 | ntt_internal(buf1, 0, n, false); 118 | ntt_internal(buf2, 0, n, false); 119 | 120 | for (int i = 0; i < n; ++i) 121 | buf1[i] *= buf2[i]; 122 | 123 | ntt_internal(buf1, 0, n, true); 124 | 125 | buf1.resize(a.size() + b.size() - 1); 126 | return buf1; 127 | } 128 | 129 | } // ntt 130 | -------------------------------------------------------------------------------- /old/fft.cpp: -------------------------------------------------------------------------------- 1 | const long double eps = 1e-12; 2 | const long double pi = 3.14159265358979323; 3 | 4 | // when using big integers mod = 10000 works better than 100000 and bigger; 5 | // using Complex = complex; // slower than my Complex 6 | 7 | namespace fft { 8 | struct Complex { 9 | long double x, y; 10 | 11 | Complex() : x(0), y(0) {} 12 | Complex(long double _x, long double _y) : x(_x), y(_y) {} 13 | Complex(long double _x) : x(_x), y(0) {} 14 | Complex(const Complex& c) : x(c.x), y(c.y) {} 15 | }; 16 | 17 | Complex operator - (Complex& a) { 18 | return Complex(-a.x, -a.y); 19 | } 20 | 21 | Complex operator + (Complex& a, Complex&& b) { 22 | return Complex(a.x + b.x, a.y + b.y); 23 | } 24 | 25 | Complex operator * (Complex& a, Complex& b) { 26 | return Complex(a.x * b.x - a.y * b.y, a.x * b.y + b.x * a.y); 27 | } 28 | 29 | template 30 | vector fft(vector& v, bool good = false) { 31 | if (!good) { 32 | int p2 = 1; 33 | while (p2 < v.size()) { 34 | p2 <<= 1; 35 | } 36 | v.resize(p2); 37 | for (int i = v.size(); i < p2; ++i) { 38 | v[i] = 0; 39 | } 40 | } 41 | if (v.size() == 1) { 42 | return vector {Complex(v[0])}; 43 | } 44 | int n = v.size() / 2; 45 | vector v1(n * 2); 46 | int k = 0, n1 = 2 * n; 47 | while (n1 > 1) { 48 | n1 >>= 1; 49 | ++k; 50 | } 51 | vector w(2 * n); 52 | w[0] = 1; 53 | w[1] = Complex(cosl(pi / n), sinl(pi / n)); 54 | for (int i = 2; i < 2 * n; ++i) { 55 | if (i >= n) { 56 | w[i] = -w[i - n]; 57 | } else { 58 | w[i] = w[i / 2] * w[i - i / 2]; 59 | } 60 | } 61 | vector ind(2 * n, 0); 62 | ind[1] = 1 << (k - 1); 63 | int id = 2; 64 | for (int i = 1; i < k; ++i) { 65 | int z = (1 << i); 66 | for (int j = 0; j < z; ++j) { 67 | ind[id] = (ind[id - z]) + (1 << (k - 1 - i)); 68 | ++id; 69 | } 70 | } 71 | for (int i = 0; i < 2 * n; ++i) { 72 | v1[i] = Complex(v[ind[i]]); 73 | } 74 | for (int i = k - 1; i >= 0; --i) { 75 | int cnt = (1 << i); 76 | int sz = (1 << (k - i)); 77 | int k1 = sz / 2 - 1; 78 | for (int j = 0; j < cnt; ++j) { 79 | int k2 = sz * j; 80 | vector va(v1.begin() + sz * j, v1.begin() + sz * j + sz / 2); 81 | vector vb(v1.begin() + sz * j + sz / 2, v1.begin() + sz * j + sz); 82 | for (int u = 0; u < sz; ++u) { 83 | v1[k2 + u] = va[u & k1] + w[u << i] * vb[u & k1]; 84 | } 85 | } 86 | } 87 | return v1; 88 | } 89 | 90 | template 91 | vector multiply(vector& a, vector& b) { 92 | // if (a.size() <= 2 || b.size() <= 2) { 93 | // vector c(a.size() + b.size() - 1, 0); 94 | // for (int i = 0; i < a.size(); ++i) { 95 | // for (int j = 0; j < b.size(); ++j) { 96 | // c[i + j] += a[i] * b[j]; 97 | // } 98 | // } 99 | // while (c.size() > 0 && c.back() == 0) { 100 | // c.pop_back(); 101 | // } 102 | // return c; 103 | // } 104 | int k = a.size() + b.size() - 1; 105 | int p2 = 1; 106 | while (p2 < k) { 107 | p2 <<= 1; 108 | } 109 | int oldasize = a.size(); 110 | int oldbsize = b.size(); 111 | a.resize(p2); 112 | for (int i = oldasize; i < p2; ++i) { 113 | a[i] = 0; 114 | } 115 | b.resize(p2); 116 | for (int i = oldbsize; i < p2; ++i) { 117 | b[i] = 0; 118 | } 119 | int n = p2; 120 | vector va = fft(a, true), vb = fft(b, true); 121 | for (int i = 0; i < n; ++i) { 122 | va[i] = va[i] * vb[i]; 123 | } 124 | vector ansC = fft(va, true); 125 | vector ans(n); 126 | for (int i = 0; i < n; ++i) { 127 | if (typeid(T) == typeid(int) || typeid(T) == typeid(long long)) { 128 | ans[i] = (long long)round(ansC[i].x / (long double)(1.0 * n)); // if T is int 129 | } else { 130 | ans[i] = ansC[i].x / (1.0 * n); // if T is real 131 | if (ans[i] < eps) { 132 | ans[i] = 0; 133 | } 134 | } 135 | } 136 | for (int i = 1; i <= n / 2; ++i) { 137 | swap(ans[i], ans[n - i]); 138 | } 139 | while (ans.size() > 0 && ans.back() == 0) { 140 | ans.pop_back(); 141 | } 142 | return ans; 143 | } 144 | 145 | template 146 | void square(vector& a) { 147 | int k = a.size() * 2 - 1; 148 | int p2 = 1; 149 | while (p2 < k) { 150 | p2 *= 2; 151 | } 152 | int oldasize = a.size(); 153 | a.resize(p2); 154 | for (int i = oldasize; i < p2; ++i) { 155 | a[i] = 0; 156 | } 157 | int n = p2; 158 | vector va = fft(a, true); 159 | for (int i = 0; i < n; ++i) { 160 | va[i] = va[i] * va[i]; 161 | } 162 | vector ansC = fft(va, true); 163 | for (int i = 0; i < n; ++i) { 164 | if (typeid(T) == typeid(int) || typeid(T) == typeid(long long)) { 165 | a[i] = (long long)round(ansC[i].x / (long double)(1.0 * n)); // if T is int 166 | } else { 167 | a[i] = ansC[i].x / (1.0 * n); // if T is real 168 | if (a[i] < eps) { 169 | a[i] = 0; 170 | } 171 | } 172 | } 173 | for (int i = 1; i <= n / 2; ++i) { 174 | swap(a[i], a[n - i]); 175 | } 176 | while (a.size() > 0 && a.back() == 0) { 177 | a.pop_back(); 178 | } 179 | } 180 | } // fft 181 | -------------------------------------------------------------------------------- /old/segtree.cpp: -------------------------------------------------------------------------------- 1 | using T = int; 2 | 3 | struct segtree { 4 | vector tree; 5 | int n; 6 | 7 | segtree(int size) : n(size), tree(size * 4, T()) {} 8 | segtree(vector& v) : n(v.size()), tree(v.size() * 4) { 9 | build(v, 0, 0, n - 1); 10 | } 11 | 12 | void build(vector& v, int i, int l, int r) { 13 | if (l == r) { 14 | tree[i] = v[l]; 15 | return; 16 | } 17 | int m = (l + r) / 2; 18 | build(v, i * 2 + 1, l, m); 19 | build(v, i * 2 + 2, m + 1, r); 20 | tree[i] = tree[2 * i + 1] + tree[2 * i + 2]; 21 | } 22 | 23 | void set(int ind, T k, int i, int l, int r) { 24 | while (l < r) { 25 | int m = (l + r) / 2; 26 | if (ind <= m) { 27 | r = m; 28 | i = 2 * i + 1; 29 | } else { 30 | l = m + 1; 31 | i = 2 * i + 2; 32 | } 33 | } 34 | tree[i] = k; 35 | while (i != 0) { 36 | i = (i - 1) / 2; 37 | tree[i] = tree[2 * i + 1] + tree[2 * i + 2]; 38 | } 39 | } 40 | 41 | void set(int ind, T k) { 42 | set(ind, k, 0, 0, n - 1); 43 | } 44 | 45 | T ask(int l, int r, int i, int vl, int vr) { 46 | if (l == vl && r == vr) { 47 | return tree[i]; 48 | } 49 | int m = (vl + vr) / 2; 50 | if (r <= m) { 51 | return ask(l, r, 2 * i + 1, vl, m); 52 | } 53 | if (l > m) { 54 | return ask(l, r, 2 * i + 2, m + 1, vr); 55 | } 56 | return ask(l, m, 2 * i + 1, vl, m) + ask(m + 1, r, 2 * i + 2, m + 1, vr); 57 | } 58 | 59 | T ask(int l, int r) { 60 | return ask(l, r, 0, 0, n - 1); 61 | } 62 | }; 63 | -------------------------------------------------------------------------------- /old/segtree_max_modify_equal.cpp: -------------------------------------------------------------------------------- 1 | const int inf = 2 * 1e9 + 100; 2 | 3 | struct item { 4 | bool is_equal = false; 5 | int equal = 0; 6 | int mx; 7 | 8 | item(int mx = -inf): mx(mx) {} 9 | 10 | int ask() { 11 | return is_equal ? equal : mx; 12 | } 13 | 14 | auto update(item& a, item& b) { 15 | if (a.ask() >= b.ask()) { // return left maximum 16 | mx = a.ask(); 17 | } else { 18 | mx = b.ask(); 19 | } 20 | } 21 | }; 22 | 23 | item operator + (item a, item b) { 24 | return item(max(a.ask(), b.ask())); 25 | } 26 | 27 | struct segtree { 28 | vector tree; 29 | int n; 30 | 31 | segtree(int size) : n(size), tree(size * 4, item()) {} 32 | template 33 | segtree(vector& v) : n(v.size()), tree(v.size() * 4) { 34 | build(v, 0, 0, n - 1); 35 | } 36 | 37 | template 38 | void build(vector& v, int i, int l, int r) { 39 | if (l == r) { 40 | tree[i] = item(v[l]); 41 | return; 42 | } 43 | int m = (l + r) / 2; 44 | build(v, i * 2 + 1, l, m); 45 | build(v, i * 2 + 2, m + 1, r); 46 | tree[i] = tree[2 * i + 1] + tree[2 * i + 2]; 47 | } 48 | 49 | template 50 | void set(int l, int r, InType k, int i, int vl, int vr) { 51 | if (l == vl && r == vr) { 52 | tree[i].is_equal = true; 53 | tree[i].equal = k; 54 | return; 55 | } 56 | int m = (vl + vr) / 2; 57 | if (tree[i].is_equal) { 58 | tree[i].is_equal = false; 59 | tree[2 * i + 1].is_equal = true; 60 | tree[2 * i + 1].equal = tree[i].equal; 61 | tree[2 * i + 2].is_equal = true; 62 | tree[2 * i + 2].equal = tree[i].equal; 63 | } 64 | if (r <= m) set(l, r, k, 2 * i + 1, vl, m); 65 | else if (l > m) set(l, r, k, 2 * i + 2, m + 1, vr); 66 | else { 67 | set( l, m, k, 2 * i + 1, vl, m); 68 | set(m + 1, r, k, 2 * i + 2, m + 1, vr); 69 | } 70 | tree[i].update(tree[2 * i + 1], tree[2 * i + 2]); 71 | } 72 | 73 | template 74 | void set(int l, int r, InType k) { 75 | set(l, r, k, 0, 0, n - 1); 76 | } 77 | 78 | auto ask(int l, int r, int i, int vl, int vr) { 79 | if (tree[i].is_equal) { 80 | return tree[i].equal; 81 | } 82 | if (l == vl && r == vr) { 83 | return tree[i].ask(); 84 | } 85 | int m = (vl + vr) / 2; 86 | if (r <= m) 87 | return ask(l, r, 2 * i + 1, vl, m); 88 | if (l > m) 89 | return ask(l, r, 2 * i + 2, m + 1, vr); 90 | return max(ask(l, m, 2 * i + 1, vl, m), ask(m + 1, r, 2 * i + 2, m + 1, vr)); 91 | } 92 | 93 | auto ask(int l, int r) { 94 | return ask(l, r, 0, 0, n - 1); 95 | } 96 | }; 97 | -------------------------------------------------------------------------------- /old/segtree_max_modify_sum.cpp: -------------------------------------------------------------------------------- 1 | const int inf = 1e9 * 2 + 5; 2 | 3 | struct item { 4 | int mx = 0; 5 | int ind = 0; // index of maximum 6 | int sm = 0; 7 | 8 | item() {} 9 | item(int mx, int ind = 0): mx(mx), ind(ind), sm(0) {} 10 | 11 | auto ask() { 12 | return mx + sm; 13 | } 14 | 15 | auto update(item& a, item& b) { 16 | if (a.ask() >= b.ask()) { // return left maximum 17 | mx = a.ask(); 18 | ind = a.ind; 19 | } else { 20 | mx = b.ask(); 21 | ind = b.ind; 22 | } 23 | return *this; 24 | } 25 | }; 26 | 27 | item operator + (item a, item b) { 28 | return item().update(a, b); 29 | } 30 | 31 | item operator + (item a, int b) { 32 | item c = a; 33 | c.mx += b; 34 | return c; 35 | } 36 | 37 | struct segtree { 38 | vector tree; 39 | int n; 40 | 41 | segtree(int size) : n(size), tree(size * 4, item()) { 42 | vector v(n, -inf); 43 | build(v, 0, 0, n - 1); 44 | } 45 | template 46 | segtree(vector& v) : n(v.size()), tree(v.size() * 4) { 47 | build(v, 0, 0, n - 1); 48 | } 49 | 50 | template 51 | void build(vector& v, int i, int l, int r) { 52 | if (l == r) { 53 | tree[i] = item(v[l], l); 54 | return; 55 | } 56 | int m = (l + r) / 2; 57 | build(v, i * 2 + 1, l, m); 58 | build(v, i * 2 + 2, m + 1, r); 59 | tree[i] = tree[2 * i + 1] + tree[2 * i + 2]; 60 | } 61 | 62 | template 63 | void set(int ind, InType k, int i, int vl, int vr) { 64 | if (vl == vr) { 65 | tree[i].mx = k - tree[i].sm; 66 | return; 67 | } 68 | int m = (vl + vr) / 2; 69 | if (ind <= m) set(ind, k - tree[i].sm, 2 * i + 1, vl, m); 70 | else set(ind, k - tree[i].sm, 2 * i + 2, m + 1, vr); 71 | tree[i].update(tree[2 * i + 1], tree[2 * i + 2]); 72 | } 73 | 74 | template 75 | void set(int ind, InType k) { 76 | set(ind, k, 0, 0, n - 1); 77 | } 78 | 79 | template 80 | void add(int l, int r, InType k, int i, int vl, int vr) { 81 | if (l == vl && r == vr) { 82 | tree[i].sm += k; 83 | return; 84 | } 85 | int m = (vl + vr) / 2; 86 | if (r <= m) add(l, r, k, 2 * i + 1, vl, m); 87 | else if (l > m) add(l, r, k, 2 * i + 2, m + 1, vr); 88 | else { 89 | add( l, m, k, 2 * i + 1, vl, m); 90 | add(m + 1, r, k, 2 * i + 2, m + 1, vr); 91 | } 92 | tree[i].update(tree[2 * i + 1], tree[2 * i + 2]); 93 | } 94 | 95 | template 96 | void add(int l, int r, InType k) { 97 | if (l > r) 98 | return; 99 | add(l, r, k, 0, 0, n - 1); 100 | } 101 | 102 | auto ask(int l, int r, int i, int vl, int vr) { 103 | if (l == vl && r == vr) { 104 | return tree[i].ask(); 105 | } 106 | int m = (vl + vr) / 2; 107 | if (r <= m) 108 | return ask(l, r, 2 * i + 1, vl, m) + tree[i].sm; 109 | if (l > m) 110 | return ask(l, r, 2 * i + 2, m + 1, vr) + tree[i].sm; 111 | return max(ask(l, m, 2 * i + 1, vl, m), ask(m + 1, r, 2 * i + 2, m + 1, vr)) + tree[i].sm; 112 | } 113 | 114 | auto ask(int l, int r) { 115 | if (l > r) 116 | return -inf; 117 | return ask(l, r, 0, 0, n - 1); 118 | } 119 | 120 | auto ask_item(int l, int r, int i, int vl, int vr) { 121 | if (l == vl && r == vr) { 122 | return item(tree[i].ask(), tree[i].ind); 123 | } 124 | int m = (vl + vr) / 2; 125 | if (r <= m) 126 | return ask_item(l, r, 2 * i + 1, vl, m) + tree[i].sm; 127 | if (l > m) 128 | return ask_item(l, r, 2 * i + 2, m + 1, vr) + tree[i].sm; 129 | return ask_item(l, m, 2 * i + 1, vl, m) + ask_item(m + 1, r, 2 * i + 2, m + 1, vr) + tree[i].sm; 130 | } 131 | 132 | auto ask_item(int l, int r) { 133 | if (l > r) 134 | return item(-inf); 135 | return ask_item(l, r, 0, 0, n - 1); 136 | } 137 | }; 138 | -------------------------------------------------------------------------------- /old/segtree_sum_max_modify_equal.cpp: -------------------------------------------------------------------------------- 1 | const int inf = 2 * 1e9 + 100; 2 | 3 | struct item { 4 | bool is_equal = false; 5 | int equal = 0; 6 | int mx; 7 | int sm = 0; 8 | int l = 0, r = 0; 9 | 10 | item(int value = -inf, int l = -1, int r = -1): mx(value), l(l), r(r), sm(value) {} 11 | 12 | auto ask_mx() { 13 | return is_equal ? equal : mx; 14 | } 15 | 16 | auto ask_sm() { 17 | return is_equal ? equal * (r - l + 1) : sm; 18 | } 19 | 20 | auto update(item& a, item& b) { 21 | if (a.ask_mx() >= b.ask_mx()) { // return left maximum 22 | mx = a.ask_mx(); 23 | } else { 24 | mx = b.ask_mx(); 25 | } 26 | sm = a.ask_sm() + b.ask_sm(); 27 | l = a.l; r = b.r; 28 | } 29 | }; 30 | 31 | item operator + (item a, item b) { 32 | item c; 33 | c.update(a, b); 34 | return c; 35 | } 36 | 37 | struct segtree { 38 | vector tree; 39 | int n; 40 | 41 | segtree(int size) : n(size), tree(size * 4, item()) {} 42 | template 43 | segtree(vector& v) : n(v.size()), tree(v.size() * 4) { 44 | build(v, 0, 0, n - 1); 45 | } 46 | 47 | template 48 | void build(vector& v, int i, int l, int r) { 49 | if (l == r) { 50 | tree[i] = item(v[l], l, l); 51 | return; 52 | } 53 | int m = (l + r) / 2; 54 | build(v, i * 2 + 1, l, m); 55 | build(v, i * 2 + 2, m + 1, r); 56 | tree[i] = tree[2 * i + 1] + tree[2 * i + 2]; 57 | } 58 | 59 | template 60 | void set(int l, int r, InType k, int i, int vl, int vr) { 61 | if (l == vl && r == vr) { 62 | tree[i].is_equal = true; 63 | tree[i].equal = k; 64 | return; 65 | } 66 | int m = (vl + vr) / 2; 67 | if (tree[i].is_equal) { 68 | tree[i].is_equal = false; 69 | tree[2 * i + 1].is_equal = true; 70 | tree[2 * i + 1].equal = tree[i].equal; 71 | tree[2 * i + 2].is_equal = true; 72 | tree[2 * i + 2].equal = tree[i].equal; 73 | } 74 | if (r <= m) set(l, r, k, 2 * i + 1, vl, m); 75 | else if (l > m) set(l, r, k, 2 * i + 2, m + 1, vr); 76 | else { 77 | set( l, m, k, 2 * i + 1, vl, m); 78 | set(m + 1, r, k, 2 * i + 2, m + 1, vr); 79 | } 80 | tree[i].update(tree[2 * i + 1], tree[2 * i + 2]); 81 | } 82 | 83 | template 84 | void set(int l, int r, InType k) { 85 | set(l, r, k, 0, 0, n - 1); 86 | } 87 | 88 | auto ask_mx(int l, int r, int i, int vl, int vr) { 89 | if (tree[i].is_equal) { 90 | return tree[i].equal; 91 | } 92 | if (l == vl && r == vr) { 93 | return tree[i].ask_mx(); 94 | } 95 | int m = (vl + vr) / 2; 96 | if (r <= m) 97 | return ask_mx(l, r, 2 * i + 1, vl, m); 98 | if (l > m) 99 | return ask_mx(l, r, 2 * i + 2, m + 1, vr); 100 | return max(ask_mx(l, m, 2 * i + 1, vl, m), ask_mx(m + 1, r, 2 * i + 2, m + 1, vr)); 101 | } 102 | 103 | auto ask_mx(int l, int r) { 104 | return ask_mx(l, r, 0, 0, n - 1); 105 | } 106 | 107 | auto ask_sm(int l, int r, int i, int vl, int vr) { 108 | if (tree[i].is_equal) { 109 | return tree[i].equal * (r - l + 1); 110 | } 111 | if (l == vl && r == vr) { 112 | return tree[i].ask_sm(); 113 | } 114 | int m = (vl + vr) / 2; 115 | if (r <= m) 116 | return ask_sm(l, r, 2 * i + 1, vl, m); 117 | if (l > m) 118 | return ask_sm(l, r, 2 * i + 2, m + 1, vr); 119 | return ask_sm(l, m, 2 * i + 1, vl, m) + ask_sm(m + 1, r, 2 * i + 2, m + 1, vr); 120 | } 121 | 122 | auto ask_sm(int l, int r) { 123 | return ask_sm(l, r, 0, 0, n - 1); 124 | } 125 | }; 126 | -------------------------------------------------------------------------------- /old/segtree_sum_max_modify_sum.cpp: -------------------------------------------------------------------------------- 1 | struct item { 2 | int mx = 0; 3 | int sm = 0; // sum on [l; r] 4 | int ind = 0; // index of maximum 5 | int l, r; 6 | int mod_sm = 0; // modify sum, not sum on [l; r] !!! 7 | 8 | item() {} 9 | item(int value, int ind = 0): sm(value), mx(value), ind(ind), l(ind), r(ind) {} 10 | 11 | int ask_mx() { 12 | return mx + mod_sm; 13 | } 14 | int ask_sm() { 15 | return sm + mod_sm * (r - l + 1); 16 | } 17 | 18 | auto update(item& a, item& b) { 19 | if (a.ask_mx() >= b.ask_mx()) { // return left maximum 20 | mx = a.ask_mx(); 21 | ind = a.ind; 22 | } else { 23 | mx = b.ask_mx(); 24 | ind = b.ind; 25 | } 26 | sm = a.ask_sm() + b.ask_sm(); 27 | l = a.l; r = b.r; 28 | return *this; 29 | } 30 | }; 31 | 32 | item operator + (item a, item b) { 33 | return item().update(a, b); 34 | } 35 | 36 | struct segtree { 37 | vector tree; 38 | int n; 39 | 40 | segtree(int size) : n(size), tree(size * 4, item()) { 41 | vector v(n, 0); 42 | build(v, 0, 0, n - 1); 43 | } 44 | template 45 | segtree(vector& v) : n(v.size()), tree(v.size() * 4) { 46 | build(v, 0, 0, n - 1); 47 | } 48 | 49 | template 50 | void build(vector& v, int i, int l, int r) { 51 | if (l == r) { 52 | tree[i] = item(v[l], l); 53 | return; 54 | } 55 | int m = (l + r) / 2; 56 | build(v, i * 2 + 1, l, m); 57 | build(v, i * 2 + 2, m + 1, r); 58 | tree[i] = tree[2 * i + 1] + tree[2 * i + 2]; 59 | } 60 | 61 | template 62 | void set(int ind, InType k, int i, int vl, int vr) { 63 | if (vl == vr) { 64 | tree[i].sm = k - tree[i].mod_sm; 65 | tree[i].mx = k - tree[i].mod_sm; 66 | return; 67 | } 68 | int m = (vl + vr) / 2; 69 | if (ind <= m) set(ind, k - tree[i].mod_sm, 2 * i + 1, vl, m); 70 | else set(ind, k - tree[i].mod_sm, 2 * i + 2, m + 1, vr); 71 | tree[i].update(tree[2 * i + 1], tree[2 * i + 2]); 72 | } 73 | 74 | template 75 | void set(int ind, InType k) { 76 | set(ind, k, 0, 0, n - 1); 77 | } 78 | 79 | template 80 | void add(int l, int r, InType k, int i, int vl, int vr) { 81 | if (l == vl && r == vr) { 82 | tree[i].mod_sm += k; 83 | return; 84 | } 85 | int m = (vl + vr) / 2; 86 | if (r <= m) add(l, r, k, 2 * i + 1, vl, m); 87 | else if (l > m) add(l, r, k, 2 * i + 2, m + 1, vr); 88 | else { 89 | add( l, m, k, 2 * i + 1, vl, m); 90 | add(m + 1, r, k, 2 * i + 2, m + 1, vr); 91 | } 92 | tree[i].update(tree[2 * i + 1], tree[2 * i + 2]); 93 | } 94 | 95 | template 96 | void add(int l, int r, InType k) { 97 | add(l, r, k, 0, 0, n - 1); 98 | } 99 | 100 | auto ask_sm(int l, int r, int i, int vl, int vr) { 101 | if (l == vl && r == vr) { 102 | return tree[i].ask_sm(); 103 | } 104 | int m = (vl + vr) / 2; 105 | if (r <= m) 106 | return ask_sm(l, r, 2 * i + 1, vl, m) + tree[i].mod_sm * (r - l + 1); 107 | if (l > m) 108 | return ask_sm(l, r, 2 * i + 2, m + 1, vr) + tree[i].mod_sm * (r - l + 1); 109 | return ask_sm(l, m, 2 * i + 1, vl, m) + ask_sm(m + 1, r, 2 * i + 2, m + 1, vr) + 110 | tree[i].mod_sm * (r - l + 1); 111 | } 112 | 113 | auto ask_sm(int l, int r) { 114 | return ask_sm(l, r, 0, 0, n - 1); 115 | } 116 | 117 | auto ask_mx(int l, int r, int i, int vl, int vr) { 118 | if (l == vl && r == vr) { 119 | return tree[i].ask_mx(); 120 | } 121 | int m = (vl + vr) / 2; 122 | if (r <= m) 123 | return ask_mx(l, r, 2 * i + 1, vl, m) + tree[i].mod_sm; 124 | if (l > m) 125 | return ask_mx(l, r, 2 * i + 2, m + 1, vr) + tree[i].mod_sm; 126 | return max(ask_mx(l, m, 2 * i + 1, vl, m), ask_mx(m + 1, r, 2 * i + 2, m + 1, vr)) + tree[i].mod_sm; 127 | } 128 | 129 | auto ask_mx(int l, int r) { 130 | return ask_mx(l, r, 0, 0, n - 1); 131 | } 132 | 133 | auto ask_item(int l, int r, int i, int vl, int vr) { 134 | if (l == vl && r == vr) { 135 | auto it = tree[i]; 136 | it.mx = it.ask_mx(); 137 | it.sm = it.ask_sm(); 138 | it.mod_sm = 0; 139 | return it; 140 | } 141 | int m = (vl + vr) / 2; 142 | item it; 143 | if (r <= m) 144 | it = ask_item(l, r, 2 * i + 1, vl, m); 145 | else if (l > m) 146 | it = ask_item(l, r, 2 * i + 2, m + 1, vr); 147 | else 148 | it = ask_item(l, m, 2 * i + 1, vl, m) + ask_item(m + 1, r, 2 * i + 2, m + 1, vr); 149 | it.mx += tree[i].mod_sm; 150 | it.sm += tree[i].mod_sm * (r - l + 1); 151 | return it; 152 | } 153 | 154 | auto ask_item(int l, int r) { 155 | return ask_item(l, r, 0, 0, n - 1); 156 | } 157 | }; 158 | -------------------------------------------------------------------------------- /old/segtree_sum_max_modify_sum_equal.cpp: -------------------------------------------------------------------------------- 1 | const int inf = 2 * 1e9 + 100; 2 | 3 | struct item { 4 | bool is_equal = false; 5 | int equal = 0; 6 | int mx; 7 | int sm = 0; 8 | int mod_sm = 0; 9 | int l = 0, r = 0; 10 | 11 | item(int value = -inf, int l = -1, int r = -1): mx(value), l(l), r(r), sm(value == -inf ? 0 : value) {} 12 | 13 | auto ask_mx() { 14 | return is_equal ? equal : mx; 15 | } 16 | 17 | auto ask_sm() { 18 | return is_equal ? equal * (r - l + 1) : sm; 19 | } 20 | 21 | auto update(item& a, item& b) { 22 | equal = 0; 23 | is_equal = false; 24 | mod_sm = 0; 25 | if (a.ask_mx() >= b.ask_mx()) { // return left maximum 26 | mx = a.ask_mx(); 27 | } else { 28 | mx = b.ask_mx(); 29 | } 30 | sm = a.ask_sm() + b.ask_sm(); 31 | l = a.l; r = b.r; 32 | return *this; 33 | } 34 | }; 35 | 36 | string to_string(item t) { 37 | return "[is_eq = " + to_string(t.is_equal) + ", equal = " + to_string(t.equal) + ", mx = " + to_string(t.mx) + 38 | ", sm = " + to_string(t.sm) + ", mod_sm = " + to_string(t.mod_sm) + 39 | ", (l,r) = (" + to_string(t.l) + "," + to_string(t.r) + ")]"; 40 | } 41 | 42 | item operator + (item a, item b) { 43 | return item().update(a, b); 44 | } 45 | 46 | struct segtree { 47 | vector tree; 48 | int n; 49 | 50 | segtree(int size) : n(size), tree(size * 4, item()) { 51 | vector v(n, 0); 52 | build(v, 0, 0, n - 1); 53 | } 54 | template 55 | segtree(vector& v) : n(v.size()), tree(v.size() * 4) { 56 | build(v, 0, 0, n - 1); 57 | } 58 | 59 | template 60 | void build(vector& v, int i, int l, int r) { 61 | if (l == r) { 62 | tree[i] = item(v[l], l, l); 63 | return; 64 | } 65 | int m = (l + r) / 2; 66 | build(v, i * 2 + 1, l, m); 67 | build(v, i * 2 + 2, m + 1, r); 68 | tree[i] = tree[2 * i + 1] + tree[2 * i + 2]; 69 | } 70 | 71 | void push(int i, int l, int r) { 72 | if (l == r) 73 | return; 74 | if (tree[i].is_equal) { 75 | tree[2 * i + 1].equal = tree[i].equal; 76 | tree[2 * i + 1].is_equal = true; 77 | 78 | tree[2 * i + 2].equal = tree[i].equal; 79 | tree[2 * i + 2].is_equal = true; 80 | } else { 81 | if (tree[2 * i + 1].is_equal) { 82 | tree[2 * i + 1].equal += tree[i].mod_sm; 83 | } else { 84 | tree[2 * i + 1].mod_sm += tree[i].mod_sm; 85 | tree[2 * i + 1].mx += tree[i].mod_sm; 86 | tree[2 * i + 1].sm += tree[i].mod_sm * (tree[2 * i + 1].r - tree[2 * i + 1].l + 1); 87 | } 88 | 89 | if (tree[2 * i + 2].is_equal) { 90 | tree[2 * i + 2].equal += tree[i].mod_sm; 91 | } else { 92 | tree[2 * i + 2].mod_sm += tree[i].mod_sm; 93 | tree[2 * i + 2].mx += tree[i].mod_sm; 94 | tree[2 * i + 2].sm += tree[i].mod_sm * (tree[2 * i + 2].r - tree[2 * i + 2].l + 1); 95 | } 96 | } 97 | tree[i].update(tree[2 * i + 1], tree[2 * i + 2]); 98 | } 99 | 100 | template 101 | void set(int l, int r, InType k, int i, int vl, int vr) { 102 | if (l == vl && r == vr) { 103 | tree[i].is_equal = true; 104 | tree[i].equal = k; 105 | return; 106 | } 107 | int m = (vl + vr) / 2; 108 | push(i, vl, vr); 109 | if (r <= m) set(l, r, k, 2 * i + 1, vl, m); 110 | else if (l > m) set(l, r, k, 2 * i + 2, m + 1, vr); 111 | else { 112 | set( l, m, k, 2 * i + 1, vl, m); 113 | set(m + 1, r, k, 2 * i + 2, m + 1, vr); 114 | } 115 | tree[i].update(tree[2 * i + 1], tree[2 * i + 2]); 116 | } 117 | 118 | template 119 | void set(int l, int r, InType k) { 120 | if (l > r) 121 | return; 122 | set(l, r, k, 0, 0, n - 1); 123 | } 124 | 125 | template 126 | void add(int l, int r, InType k, int i, int vl, int vr) { 127 | if (l == vl && r == vr) { 128 | if (tree[i].is_equal) { 129 | tree[i].equal += k; 130 | } else { 131 | tree[i].mod_sm += k; 132 | tree[i].sm += k * (tree[i].r - tree[i].l + 1); 133 | tree[i].mx += k; 134 | } 135 | return; 136 | } 137 | int m = (vl + vr) / 2; 138 | push(i, vl, vr); 139 | if (r <= m) add(l, r, k, 2 * i + 1, vl, m); 140 | else if (l > m) add(l, r, k, 2 * i + 2, m + 1, vr); 141 | else { 142 | add( l, m, k, 2 * i + 1, vl, m); 143 | add(m + 1, r, k, 2 * i + 2, m + 1, vr); 144 | } 145 | tree[i].update(tree[2 * i + 1], tree[2 * i + 2]); 146 | } 147 | 148 | template 149 | void add(int l, int r, InType k) { 150 | if (l > r) 151 | return; 152 | add(l, r, k, 0, 0, n - 1); 153 | } 154 | 155 | auto ask_mx(int l, int r, int i, int vl, int vr) { 156 | if (tree[i].is_equal) { 157 | return tree[i].equal; 158 | } 159 | if (l == vl && r == vr) { 160 | return tree[i].ask_mx(); 161 | } 162 | push(i, vl, vr); 163 | int m = (vl + vr) / 2; 164 | if (r <= m) 165 | return ask_mx(l, r, 2 * i + 1, vl, m); 166 | if (l > m) 167 | return ask_mx(l, r, 2 * i + 2, m + 1, vr); 168 | return max(ask_mx(l, m, 2 * i + 1, vl, m), ask_mx(m + 1, r, 2 * i + 2, m + 1, vr)); 169 | } 170 | 171 | auto ask_mx(int l, int r) { 172 | if (l > r) 173 | return -inf; 174 | return ask_mx(l, r, 0, 0, n - 1); 175 | } 176 | 177 | auto ask_sm(int l, int r, int i, int vl, int vr) { 178 | if (tree[i].is_equal) { 179 | return tree[i].equal * (r - l + 1); 180 | } 181 | if (l == vl && r == vr) { 182 | return tree[i].ask_sm(); 183 | } 184 | push(i, vl, vr); 185 | int m = (vl + vr) / 2; 186 | if (r <= m) 187 | return ask_sm(l, r, 2 * i + 1, vl, m); 188 | if (l > m) 189 | return ask_sm(l, r, 2 * i + 2, m + 1, vr); 190 | return ask_sm(l, m, 2 * i + 1, vl, m) + ask_sm(m + 1, r, 2 * i + 2, m + 1, vr); 191 | } 192 | 193 | auto ask_sm(int l, int r) { 194 | if (l > r) 195 | return 0; 196 | return ask_sm(l, r, 0, 0, n - 1); 197 | } 198 | }; 199 | -------------------------------------------------------------------------------- /old/segtree_sum_modify_sum.cpp: -------------------------------------------------------------------------------- 1 | struct item { 2 | int value = 0; 3 | int l = 0; 4 | int r = 0; 5 | int mod_sm = 0; // modify sum, not sum on [l; r] !!! 6 | 7 | item() {} 8 | item(int value, int l = 0, int r = 0): value(value), l(l), r(r) {} 9 | 10 | int ask() { 11 | return value + mod_sm * (r - l + 1); 12 | } 13 | }; 14 | 15 | item operator + (item a, item b) { 16 | return item(a.ask() + b.ask(), a.l, b.r); 17 | } 18 | 19 | struct segtree { 20 | vector tree; 21 | int n; 22 | 23 | segtree(int size) : segtree(vector(size, 0)) {} 24 | template 25 | segtree(vector v) : n(v.size()), tree(v.size() * 4) { 26 | build(v, 0, 0, n - 1); 27 | } 28 | 29 | template 30 | void build(vector& v, int i, int l, int r) { 31 | if (l == r) { 32 | tree[i] = item(v[l], l, l); 33 | return; 34 | } 35 | int m = (l + r) / 2; 36 | build(v, i * 2 + 1, l, m); 37 | build(v, i * 2 + 2, m + 1, r); 38 | tree[i] = tree[2 * i + 1] + tree[2 * i + 2]; 39 | } 40 | 41 | template 42 | void set(int ind, InType k, int i, int vl, int vr) { 43 | if (vl == vr) { 44 | tree[i].value = k - tree[i].mod_sm; 45 | return; 46 | } 47 | int m = (vl + vr) / 2; 48 | if (ind <= m) set(ind, k - tree[i].mod_sm, 2 * i + 1, vl, m); 49 | else set(ind, k - tree[i].mod_sm, 2 * i + 2, m + 1, vr); 50 | tree[i].value = (tree[2 * i + 1] + tree[2 * i + 2]).value; 51 | } 52 | 53 | template 54 | void set(int ind, InType k) { 55 | set(ind, k, 0, 0, n - 1); 56 | } 57 | 58 | template 59 | void add(int l, int r, InType k, int i, int vl, int vr) { 60 | if (l == vl && r == vr) { 61 | tree[i].mod_sm += k; 62 | return; 63 | } 64 | int m = (vl + vr) / 2; 65 | if (r <= m) add(l, r, k, 2 * i + 1, vl, m); 66 | else if (l > m) add(l, r, k, 2 * i + 2, m + 1, vr); 67 | else { 68 | add( l, m, k, 2 * i + 1, vl, m); 69 | add(m + 1, r, k, 2 * i + 2, m + 1, vr); 70 | } 71 | tree[i].value = (tree[2 * i + 1] + tree[2 * i + 2]).value; 72 | } 73 | 74 | template 75 | void add(int l, int r, InType k) { 76 | add(l, r, k, 0, 0, n - 1); 77 | } 78 | 79 | auto ask(int l, int r, int i, int vl, int vr) { 80 | if (l == vl && r == vr) { 81 | return tree[i].ask(); 82 | } 83 | int m = (vl + vr) / 2; 84 | if (r <= m) 85 | return ask(l, r, 2 * i + 1, vl, m) + tree[i].mod_sm * (r - l + 1); 86 | if (l > m) 87 | return ask(l, r, 2 * i + 2, m + 1, vr) + tree[i].mod_sm * (r - l + 1); 88 | return ask(l, m, 2 * i + 1, vl, m) + ask(m + 1, r, 2 * i + 2, m + 1, vr) + tree[i].mod_sm * (r - l + 1); 89 | } 90 | 91 | auto ask(int l, int r) { 92 | return ask(l, r, 0, 0, n - 1); 93 | } 94 | }; 95 | -------------------------------------------------------------------------------- /old/suffix_array_nlogn.cpp: -------------------------------------------------------------------------------- 1 | // O(n*log) 2 | vector build_suf_array(string s, bool add_dollar = true) { 3 | if (add_dollar) 4 | s += '$'; 5 | int n = s.size(); 6 | vector> cur(s.size()); 7 | for (int i = 0; i < s.size(); ++i) { 8 | cur[i] = make_pair(i, 0); 9 | } 10 | sort(cur.begin(), cur.end(), [&](const pair &a, const pair &b) { 11 | return s[a.first] < s[b.first]; 12 | }); 13 | for (int i = 1; i < s.size(); ++i) { 14 | cur[i].second = cur[i - 1].second + (s[cur[i].first] != s[cur[i - 1].first]); 15 | } 16 | vector ind(n); 17 | vector count(n); 18 | vector> tmp(n); 19 | for (int k = 1; k <= n; k *= 2) { 20 | for (int i = 0; i < n; ++i) { 21 | ind[cur[i].first] = cur[i].second; 22 | } 23 | for (int i = 0; i < n; ++i) { 24 | cur[i].first = (cur[i].first - k + n) % n; 25 | cur[i].second = ind[cur[i].first]; 26 | } 27 | count.assign(count.size(), 0); 28 | for (int i = 0; i < n; ++i) { 29 | count[cur[i].second]++; 30 | } 31 | for (int i = 1; i < n; ++i) 32 | count[i] += count[i - 1]; 33 | for (int i = 0; i < n; ++i) 34 | --count[i]; 35 | for (int i = n - 1; i >= 0; --i) { 36 | tmp[count[cur[i].second]--] = make_pair(cur[i].first, 0); 37 | } 38 | swap(cur, tmp); 39 | for (int i = 1; i < n; ++i) { 40 | cur[i].second = cur[i - 1].second; 41 | if (ind[cur[i].first] != ind[cur[i - 1].first] || ind[(cur[i].first + k) % n] != ind[(cur[i - 1].first + k) % n]) 42 | ++cur[i].second; 43 | } 44 | } 45 | vector res(n); 46 | for (int i = 0; i < cur.size(); ++i) { 47 | res[i] = cur[i].first; 48 | } 49 | 50 | if (add_dollar) 51 | res.erase(res.begin()); 52 | 53 | return res; 54 | } 55 | 56 | vector build_lcp(const string &s, const vector &suf_array) { 57 | int n = s.size(); 58 | vector lcp(n - 1); 59 | vector ind(n); 60 | for (int i = 0; i < n; ++i) { 61 | ind[suf_array[i]] = i; 62 | } 63 | int last = 1; 64 | for (int i = 0; i < n; ++i) { 65 | last = max(last - 1, 0); 66 | int i_cur = i; 67 | if (ind[i_cur] != 0) { 68 | int i_prev = suf_array[ind[i_cur] - 1]; 69 | while (i_cur + last < s.size() && i_prev + last < s.size() && s[i_cur + last] == s[i_prev + last]) 70 | ++last; 71 | lcp[ind[i_cur] - 1] = last; 72 | } 73 | } 74 | return lcp; 75 | } 76 | -------------------------------------------------------------------------------- /point.cpp: -------------------------------------------------------------------------------- 1 | struct point { 2 | ld x, y; 3 | 4 | point(ld x = 0, ld y = 0): x(x), y(y) {} 5 | point(point a, point b) { 6 | x = b.x - a.x; 7 | y = b.y - a.y; 8 | } 9 | 10 | ld dist(point b) const { 11 | return sqrt((b.x - x) * (b.x - x) + (b.y - y) * (b.y - y)); 12 | } 13 | ld sdist(point b) const { 14 | return ((b.x - x) * (b.x - x) + (b.y - y) * (b.y - y)); 15 | } 16 | ld len() const { 17 | return sqrt(x * x + y * y); 18 | } 19 | ld slen() const { 20 | return x * x + y * y; 21 | } 22 | point ort() const { 23 | return point(-y, x); 24 | } 25 | ld dp(point p) const { 26 | return x * p.x + y * p.y; 27 | } 28 | ld cp(point p) const { 29 | return x * p.y - y * p.x; 30 | } 31 | 32 | point operator + (point a) const { 33 | return point(a.x + x, a.y + y); 34 | } 35 | point operator - (point a) const { 36 | return point(x - a.x, y - a.y); 37 | } 38 | point operator * (ld k) const { 39 | return point(x * k, y * k); 40 | } 41 | point operator / (ld k) const { 42 | return point(x / k, y / k); 43 | } 44 | 45 | point& norm() { 46 | ld d = len(); 47 | if (d != 0) { 48 | x /= d; 49 | y /= d; 50 | } 51 | return *this; 52 | } 53 | }; 54 | ostream& operator << (ostream& o, const point &p) { 55 | return o << "(" << p.x << ", " << p.y << ")"; 56 | } 57 | -------------------------------------------------------------------------------- /point3d.cpp: -------------------------------------------------------------------------------- 1 | struct Pt { 2 | long double x, y, z; 3 | 4 | Pt() : x(0), y(0), z(0) {} 5 | Pt(long double x, long double y, long double z) : x(x), y(y), z(z) {} 6 | 7 | Pt operator - (Pt b) { 8 | return Pt(x - b.x, y - b.y, z - b.z); 9 | } 10 | Pt operator + (Pt b) { 11 | return Pt(x + b.x, y + b.y, z + b.z); 12 | } 13 | Pt operator * (long double k) { 14 | return Pt(x * k, y * k, z * k); 15 | } 16 | Pt operator / (long double k) { 17 | return Pt(x / k, y / k, z / k); 18 | } 19 | 20 | long double len() { 21 | return sqrt(x * x + y * y + z * z); 22 | } 23 | 24 | long double dp(Pt b) { 25 | return x * b.x + y * b.y + z * b.z; 26 | } 27 | 28 | Pt cp(Pt b) { 29 | return Pt(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x); 30 | } 31 | }; 32 | long double tp(Pt a, Pt b, Pt c) { 33 | return a.dp(b.cp(c)); 34 | } 35 | string to_string(Pt a) { 36 | return "(" + to_string(a.x) + ", " + to_string(a.y) + ", " + to_string(a.z) + ")"; 37 | } 38 | ostream& operator << (ostream& o, const Pt &p) { 39 | return o << to_string(p); 40 | } 41 | struct Tr { 42 | Pt a, b, c; 43 | Pt norm; 44 | 45 | Tr() {} 46 | Tr(Pt _a, Pt _b, Pt _c, Pt _norm = Pt(0, 0, 0)) : a(_a), b(_b), c(_c), norm(_norm) { 47 | // if (a.i > b.i) 48 | // swap(a, b); 49 | // if (a.i > c.i) 50 | // swap(a, c); 51 | // if (b.i > c.i) 52 | // swap(b, c); 53 | } 54 | }; 55 | -------------------------------------------------------------------------------- /pow_mod.cpp: -------------------------------------------------------------------------------- 1 | long long mpow(long long a, long long p, long long mod = mod) { 2 | long long res = 1; 3 | while (p) { 4 | if (p & 1) res = res * a % mod; 5 | p >>= 1; 6 | a = a * a % mod; 7 | } 8 | return res; 9 | } 10 | 11 | ll inv(ll k, ll mod = mod) { 12 | return mpow(k, mod - 2, mod); 13 | } 14 | -------------------------------------------------------------------------------- /pow_no_mod.cpp: -------------------------------------------------------------------------------- 1 | long long fpow(long long a, long long p) { 2 | long long res = 1; 3 | while (p) { 4 | if (p & 1) res = res * a; 5 | p >>= 1; 6 | a = a * a; 7 | } 8 | return res; 9 | } 10 | -------------------------------------------------------------------------------- /precursive.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct PRecursive { 3 | // n = size of recurrence = size of base (initial terms) 4 | // m = size of sequence given to find_recurrence() 5 | // k = max_degtree given to find_recurrence() 6 | 7 | // find_recurrence() works in O(m*k^2*n^3) 8 | // nth(ind) works in O(ind*k*n) 9 | 10 | // it is possible to use nth() with precalculated recurrence, 11 | // use set_recurrence and set_base for that 12 | 13 | // rec should satisfy a[i] = (sum_{j=0..rec.size()-1} a[i-j-1] * sum_{k=0..rec[j+1].size()-1} rec[j+1][k]*i^k) 14 | // / (sum_{k=0..rec[0].size()-1} rec[0][k]*i^k) 15 | 16 | // pass validate = x to use last x elements of a sequence for validation 17 | // use print() to print recurrence relation in a readable form 18 | 19 | vector> rec; 20 | vector base; 21 | vector cache; 22 | 23 | PRecursive() {} 24 | 25 | // this can be used with initializer_list 26 | void set_recurrence(const vector> &v) { 27 | rec = v; 28 | } 29 | template 30 | void set_recurrence(const vector> &v) { 31 | rec.clear(); 32 | for (const auto& l : v) 33 | rec.emplace_back(l.begin(), l.end()); 34 | } 35 | 36 | void set_base(const vector &v) { 37 | base = v; 38 | } 39 | template 40 | void set_base(const vector &v) { 41 | base.assign(v.begin(), v.end()); 42 | } 43 | 44 | void find_recurrence(const vector& v, int max_degree, int validate = 0) { 45 | // just gaussian elimination 46 | for (int sz = 0;; ++sz) { 47 | vector> A; 48 | for (int i = sz; i + validate < v.size(); ++i) { 49 | vector row((sz + 1) * (max_degree + 1) + 1); 50 | for (int j = 0; j <= sz; ++j) { 51 | T pw = 1; 52 | for (int k = 0; k <= max_degree; ++k) { 53 | row[k * (sz + 1) + j] = v[i - j] * pw * (j == 0 ? -1 : 1); 54 | pw *= i; 55 | } 56 | } 57 | // largest degree in denominator has to be 1, otherwise all 0-s is a solution 58 | swap(row[max_degree * (sz + 1)], row.back()); 59 | row.back() = -row.back(); 60 | row.erase(row.begin() + max_degree * (sz + 1)); 61 | A.push_back(std::move(row)); 62 | } 63 | 64 | assert(!A.empty()); 65 | int last = 0; 66 | for (int col = 0; last < A.size() && col + 1 < A[0].size(); ++col) { 67 | if (A[last][col] == 0) { 68 | for (int j = last + 1; j < A.size(); ++j) { 69 | if (A[j][col] != 0) { 70 | swap(A[j], A[last]); 71 | break; 72 | } 73 | } 74 | } 75 | if (A[last][col] == 0) continue; 76 | for (int j = last + 1; j < A.size(); ++j) { 77 | if (A[j][col] == 0) continue; 78 | T coef = A[j][col] / A[last][col]; 79 | for (int k = col; k < A[0].size(); ++k) { 80 | A[j][k] -= A[last][k] * coef; 81 | } 82 | } 83 | ++last; 84 | } 85 | 86 | bool has_solution = true; 87 | for (int i = 0; i < A.size(); ++i) { 88 | if (A[i].back() != 0) has_solution = false; 89 | for (int j = 0; j + 1 < A[i].size(); ++j) 90 | if (A[i][j] != 0) 91 | has_solution = true; 92 | if (!has_solution) break; 93 | } 94 | if (!has_solution) continue; 95 | vector solution(A[0].size() - 1); 96 | for (int i = (int)A.size() - 1; i >= 0; --i) { 97 | int j = 0; 98 | while (j < A[i].size() && A[i][j] == 0) ++j; 99 | if (j == A[i].size()) continue; 100 | T res = A[i].back(); 101 | for (int k = j + 1; k + 1 < A[i].size(); ++k) 102 | res -= A[i][k] * solution[k]; 103 | solution[j] = res / A[i][j]; 104 | } 105 | solution.insert(solution.begin() + max_degree * (sz + 1), 1); 106 | rec.resize(sz + 1); 107 | for (int i = 0; i <= sz; ++i) { 108 | rec[i].resize(max_degree + 1); 109 | for (int j = 0; j <= max_degree; ++j) { 110 | rec[i][j] = solution[j * (sz + 1) + i]; 111 | } 112 | } 113 | 114 | // remove largest degrees with zeros 115 | while (true) { 116 | bool has_non_zero = false; 117 | for (const auto& r : rec) 118 | if (r.back() != 0) 119 | has_non_zero = true; 120 | if (has_non_zero) break; 121 | for (auto& r : rec) 122 | r.pop_back(); 123 | } 124 | 125 | base.assign(v.begin(), v.begin() + sz); 126 | cache = base; 127 | for (int i = (int)v.size() - validate; i < v.size(); ++i) { 128 | T correct = v[i]; 129 | T calculated = nth(i); 130 | if (correct != calculated) { 131 | cerr << "validation failed at index " << i << ": correct is " << correct << ", calculated is " << calculated << endl; 132 | print(); 133 | assert(correct == calculated); 134 | } 135 | } 136 | break; 137 | } 138 | } 139 | template 140 | void find_recurrence(const vector &v, int max_degree, int validate = 0) { 141 | find_recurrence(vector(v.begin(), v.end()), max_degree, validate); 142 | } 143 | 144 | T nth(int ind) { 145 | while (ind >= cache.size()) { 146 | T res = 0; 147 | for (int i = 1; i < rec.size(); ++i) { 148 | T pw = 1; 149 | for (int j = 0; j < rec[i].size(); ++j) { 150 | res += cache[cache.size() - i] * rec[i][j] * pw; 151 | pw *= T(cache.size()); 152 | } 153 | } 154 | T den = 0; 155 | T pw = 1; 156 | for (int j = 0; j < rec[0].size(); ++j) { 157 | den += rec[0][j] * pw; 158 | pw *= T(cache.size()); 159 | } 160 | cache.push_back(res / den); 161 | } 162 | return cache[ind]; 163 | } 164 | 165 | void print() const { 166 | string recs = ""; 167 | auto get_poly = [&](int i) -> string { 168 | stringstream poly; 169 | for (int j = 0; j < rec[i].size(); ++j) { 170 | if (rec[i][j] != 0) { 171 | if (!poly.str().empty()) poly << '+'; 172 | poly << rec[i][j]; 173 | if (j) { 174 | poly << "n"; 175 | if (j > 1) 176 | poly << '^' << j; 177 | } 178 | } 179 | } 180 | return poly.str(); 181 | }; 182 | for (int i = 1; i < rec.size(); ++i) { 183 | string polys = get_poly(i); 184 | if (polys.empty()) continue; 185 | polys = "(" + polys + ")*a[n-" + to_string(i) + "]"; 186 | if (!recs.empty()) recs += " + "; 187 | recs += polys; 188 | } 189 | if (recs.empty()) recs = "0"; 190 | cerr << '(' << get_poly(0) << ")*a[n] = " << recs << '\n'; 191 | cerr << "base: ["; 192 | for (int i = 0; i < base.size(); ++i) { 193 | if (i) cerr << ", "; 194 | cerr << base[i]; 195 | } 196 | cerr << "]" << endl; 197 | } 198 | }; 199 | -------------------------------------------------------------------------------- /prefix_function.cpp: -------------------------------------------------------------------------------- 1 | template 2 | vector prefix_function(const T &s) { 3 | int n = s.size(); 4 | vector p(n, 0); 5 | for (int i = 1; i < n; ++i) { 6 | p[i] = (s[i] == s[0]); 7 | int x = i; 8 | while (x) { 9 | x = p[x - 1]; 10 | if (s[x] == s[i]) { 11 | p[i] = x + 1; 12 | break; 13 | } 14 | } 15 | } 16 | return p; 17 | } 18 | -------------------------------------------------------------------------------- /prime_count.cpp: -------------------------------------------------------------------------------- 1 | // works in 250ms for n=1e11, in ~1s for n=1e12 2 | // O(n^2/3 logn) 3 | // just call count_primes(n) 4 | struct _count_primes_struct_t_ { 5 | vector primes; 6 | vector mnprimes; 7 | ll ans; 8 | ll y; 9 | vector, char>> queries; 10 | 11 | void phi(ll n, int a, int sign = 1) { 12 | if (n == 0) return; 13 | if (a == -1) { 14 | ans += n * sign; 15 | return; 16 | } 17 | if (n <= y) { 18 | queries.emplace_back(make_pair(n, a), sign); 19 | return; 20 | } 21 | phi(n, a - 1, sign); 22 | phi(n / primes[a], a - 1, -sign); 23 | } 24 | 25 | struct fenwick { 26 | vector tree; 27 | int n; 28 | 29 | fenwick(int n = 0) : n(n) { 30 | tree.assign(n, 0); 31 | } 32 | 33 | void add(int i, int k) { 34 | for (; i < n; i = (i | (i + 1))) 35 | tree[i] += k; 36 | } 37 | 38 | int ask(int r) { 39 | int res = 0; 40 | for (; r >= 0; r = (r & (r + 1)) - 1) 41 | res += tree[r]; 42 | return res; 43 | } 44 | }; 45 | 46 | ll count_primes(ll n) { 47 | y = pow(n, 0.64); 48 | if (n < 100) y = n; 49 | primes.clear(); 50 | mnprimes.assign(y + 1, -1); 51 | ans = 0; 52 | for (int i = 2; i <= y; ++i) { 53 | if (mnprimes[i] == -1) { 54 | mnprimes[i] = primes.size(); 55 | primes.push_back(i); 56 | } 57 | for (int k = 0; k < primes.size(); ++k) { 58 | int j = primes[k]; 59 | if (i * j > y) break; 60 | mnprimes[i * j] = k; 61 | if (i % j == 0) break; 62 | } 63 | } 64 | if (n < 100) return primes.size(); 65 | ll s = n / y; 66 | 67 | // pi(n) -- prime counting function 68 | // phi(n, a) -- number of integers from 1 to n which are not divisible by any prime from 0-th to a-th (p0=2) 69 | 70 | // pi(n) = phi(n, cbrt(n)) + pi(cbrt(n)) - F, where F is the number of composite number of 71 | // the form p*q, where p >= q >= cbrt(n) (can be counted with two pointers) 72 | 73 | // pi(cbrt(n)) 74 | for (int p : primes) { 75 | if (p > s) break; 76 | ans++; 77 | } 78 | 79 | // F 80 | int ssz = ans; 81 | int ptr = primes.size() - 1; 82 | for (int i = ssz; i < primes.size(); ++i) { 83 | while (ptr >= i && (ll)primes[i] * primes[ptr] > n) 84 | --ptr; 85 | if (ptr < i) break; 86 | ans -= ptr - i + 1; 87 | } 88 | 89 | // phi 90 | // store all queries phi(m, a) with m < n^2/3, calculate later with fenwick (sum in a rectangle) 91 | phi(n, ssz - 1); 92 | sort(queries.begin(), queries.end()); 93 | int ind = 2; 94 | int sz = primes.size(); 95 | // the order will be reversed, because prefix sum in a fenwick is just one query 96 | fenwick fw(sz); 97 | for (auto [na, sign] : queries) { 98 | auto [n, a] = na; 99 | while (ind <= n) 100 | fw.add(sz - 1 - mnprimes[ind++], 1); 101 | ans += (fw.ask(sz - a - 2) + 1) * sign; 102 | } 103 | queries.clear(); 104 | return ans - 1; 105 | } 106 | } _count_primes_struct_; 107 | 108 | ll count_primes(ll n) { 109 | return _count_primes_struct_.count_primes(n); 110 | } 111 | -------------------------------------------------------------------------------- /prime_count_slow.cpp: -------------------------------------------------------------------------------- 1 | // works in <1s for 1e11, 4s for 1e12 2 | // O(n^3/4) 3 | ll count_primes(ll n) { 4 | auto f = [&](ll n) { 5 | // should be multiplicative (f(ab) = f(a)f(b)), 6 | // the result will be sum f(p) over all primes 7 | return 1; 8 | }; 9 | auto pref = [&](ll n) { 10 | // should return sum_{i=1..n} f(i) 11 | return n; 12 | }; 13 | 14 | vector v; 15 | v.reserve((int)sqrt(n) * 2 + 20); 16 | ll sq; 17 | { 18 | ll k = 1; 19 | for (; k * k <= n; ++k) { 20 | v.pb(k); 21 | } 22 | --k; 23 | sq = k; 24 | if (k * k == n) --k; 25 | for (; k >= 1; --k) { 26 | v.pb(n / k); 27 | } 28 | } 29 | vector s(v.size()); 30 | for (int i = 0; i < s.size(); ++i) 31 | s[i] = pref(v[i]) - 1; 32 | auto geti = [&](ll x) { 33 | if (x <= sq) return (int)x - 1; 34 | else return (int)(v.size() - (n / x)); 35 | }; 36 | for (ll p = 2; p * p <= n; ++p) { 37 | if (s[p - 1] != s[p - 2]) { 38 | ll sp = s[p - 2]; 39 | ll p2 = p * p; 40 | for (int i = (int)v.size() - 1; i >= 0; --i) { 41 | if (v[i] < p2) { 42 | break; 43 | } 44 | s[i] -= (s[geti(v[i] / p)] - sp) * f(p); 45 | } 46 | } 47 | } 48 | return s.back(); 49 | } 50 | -------------------------------------------------------------------------------- /print_int128.cpp: -------------------------------------------------------------------------------- 1 | string to_string(__int128 x) { 2 | if (x == 0) return "0"; 3 | __uint128_t k = x; 4 | if (k == (((__uint128_t)1) << 127)) return "-170141183460469231731687303715884105728"; 5 | string result; 6 | if (x < 0) { 7 | result += "-"; 8 | x *= -1; 9 | } 10 | string t; 11 | while (x) { 12 | t.push_back('0' + x % 10); 13 | x /= 10; 14 | } 15 | reverse(t.begin(), t.end()); 16 | return result + t; 17 | } 18 | 19 | ostream &operator << (ostream &o, __int128 x) { 20 | return o << to_string(x); 21 | } 22 | -------------------------------------------------------------------------------- /random.cpp: -------------------------------------------------------------------------------- 1 | mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()); 2 | ll rnd (ll l, ll r) { return (ll)(rng() % (r - l + 1)) + l; } 3 | ll rnd (ll r) { return rng() % r; } 4 | ll rnd () { return rng(); } 5 | ld rndf() { return (ld)rng() / (ld)ULLONG_MAX; } 6 | ld rndf(ld l, ld r) { return rndf() * (r - l) + l; } 7 | -------------------------------------------------------------------------------- /ranges.cpp: -------------------------------------------------------------------------------- 1 | namespace ranges { 2 | // waiting for C++ 20 3 | 4 | template struct _range { 5 | I first, last; 6 | explicit _range(const I &first, const I &last) : first(first), last(last) {} 7 | 8 | I begin() const { return first; } 9 | I end() const { return last; } 10 | 11 | auto rbegin() const { return make_reverse_iterator(last ); } 12 | auto rend() const { return make_reverse_iterator(first); } 13 | 14 | int size() const { return distance(first, last); } 15 | bool empty() const { return first == last; } 16 | }; 17 | template _range range(const I &first, const I &last) { return _range(first, last); } 18 | template auto range(C &c) { return _range(c.begin(), c.end()); } 19 | 20 | template _range> reversed(const _range &r) { return range(make_reverse_iterator(r.end()), make_reverse_iterator(r.begin())); } 21 | // not const reference to replace UB in reversed(f()) with CE 22 | template auto reversed(T &v) { return range(v.rbegin(), v.rend()); } 23 | 24 | // comparison operators 25 | template 26 | bool operator < (const _range &a, const _range &b) { 27 | auto ita = a.begin(); auto itb = b.begin(); 28 | for (; ita != a.end() && itb != b.end(); ++ita, ++itb) 29 | if (*ita != *itb) 30 | return *ita < *itb; 31 | return ita == a.end() && itb != b.end(); 32 | } 33 | template bool operator > (const _range &a, const _range &b) { return b < a; } 34 | template bool operator <= (const _range &a, const _range &b) { return !(a > b); } 35 | template bool operator >= (const _range &a, const _range &b) { return !(a < b); } 36 | 37 | // equality operators, O(1) for random_access_iterators with different range lengths 38 | template 39 | bool operator_eq_brute(const _range &a, const _range &b) { 40 | auto ita = a.begin(); auto itb = b.begin(); 41 | for (; ita != a.end() && itb != b.end(); ++ita, ++itb) 42 | if (*ita != *itb) 43 | return false; 44 | return ita == a.end() && itb == b.end(); 45 | } 46 | template::iterator_category>::value && 48 | is_base_of::iterator_category>::value>::type* = nullptr> 49 | bool operator == (const _range &a, const _range &b) { 50 | if (a.size() != b.size()) return false; 51 | return operator_eq_brute(a, b); 52 | } 53 | template::iterator_category>::value || 55 | !is_base_of::iterator_category>::value>::type* = nullptr> 56 | bool operator == (const _range &a, const _range &b) { 57 | return operator_eq_brute(a, b); 58 | } 59 | template bool operator != (const _range &a, const _range &b) { return !(a == b); } 60 | 61 | #define unrange(r) (r).first, (r).last 62 | 63 | } 64 | using namespace ranges; 65 | -------------------------------------------------------------------------------- /rational.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct Rational { 3 | T a, b; 4 | Rational(T a = 0, T b = 1) : a(a), b(b) { norm(); } 5 | 6 | T floor() const { T res = a / b; if (a < 0 && a != b * res) --res; return res; } 7 | T ceil() const { T res = a / b; if (a > 0 && a != b * res) ++res; return res; } 8 | 9 | friend Rational& operator += ( Rational &n, const Rational &m) { return n = Rational(n.a * m.b + n.b * m.a, n.b * m.b); } 10 | friend Rational operator + (const Rational &n, const Rational &m) { auto res = n; return res += m; } 11 | friend Rational& operator -= ( Rational &n, const Rational &m) { return n = Rational(n.a * m.b - n.b * m.a, n.b * m.b); } 12 | friend Rational operator - (const Rational &n, const Rational &m) { auto res = n; return res -= m; } 13 | friend Rational operator - (const Rational &n) { return Rational{-n.a, n.b}; } 14 | friend Rational& operator *= ( Rational &n, const Rational &m) { return n = Rational(n.a * m.a, n.b * m.b); } 15 | friend Rational operator * (const Rational &n, const Rational &m) { auto res = n; return res *= m; } 16 | friend Rational& operator /= ( Rational &n, const Rational &m) { return n = Rational(n.a * m.b, n.b * m.a); } 17 | friend Rational operator / (const Rational &n, const Rational &m) { auto res = n; return res /= m; } 18 | 19 | // doesn't overflow 20 | friend bool operator < (Rational n, Rational m) { 21 | while (true) { 22 | T a = n.floor(), b = m.floor(); if (a != b) return a < b; 23 | n -= a; m -= b; 24 | if (n.b == m.b) return (n.a < m.a); 25 | if (n.a == 0) return true; else if (m.a == 0) return false; 26 | swap(n, m); swap(n.a, n.b); swap(m.a, m.b); 27 | } 28 | return false; 29 | } 30 | // maybe faster? 31 | // friend bool operator < (const Rational &n, const Rational &m) { return n.a * m.b < n.b * m.a; } 32 | friend bool operator <= (const Rational &n, const Rational &m) { return !(m < n); } 33 | friend bool operator > (const Rational &n, const Rational &m) { return m < n ; } 34 | friend bool operator >= (const Rational &n, const Rational &m) { return !(n < m); } 35 | 36 | friend bool operator == (const Rational &n, const Rational &m) { return n.a == m.a && n.b == m.b; } 37 | friend bool operator != (const Rational &n, const Rational &m) { return n.a != m.a || n.b != m.b; } 38 | 39 | static T gcd(T a, T b) { 40 | while (b != 0) { 41 | a %= b; 42 | swap(a, b); 43 | } 44 | return a; 45 | } 46 | 47 | void norm() { 48 | if (b < 0) { 49 | a = -a; 50 | b = -b; 51 | } 52 | T d = gcd((a < 0 ? -a : a), b); 53 | a /= d; 54 | b /= d; 55 | } 56 | }; 57 | 58 | template 59 | Rational pow(Rational a, ll p) { 60 | Rational res = 1; 61 | while (p) { 62 | if (p & 1) res *= a; 63 | a *= a; 64 | p >>= 1; 65 | } 66 | return res; 67 | } 68 | 69 | template ostream& operator << (ostream &o, const Rational &m) { return o << m.a << '/' << m.b; } 70 | template istream& operator >> (istream &i, Rational &m) { T a, b = 1; i >> a; if (i.peek() == '/') i.get(), i >> b; m = Rational(a, b); return i; } 71 | -------------------------------------------------------------------------------- /scc.cpp: -------------------------------------------------------------------------------- 1 | vector scc(vector>& g) { 2 | int n = g.size(); 3 | vector topsort; topsort.reserve(n); 4 | vector u(n, false); 5 | function scc_dfs1 = [&](int v) { 6 | u[v] = true; 7 | for (auto k : g[v]) 8 | if (!u[k]) 9 | scc_dfs1(k); 10 | topsort.push_back(v); 11 | }; 12 | for (int i = 0; i < n; ++i) 13 | if (!u[i]) 14 | scc_dfs1(i); 15 | vector> gi(n); 16 | for (int i = 0; i < n; ++i) 17 | for (auto j : g[i]) 18 | gi[j].push_back(i); 19 | int color = 0; 20 | vector comp(n, -1); 21 | reverse(topsort.begin(), topsort.end()); 22 | function scc_dfs2 = [&](int v, int color) { 23 | comp[v] = color; 24 | for (auto k : gi[v]) 25 | if (comp[k] == -1) 26 | scc_dfs2(k, color); 27 | }; 28 | for (auto v : topsort) 29 | if (comp[v] == -1) 30 | scc_dfs2(v, color++); 31 | return comp; 32 | } 33 | -------------------------------------------------------------------------------- /segtree_.cpp: -------------------------------------------------------------------------------- 1 | namespace segtree_ns { 2 | struct item { 3 | template 4 | void init(const T &t, int l, int r) { 5 | } 6 | 7 | void update(const item &first, const item &second, int l, int r) { 8 | } 9 | 10 | static item merge(const item &first, const item &second, int l, int r) { 11 | item res; 12 | res.update(first, second, l, r); // careful with different lengths 13 | return res; 14 | } 15 | }; 16 | OSTREAM(item); 17 | 18 | struct segtree { 19 | vector tree; 20 | int n = 1; 21 | 22 | segtree(int n = 1) : n(n) { 23 | tree.resize(1 << (__lg(max(1, n - 1)) + 2)); 24 | } 25 | 26 | template 27 | segtree(const vector& v) { 28 | build(v); 29 | } 30 | 31 | template 32 | void build(const vector &v, int i, int l, int r) { 33 | if (l == r) { 34 | tree[i].init(v[l], l, r); 35 | return; 36 | } 37 | int m = (l + r) >> 1; 38 | build(v, i * 2 + 1, l, m); 39 | build(v, i * 2 + 2, m + 1, r); 40 | tree[i].update(tree[i * 2 + 1], tree[i * 2 + 2], l, r); 41 | } 42 | 43 | template 44 | void build(const vector &v) { 45 | n = v.size(); 46 | tree.assign(1 << (__lg(max(1, n - 1)) + 2), item()); 47 | build(v, 0, 0, n - 1); 48 | } 49 | 50 | item ask(int l, int r, int i, int vl, int vr) { 51 | if (l == vl && r == vr) { 52 | return tree[i]; 53 | } 54 | int m = (vl + vr) >> 1; 55 | if (r <= m) { 56 | return ask(l, r, i * 2 + 1, vl, m); 57 | } else if (m < l) { 58 | return ask(l, r, i * 2 + 2, m + 1, vr); 59 | } else { 60 | return item::merge(ask(l, m, i * 2 + 1, vl, m), ask(m + 1, r, i * 2 + 2, m + 1, vr), l, r); 61 | } 62 | } 63 | 64 | item ask(int l, int r) { 65 | l = max(l, 0); r = min(r, n - 1); 66 | if (l > r) return item(); 67 | return ask(l, r, 0, 0, n - 1); 68 | } 69 | 70 | template 71 | void set(int ind, const T &t) { 72 | static array, 30> st; 73 | int l = 0, r = n - 1, i = 0; 74 | int ptr = -1; 75 | while (l != r) { 76 | st[++ptr] = {l, r}; 77 | int m = (l + r) >> 1; 78 | if (ind <= m) { 79 | i = i * 2 + 1; 80 | r = m; 81 | } else { 82 | i = i * 2 + 2; 83 | l = m + 1; 84 | } 85 | } 86 | tree[i].init(t, l, r); 87 | while (i != 0) { 88 | i = (i - 1) / 2; 89 | tree[i].update(tree[i * 2 + 1], tree[i * 2 + 2], st[ptr].first, st[ptr].second); 90 | --ptr; 91 | } 92 | } 93 | }; 94 | 95 | ostream& operator << (ostream& o, segtree& tree) { 96 | #ifdef HOME 97 | vector items; 98 | for (int i = 0; i < tree.n; ++i) 99 | items.push_back(tree.ask(i, i)); 100 | const bool print_horizontal = true; 101 | if (print_horizontal) { 102 | for (int i = 0; i < items.size(); ++i) { 103 | if (i != 0) o << " "; 104 | o << items[i]; 105 | } 106 | } else { 107 | for (int i = 0; i < items.size(); ++i) { 108 | o << '\n' << string(10, ' '); 109 | o << items[i]; 110 | } 111 | } 112 | #endif 113 | return o; 114 | } 115 | 116 | } 117 | using namespace segtree_ns; 118 | -------------------------------------------------------------------------------- /segtree_beats.cpp: -------------------------------------------------------------------------------- 1 | namespace segtree_ns { 2 | 3 | // supports min=, max=, += on a segment, maintains sum on a segment 4 | 5 | const ll inf = 1e18; 6 | 7 | struct mod_max { ll v; }; 8 | struct mod_min { ll v; }; 9 | struct mod_add { ll v; }; 10 | 11 | struct item { 12 | ll mn1, mn2, mx1, mx2, sm; 13 | ll cmn1, cmx1; 14 | mod_add madd{0}; 15 | 16 | template 17 | void init(const T &t, int l, int r) { 18 | mn1 = mx1 = t; 19 | mn2 = inf; 20 | mx2 = -inf; 21 | cmn1 = cmx1 = r - l + 1; 22 | sm = t * cmn1; 23 | } 24 | 25 | void update(const item &first, const item &second, int l, int r) { 26 | sm = first.sm + second.sm; 27 | 28 | mn1 = min(first.mn1, second.mn1); 29 | if (first.mn1 < second.mn1) cmn1 = first.cmn1; 30 | else if (first.mn1 > second.mn1) cmn1 = second.cmn1; 31 | else cmn1 = first.cmn1 + second.cmn1; 32 | 33 | mx1 = max(first.mx1, second.mx1); 34 | if (first.mx1 > second.mx1) cmx1 = first.cmx1; 35 | else if (first.mx1 < second.mx1) cmx1 = second.cmx1; 36 | else cmx1 = first.cmx1 + second.cmx1; 37 | 38 | mn2 = min(mn1 == first.mn1 ? first.mn2 : first.mn1, 39 | mn1 == second.mn1 ? second.mn2 : second.mn1); 40 | mx2 = max(mx1 == first.mx1 ? first.mx2 : first.mx1, 41 | mx1 == second.mx1 ? second.mx2 : second.mx1); 42 | } 43 | 44 | static item merge(const item &first, const item &second, int l, int r) { 45 | item res; 46 | res.update(first, second, l, r); // careful with different lengths 47 | return res; 48 | } 49 | 50 | // return true if modification can be applied 51 | bool modify(const mod_add &md, int l, int r) { 52 | ll m = md.v; 53 | sm += m * (r - l + 1); 54 | mn1 += m; 55 | mn2 += m; 56 | mx1 += m; 57 | mx2 += m; 58 | madd.v += m; 59 | return true; 60 | } 61 | 62 | // return true if modification can be applied 63 | bool modify(const mod_min &md, int l, int r) { 64 | ll m = md.v; 65 | 66 | if (m >= mx1) 67 | return true; 68 | 69 | if (m <= mn1) { 70 | init(m, l, r); 71 | return true; 72 | } 73 | if (m > mx2) { 74 | sm += cmx1 * (m - mx1); 75 | if (mx1 == mn2) 76 | mn2 = m; 77 | mx1 = m; 78 | return true; 79 | } 80 | return false; 81 | } 82 | 83 | // return true if modification can be applied 84 | bool modify(const mod_max &md, int l, int r) { 85 | ll m = md.v; 86 | 87 | if (m <= mn1) 88 | return true; 89 | 90 | if (m >= mx1) { 91 | init(m, l, r); 92 | return true; 93 | } 94 | if (m < mn2) { 95 | sm += cmn1 * (m - mn1); 96 | if (mn1 == mx2) 97 | mx2 = m; 98 | mn1 = m; 99 | return true; 100 | } 101 | return false; 102 | } 103 | 104 | void push(item &first, item &second, int l, int r) { 105 | int m = (l + r) / 2; 106 | if (mn1 == mx1) { 107 | first.init(mn1, l, m); 108 | second.init(mn1, m + 1, r); 109 | } else { 110 | first.modify(madd, l, m); 111 | first.modify(mod_min{mx1}, l, m); 112 | first.modify(mod_max{mn1}, l, m); 113 | second.modify(madd, m + 1, r); 114 | second.modify(mod_min{mx1}, m + 1, r); 115 | second.modify(mod_max{mn1}, m + 1, r); 116 | } 117 | madd.v = 0; 118 | } 119 | }; 120 | 121 | string to_string(const item &i) { 122 | stringstream ss; 123 | ss << "[" << "]"; 124 | return ss.str(); 125 | } 126 | ostream& operator << (ostream &o, const item &i) { 127 | return o << to_string(i); 128 | } 129 | 130 | struct segtree { 131 | vector tree; 132 | int n = 1; 133 | 134 | segtree(int n = 1) : n(n) { 135 | tree.resize(1 << (__lg(max(1, n - 1)) + 2)); 136 | } 137 | 138 | template 139 | segtree(const vector& v) { 140 | build(v); 141 | } 142 | 143 | template 144 | void build(const vector &v, int i, int l, int r) { 145 | if (l == r) { 146 | tree[i].init(v[l], l, r); 147 | return; 148 | } 149 | int m = (l + r) >> 1; 150 | build(v, i * 2 + 1, l, m); 151 | build(v, i * 2 + 2, m + 1, r); 152 | tree[i].update(tree[i * 2 + 1], tree[i * 2 + 2], l, r); 153 | } 154 | 155 | template 156 | void build(const vector &v) { 157 | n = v.size(); 158 | tree.assign(1 << (__lg(max(1, n - 1)) + 2), item()); 159 | build(v, 0, 0, n - 1); 160 | } 161 | 162 | item ask(int l, int r, int i, int vl, int vr) { 163 | if (vl != vr) { 164 | tree[i].push(tree[i * 2 + 1], tree[i * 2 + 2], vl, vr); 165 | } 166 | if (l == vl && r == vr) { 167 | return tree[i]; 168 | } 169 | int m = (vl + vr) >> 1; 170 | if (r <= m) { 171 | return ask(l, r, i * 2 + 1, vl, m); 172 | } else if (m < l) { 173 | return ask(l, r, i * 2 + 2, m + 1, vr); 174 | } else { 175 | return item::merge(ask(l, m, i * 2 + 1, vl, m), ask(m + 1, r, i * 2 + 2, m + 1, vr), l, r); 176 | } 177 | } 178 | 179 | item ask(int l, int r) { 180 | l = max(l, 0); r = min(r, n - 1); 181 | if (l > r) return item(); 182 | return ask(l, r, 0, 0, n - 1); 183 | } 184 | 185 | template 186 | void set(int ind, const T &t) { 187 | static array, 30> st; 188 | int l = 0, r = n - 1, i = 0; 189 | int ptr = -1; 190 | while (l != r) { 191 | if (l != r) { 192 | tree[i].push(tree[i * 2 + 1], tree[i * 2 + 2], l, r); 193 | } 194 | st[++ptr] = {l, r}; 195 | int m = (l + r) >> 1; 196 | if (ind <= m) { 197 | i = i * 2 + 1; 198 | r = m; 199 | } else { 200 | i = i * 2 + 2; 201 | l = m + 1; 202 | } 203 | } 204 | tree[i].init(t, l, r); 205 | while (i != 0) { 206 | i = (i - 1) / 2; 207 | tree[i].update(tree[i * 2 + 1], tree[i * 2 + 2], st[ptr].first, st[ptr].second); 208 | --ptr; 209 | } 210 | } 211 | 212 | template 213 | void modify(int l, int r, const Modifier &modifier, int i, int vl, int vr) { 214 | if (vl != vr) { 215 | tree[i].push(tree[i * 2 + 1], tree[i * 2 + 2], vl, vr); 216 | } 217 | if (l == vl && r == vr && tree[i].modify(modifier, vl, vr)) { 218 | return; 219 | } 220 | int m = (vl + vr) >> 1; 221 | if (r <= m) { 222 | modify(l, r, modifier, i * 2 + 1, vl, m); 223 | } else if (m < l) { 224 | modify(l, r, modifier, i * 2 + 2, m + 1, vr); 225 | } else { 226 | modify(l, m, modifier, i * 2 + 1, vl, m); 227 | modify(m + 1, r, modifier, i * 2 + 2, m + 1, vr); 228 | } 229 | tree[i].update(tree[i * 2 + 1], tree[i * 2 + 2], vl, vr); 230 | } 231 | 232 | template 233 | void modify(int l, int r, const Modifier &modifier) { 234 | l = max(l, 0); r = min(r, n - 1); 235 | if (l > r) return; 236 | modify(l, r, modifier, 0, 0, n - 1); 237 | } 238 | }; 239 | } 240 | using segtree_ns::segtree, segtree_ns::mod_min, segtree_ns::mod_max, segtree_ns::mod_add; 241 | -------------------------------------------------------------------------------- /segtree_lazy.cpp: -------------------------------------------------------------------------------- 1 | namespace segtree_ns { 2 | struct item { 3 | template 4 | void init(const T &t, int l, int r) { 5 | } 6 | 7 | void update(const item &first, const item &second, int l, int r) { 8 | } 9 | 10 | static item merge(const item &first, const item &second, int l, int r) { 11 | item res; 12 | res.update(first, second, l, r); // careful with different lengths 13 | return res; 14 | } 15 | 16 | template 17 | void modify(const Modifier &m, int l, int r) { 18 | // apply here, save for children 19 | } 20 | 21 | void push(item &first, item &second, int l, int r) { 22 | // int m = (l + r) / 2; 23 | // first.modify(, l, m); 24 | // second.modify(, m + 1, r); 25 | // reset modifier 26 | } 27 | }; 28 | OSTREAM(item); 29 | 30 | struct segtree { 31 | vector tree; 32 | int n = 1; 33 | 34 | segtree(int n = 1) : n(n) { 35 | tree.resize(1 << (__lg(max(1, n - 1)) + 2)); 36 | } 37 | 38 | template 39 | segtree(const vector& v) { 40 | build(v); 41 | } 42 | 43 | template 44 | void build(const vector &v, int i, int l, int r) { 45 | if (l == r) { 46 | tree[i].init(v[l], l, r); 47 | return; 48 | } 49 | int m = (l + r) >> 1; 50 | build(v, i * 2 + 1, l, m); 51 | build(v, i * 2 + 2, m + 1, r); 52 | tree[i].update(tree[i * 2 + 1], tree[i * 2 + 2], l, r); 53 | } 54 | 55 | template 56 | void build(const vector &v) { 57 | n = v.size(); 58 | tree.assign(1 << (__lg(max(1, n - 1)) + 2), item()); 59 | build(v, 0, 0, n - 1); 60 | } 61 | 62 | item ask(int l, int r, int i, int vl, int vr) { 63 | if (vl != vr) { 64 | tree[i].push(tree[i * 2 + 1], tree[i * 2 + 2], vl, vr); 65 | } 66 | if (l == vl && r == vr) { 67 | return tree[i]; 68 | } 69 | int m = (vl + vr) >> 1; 70 | if (r <= m) { 71 | return ask(l, r, i * 2 + 1, vl, m); 72 | } else if (m < l) { 73 | return ask(l, r, i * 2 + 2, m + 1, vr); 74 | } else { 75 | return item::merge(ask(l, m, i * 2 + 1, vl, m), ask(m + 1, r, i * 2 + 2, m + 1, vr), l, r); 76 | } 77 | } 78 | 79 | item ask(int l, int r) { 80 | l = max(l, 0); r = min(r, n - 1); 81 | if (l > r) return item(); 82 | return ask(l, r, 0, 0, n - 1); 83 | } 84 | 85 | template 86 | void set(int ind, const T &t) { 87 | static array, 30> st; 88 | int l = 0, r = n - 1, i = 0; 89 | int ptr = -1; 90 | while (l != r) { 91 | if (l != r) { 92 | tree[i].push(tree[i * 2 + 1], tree[i * 2 + 2], l, r); 93 | } 94 | st[++ptr] = {l, r}; 95 | int m = (l + r) >> 1; 96 | if (ind <= m) { 97 | i = i * 2 + 1; 98 | r = m; 99 | } else { 100 | i = i * 2 + 2; 101 | l = m + 1; 102 | } 103 | } 104 | tree[i].init(t, l, r); 105 | while (i != 0) { 106 | i = (i - 1) / 2; 107 | tree[i].update(tree[i * 2 + 1], tree[i * 2 + 2], st[ptr].first, st[ptr].second); 108 | --ptr; 109 | } 110 | } 111 | 112 | template 113 | void modify(int l, int r, const Modifier &modifier, int i, int vl, int vr) { 114 | if (vl != vr) { 115 | tree[i].push(tree[i * 2 + 1], tree[i * 2 + 2], vl, vr); 116 | } 117 | if (l == vl && r == vr) { 118 | tree[i].modify(modifier, vl, vr); 119 | return; 120 | } 121 | int m = (vl + vr) >> 1; 122 | if (r <= m) { 123 | modify(l, r, modifier, i * 2 + 1, vl, m); 124 | } else if (m < l) { 125 | modify(l, r, modifier, i * 2 + 2, m + 1, vr); 126 | } else { 127 | modify(l, m, modifier, i * 2 + 1, vl, m); 128 | modify(m + 1, r, modifier, i * 2 + 2, m + 1, vr); 129 | } 130 | tree[i].update(tree[i * 2 + 1], tree[i * 2 + 2], vl, vr); 131 | } 132 | 133 | template 134 | void modify(int l, int r, const Modifier &modifier) { 135 | l = max(l, 0); r = min(r, n - 1); 136 | if (l > r) return; 137 | modify(l, r, modifier, 0, 0, n - 1); 138 | } 139 | }; 140 | 141 | ostream& operator << (ostream& o, segtree& tree) { 142 | #ifdef HOME 143 | vector items; 144 | for (int i = 0; i < tree.n; ++i) 145 | items.push_back(tree.ask(i, i)); 146 | const bool print_horizontal = true; 147 | if (print_horizontal) { 148 | for (int i = 0; i < items.size(); ++i) { 149 | if (i != 0) o << " "; 150 | o << items[i]; 151 | } 152 | } else { 153 | for (int i = 0; i < items.size(); ++i) { 154 | o << '\n' << string(10, ' '); 155 | o << items[i]; 156 | } 157 | } 158 | #endif 159 | return o; 160 | } 161 | 162 | } 163 | using namespace segtree_ns; 164 | -------------------------------------------------------------------------------- /sieve.cpp: -------------------------------------------------------------------------------- 1 | struct Sieve { 2 | struct PrimeIterator { 3 | int prime; 4 | int count; 5 | int num; 6 | const Sieve& sieve; 7 | 8 | PrimeIterator(int num, const Sieve& sieve) : num(num), sieve(sieve) { 9 | step(); 10 | } 11 | 12 | void step() { 13 | prime = sieve.mn[num]; 14 | count = 0; 15 | while (num != 1 && sieve.mn[num] == prime) { 16 | num /= sieve.mn[num]; 17 | ++count; 18 | } 19 | } 20 | 21 | bool operator == (const PrimeIterator& other) const { 22 | return tie(prime, count, num) == tie(other.prime, other.count, other.num); 23 | } 24 | bool operator != (const PrimeIterator& other) const { 25 | return !(*this == other); 26 | } 27 | 28 | PrimeIterator& operator ++ () { 29 | step(); 30 | return *this; 31 | } 32 | 33 | pair operator * () const { 34 | return {prime, count}; 35 | } 36 | }; 37 | 38 | struct PrimeIteratorContainer { 39 | int num; 40 | const Sieve& sieve; 41 | using iterator = PrimeIterator; 42 | 43 | PrimeIteratorContainer(int num, const Sieve& sieve) : num(num), sieve(sieve) {} 44 | 45 | PrimeIterator begin() const { 46 | return PrimeIterator(num, sieve); 47 | } 48 | 49 | PrimeIterator end() const { 50 | return PrimeIterator(1, sieve); 51 | } 52 | 53 | vector> collect() const { 54 | vector> result; 55 | for (auto p : *this) 56 | result.push_back(p); 57 | return result; 58 | } 59 | }; 60 | 61 | template 62 | struct DoubleIterator { 63 | U u; 64 | V v; 65 | U::iterator uit; 66 | V::iterator vit; 67 | int prime; 68 | int count; 69 | 70 | DoubleIterator(const U& u, const V& v, U::iterator uit, V::iterator vit) : u(u), v(v), uit(uit), vit(vit) { 71 | tie(prime, count) = this->operator*(); 72 | } 73 | 74 | DoubleIterator& operator ++ () { 75 | if (uit == u.end()) { 76 | ++vit; 77 | } else if (vit == v.end()) { 78 | ++uit; 79 | } else if ((*uit).first < (*vit).first) { 80 | ++uit; 81 | } else if ((*uit).first > (*vit).first) { 82 | ++vit; 83 | } else { 84 | ++uit; 85 | ++vit; 86 | } 87 | return *this; 88 | } 89 | 90 | bool operator == (const DoubleIterator& other) const { 91 | return tie(uit, vit) == tie(other.uit, other.vit); 92 | } 93 | bool operator != (const DoubleIterator& other) const { 94 | return !(*this == other); 95 | } 96 | 97 | pair operator * () const { 98 | if (uit == u.end()) return *vit; 99 | if (vit == v.end()) return *uit; 100 | if ((*uit).first < (*vit).first) return *uit; 101 | if ((*uit).first > (*vit).first) return *vit; 102 | return {(*uit).first, (*uit).second + (*vit).second}; 103 | } 104 | }; 105 | 106 | template 107 | struct DoubleIteratorContainer { 108 | using iterator = DoubleIterator; 109 | U u; 110 | V v; 111 | 112 | DoubleIteratorContainer(const U& u, const V& v) : u(u), v(v) {} 113 | 114 | iterator begin() const { 115 | return iterator(u, v, u.begin(), v.begin()); 116 | } 117 | 118 | iterator end() const { 119 | return iterator(u, v, u.end(), v.end()); 120 | } 121 | 122 | vector> collect() const { 123 | vector> result; 124 | for (auto p : *this) 125 | result.push_back(p); 126 | return result; 127 | } 128 | }; 129 | 130 | vector isp; 131 | vector primes; 132 | vector mn; 133 | 134 | Sieve(int n, bool gen_primes = false, bool gen_mn = false) { 135 | isp.assign(n + 1, true); isp[0] = isp[1] = false; 136 | for (int i = 2; i * i <= n; ++i) 137 | if (isp[i]) 138 | for (int j = i * i; j <= n; j += i) 139 | isp[j] = false; 140 | 141 | if (gen_primes) 142 | for (int i = 2; i <= n; ++i) 143 | if (isp[i]) 144 | primes.push_back(i); 145 | 146 | if (gen_mn) { 147 | mn.assign(n + 1, -1); 148 | for (int i = 2; i <= n; ++i) { 149 | if (isp[i]) { 150 | mn[i] = i; 151 | if ((ll)i * i <= n) 152 | for (int j = i * i; j <= n; j += i) 153 | if (mn[j] == -1) 154 | mn[j] = i; 155 | } 156 | } 157 | } 158 | } 159 | 160 | bool is_prime(int k) const { 161 | return isp[k]; 162 | } 163 | 164 | bool operator[](int k) const { 165 | return isp[k]; 166 | } 167 | 168 | // can be used as vector>, as in function phi() below 169 | // except doesn't create a vector to avoid heap allocations 170 | // can be transformed into vector> with .collect() 171 | auto get_prime_divs(int p) const { 172 | return PrimeIteratorContainer(p, *this); 173 | } 174 | 175 | // if you want to get prime divs for n = a * b * c where max(a, b, c) < size(sieve), then call get_prime_divs(a, b, c) 176 | template 177 | auto get_prime_divs(int p, Args... args) const { 178 | return DoubleIteratorContainer(PrimeIteratorContainer(p, *this), get_prime_divs(args...)); 179 | } 180 | 181 | int phi(int n) const { 182 | auto v = get_prime_divs(n); 183 | for (auto [p, c] : v) 184 | n = n / p * (p - 1); 185 | return n; 186 | } 187 | }; 188 | -------------------------------------------------------------------------------- /small_vec.cpp: -------------------------------------------------------------------------------- 1 | namespace small_vec_ns { 2 | 3 | template 4 | struct small_vec { 5 | array data; 6 | int size_ = 0; 7 | 8 | small_vec(int n = 0, const T& value = T()) : size_(n) { 9 | fill(data.begin(), data.begin() + n, value); 10 | } 11 | template 12 | small_vec(It begin, It end) { 13 | while (begin != end) data[size_++] = *(begin++); 14 | } 15 | small_vec(const std::initializer_list& list) : small_vec(list.begin(), list.end()) {} 16 | 17 | void assign(int n, const T& value) { 18 | size_ = n; 19 | for (int i = 0; i < n; ++i) data[i] = value; 20 | } 21 | void resize(int n, const T& value = T()) { 22 | if (n > size_) fill(data.begin() + size_, data.begin() + n, value); 23 | size_ = n; 24 | } 25 | 26 | int size () const { return size_; } 27 | bool empty() const { return size_ == 0; } 28 | 29 | auto begin () const { return data.begin(); } 30 | auto end () const { return data.begin() + size_; } 31 | auto begin () { return data.begin(); } 32 | auto end () { return data.begin() + size_; } 33 | auto rbegin() const { return data.rend () - size_; } 34 | auto rend () const { return data.rend (); } 35 | auto rbegin() { return data.rend () - size_; } 36 | auto rend () { return data.rend (); } 37 | 38 | void push_back(const T& value) { data[size_++] = value; } 39 | void push_back( T&& value) { data[size_++] = std::move(value); } 40 | template void emplace_back(Args&&... args) { data[size_++] = T(args...);; } 41 | void pop_back() { --size_; } 42 | 43 | template 44 | void insert(It pos, T value) { 45 | while (pos <= end()) { swap(*(pos++), value); } 46 | ++size_; 47 | } 48 | template 49 | void erase(It pos) { 50 | while (next(pos) < end()) { auto nx = next(pos); swap(*(pos++), *nx); } 51 | --size_; 52 | } 53 | 54 | T& operator[] (int i) { return data[i]; } 55 | const T& operator[] (int i) const { return data[i]; } 56 | 57 | T& front() { return data[0]; } 58 | T& back () { return data[size_ - 1]; } 59 | const T& front() const { return data[0]; } 60 | const T& back () const { return data[size_ - 1]; } 61 | 62 | bool operator < (const small_vec& other) const { 63 | for (int i = 0; i < min(size_, other.size_); ++i) 64 | if (data[i] != other.data[i]) 65 | return data[i] < other.data[i]; 66 | return size_ < other.size_; 67 | } 68 | bool operator > (const small_vec& other) const { return other < *this; } 69 | bool operator <= (const small_vec& other) const { return !(other < *this); } 70 | bool operator >= (const small_vec& other) const { return !(*this < other); } 71 | bool operator == (const small_vec& other) const { 72 | if (size_ != other.size_) return false; 73 | for (int i = 0; i < size_; ++i) 74 | if (data[i] != other.data[i]) 75 | return false; 76 | return true; 77 | } 78 | bool operator != (const small_vec& other) const { return !(*this == other); } 79 | 80 | vector to_vector() const { return vector(begin(), end()); } 81 | }; 82 | 83 | template string _to_string_(const small_vec& v) { return _to_string_(v.to_vector()); } 84 | } 85 | using namespace small_vec_ns; 86 | -------------------------------------------------------------------------------- /sparse_table.cpp: -------------------------------------------------------------------------------- 1 | template> 2 | struct SparseTable { 3 | vector> table; 4 | vector p2; 5 | F combine; 6 | 7 | SparseTable(int n, F combine) : combine(combine) { 8 | while ((1 << table.size()) <= n || table.empty()) 9 | table.emplace_back(n); 10 | } 11 | template 12 | SparseTable(const vector& v, F combine) : SparseTable(v.size(), combine) { 13 | table[0].assign(v.begin(), v.end()); 14 | build(); 15 | } 16 | 17 | void build() { 18 | p2.resize(table[0].size() + 1); 19 | for (int i = 2; i < p2.size(); ++i) 20 | p2[i] = p2[i / 2] + 1; 21 | for (int i = 1; i < table.size(); ++i) { 22 | for (int j = 0; j + (1 << i) <= table[i].size(); ++j) { 23 | table[i][j] = combine(table[i - 1][j], table[i - 1][j + (1 << (i - 1))]); 24 | } 25 | } 26 | } 27 | 28 | T ask(int l, int r) { 29 | int ln = p2[r - l + 1]; 30 | if (r - l + 1 == ln) return table[ln][l]; 31 | return combine(table[ln][l], table[ln][r - (1 << ln) + 1]); 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /static_pointer.cpp: -------------------------------------------------------------------------------- 1 | namespace static_pointer_ns { 2 | 3 | // pointer to vector of nodes instead of just heap 4 | // - takes only sizeof(int) memory, instead of sizeof(size_t) 5 | // - has the same api as raw pointers, so can be used after one "replace all" action 6 | // - does not break with wrong aliasing (like __int128 with fast_allocator.cpp) 7 | // - only takes memory for nodes, so temporary vectors do not take space like with fast_allocator.cpp 8 | // - supports operator ostream and casting to int (-1 is nullptr), which makes debugging easier (can be used as node id) 9 | 10 | // usage: 11 | // example for struct S is in the bottom 12 | // better performace with .reserve() in main 13 | // create new nodes with static new_node() function 14 | // is is possible to create using operator new, but it has some unnecessary overhead 15 | // does not support operator delete 16 | 17 | template& v> 18 | struct static_pointer { 19 | int ind = -1; 20 | static_pointer() {} 21 | static_pointer(int ind) : ind(ind) {} 22 | static_pointer(T *ptr) { 23 | v.push_back(*ptr); 24 | delete ptr; 25 | ind = v.size() - 1; 26 | } 27 | static_pointer(nullptr_t p) : ind(-1) {} 28 | 29 | template 30 | static static_pointer new_node(Args... args) { 31 | v.emplace_back(args...); 32 | return v.size() - 1; 33 | } 34 | 35 | T* operator -> () const { 36 | return &v[ind]; 37 | } 38 | 39 | T& operator * () { 40 | return v[ind]; 41 | } 42 | 43 | operator bool () const { 44 | return ind != -1; 45 | } 46 | operator int () const { 47 | return ind; 48 | } 49 | 50 | bool operator == (nullptr_t p) const { 51 | return ind == -1; 52 | } 53 | bool operator == (int k) const { 54 | return ind == k; 55 | } 56 | bool operator != (nullptr_t p) const { 57 | return ind != -1; 58 | } 59 | bool operator != (int k) const { 60 | return ind != k; 61 | } 62 | }; 63 | 64 | template& v> 65 | ostream &operator << (ostream &o, const static_pointer &ptr) { 66 | return o << (int)ptr; 67 | } 68 | 69 | } 70 | using namespace static_pointer_ns; 71 | 72 | // struct S; 73 | // vector nodes; 74 | // using s_ptr = static_pointer; 75 | -------------------------------------------------------------------------------- /subset_convolution.cpp: -------------------------------------------------------------------------------- 1 | // res[i] = sum_{j = submask(i)} a[i] * b[i ^ j] 2 | template 3 | vector subset_convolution(const vector &a, const vector &b) { 4 | int n = a.size(); 5 | assert((n & (n - 1)) == 0); 6 | assert(a.size() == b.size()); 7 | static vector> buf1; 8 | static vector> buf2; 9 | static vector buf3; 10 | 11 | buf1.assign(__lg(n) + 1, vector(n, 0)); 12 | buf2.assign(__lg(n) + 1, vector(n, 0)); 13 | 14 | for (int i = 0; i < n; ++i) { 15 | int cnt = __builtin_popcount(i); 16 | buf1[cnt][i] = a[i]; 17 | buf2[cnt][i] = b[i]; 18 | } 19 | 20 | auto submask_sum = [&](vector &v) { 21 | for (int b = 0; (1 << b) < n; ++b) 22 | for (int i = 0; i < n; ++i) 23 | if (((i >> b) & 1) == 0) 24 | v[i ^ (1 << b)] += v[i]; 25 | }; 26 | 27 | for (int i = 0; i < buf1.size(); ++i) { 28 | submask_sum(buf1[i]); 29 | submask_sum(buf2[i]); 30 | } 31 | 32 | vector res(n, 0); 33 | 34 | for (int i = 0; i < buf1.size(); ++i) { 35 | buf3.assign(n, 0); 36 | 37 | for (int j = 0; j <= i; ++j) 38 | for (int k = 0; k < n; ++k) 39 | buf3[k] += buf1[j][k] * buf2[i - j][k]; 40 | 41 | for (int b = 0; (1 << b) < n; ++b) 42 | for (int i = 0; i < n; ++i) 43 | if (((i >> b) & 1) == 0) 44 | buf3[i ^ (1 << b)] -= buf3[i]; 45 | 46 | for (int j = 0; j < n; ++j) 47 | if (__builtin_popcount(j) == i) 48 | res[j] = buf3[j]; 49 | } 50 | 51 | return res; 52 | } 53 | -------------------------------------------------------------------------------- /suffix_array.cpp: -------------------------------------------------------------------------------- 1 | namespace suffix_array { 2 | 3 | // linear suffix array 4 | // works in O(n + sigma) 5 | // for strings call suffix_array(s, ALPHA_SMALL | ALPHA_LARGE) for example, 6 | // or just suffix_array(s) 7 | // for vectors call suffix_array(v, *max_element(v.begin(), v.end())), v[i] has to be at least 1 for all i 8 | 9 | // call lcp(string/vector, suffix_array) for lcp 10 | 11 | const int ALPHA_SMALL = 1; 12 | const int ALPHA_LARGE = 2; 13 | const int DIGITS = 4; 14 | 15 | vector buf1, buf2, buf3; 16 | 17 | vector suffix_array(vector s, int k) { 18 | if (s.size() <= 4) { 19 | vector res(s.size()); iota(res.begin(), res.end(), 0); 20 | sort(res.begin(), res.end(), [&](int i1, int i2) { 21 | if (i1 == i2) return false; 22 | while (i1 < s.size() && i2 < s.size() && s[i1] == s[i2]) { 23 | ++i1; ++i2; 24 | } 25 | if (i1 == s.size() || i2 == s.size()) return i1 > i2; 26 | return s[i1] < s[i2]; 27 | }); 28 | return res; 29 | } 30 | int init_size = s.size(); 31 | s.resize(s.size() + 3, 0); 32 | 33 | vector triple_inds; 34 | for (int i = 0; i + 3 <= s.size(); ++i) 35 | if (i % 3 != 0) 36 | triple_inds.push_back(i); 37 | 38 | // sort triples 39 | for (int it = 2; it >= 0; --it) { 40 | buf1.assign(k + 1, 0); 41 | for (int i : triple_inds) 42 | buf1[s[i + it]]++; 43 | for (int i = 1; i < buf1.size(); ++i) 44 | buf1[i] += buf1[i - 1]; 45 | buf2.resize(triple_inds.size()); 46 | for (int i = (int)triple_inds.size() - 1; i >= 0; --i) 47 | buf2[--buf1[s[triple_inds[i] + it]]] = triple_inds[i]; 48 | swap(triple_inds, buf2); 49 | } 50 | 51 | // assign equivalency classes to triples 52 | buf2.resize(triple_inds.size()); 53 | buf2[0] = 1; 54 | for (int i = 1; i < triple_inds.size(); ++i) { 55 | if (s[triple_inds[i]] == s[triple_inds[i - 1]] && 56 | s[triple_inds[i] + 1] == s[triple_inds[i - 1] + 1] && 57 | s[triple_inds[i] + 2] == s[triple_inds[i - 1] + 2]) { 58 | buf2[i] = buf2[i - 1]; 59 | } else { 60 | buf2[i] = buf2[i - 1] + 1; 61 | } 62 | } 63 | 64 | // recursively sort triples if there are equal 65 | if (buf2.back() != buf2.size()) { 66 | int last = buf2.back(); 67 | buf1.resize(s.size()); 68 | for (int i = 0; i < triple_inds.size(); ++i) 69 | buf1[triple_inds[i]] = buf2[i]; 70 | buf2.clear(); 71 | for (int i = 1; i + 3 <= s.size(); i += 3) 72 | buf2.push_back(buf1[i]); 73 | int n1 = buf2.size(); 74 | for (int i = 2; i + 3 <= s.size(); i += 3) 75 | buf2.push_back(buf1[i]); 76 | triple_inds = suffix_array(buf2, last); 77 | for (int &i : triple_inds) { 78 | if (i * 3 + 1 + 3 <= s.size()) i = i * 3 + 1; 79 | else i = (i - n1) * 3 + 2; 80 | } 81 | } 82 | 83 | buf2.clear(); 84 | if (s.size() % 3 == 0) 85 | buf2.push_back(s.size() - 3); 86 | for (int i : triple_inds) 87 | if (i % 3 == 1) 88 | buf2.push_back(i - 1); 89 | 90 | // sort suffixes with i % 3 = 0 91 | { 92 | buf1.assign(k + 1, 0); 93 | for (int i : buf2) 94 | buf1[s[i]]++; 95 | for (int i = 1; i < buf1.size(); ++i) 96 | buf1[i] += buf1[i - 1]; 97 | 98 | buf3.resize(buf2.size()); 99 | for (int i = (int)buf2.size() - 1; i >= 0; --i) 100 | buf3[--buf1[s[buf2[i]]]] = buf2[i]; 101 | 102 | swap(buf2, buf3); 103 | } 104 | 105 | buf1.assign(s.size(), 0); 106 | for (int i = 0; i < triple_inds.size(); ++i) 107 | buf1[triple_inds[i]] = i + 1; 108 | 109 | // compare suffixes with i1 % 3 != 0 and i2 % 3 == 0 110 | auto cmp = [&](int i1, int i2) { 111 | if (s[i1] != s[i2]) return s[i1] < s[i2]; 112 | ++i1; ++i2; 113 | if (i1 % 3 != 0) return buf1[i1] < buf1[i2]; 114 | if (s[i1] != s[i2]) return s[i1] < s[i2]; 115 | ++i1; ++i2; 116 | return buf1[i1] < buf1[i2]; 117 | }; 118 | 119 | // merge suf12 and suf0 120 | buf3.clear(); 121 | auto &res = buf3; 122 | res.reserve(s.size()); 123 | int i1 = 0, i2 = 0; 124 | while (i1 < triple_inds.size() || i2 < buf2.size()) { 125 | bool choose1; 126 | if (i1 == triple_inds.size()) choose1 = false; 127 | else if (i2 == buf2.size()) choose1 = true; 128 | else if (cmp(triple_inds[i1], buf2[i2])) choose1 = true; 129 | else choose1 = false; 130 | 131 | if (choose1) { 132 | if (triple_inds[i1] < init_size) 133 | res.push_back(triple_inds[i1]); 134 | ++i1; 135 | } else { 136 | if (buf2[i2] < init_size) 137 | res.push_back(buf2[i2]); 138 | ++i2; 139 | } 140 | } 141 | 142 | return res; 143 | } 144 | 145 | vector suffix_array(const string &s, int mask = 0) { 146 | if (mask == 0) { 147 | array has; has.fill(0); 148 | for (unsigned char c : s) { 149 | has[c] = 1; 150 | } 151 | int last = 0; 152 | for (int i = 0; i < 256; ++i) { 153 | if (has[i]) { 154 | ++last; 155 | has[i] = last; 156 | } 157 | } 158 | 159 | vector v(s.size()); 160 | for (int i = 0; i < v.size(); ++i) { 161 | v[i] = has[(unsigned char)s[i]]; 162 | } 163 | return suffix_array(v, last); 164 | } else { 165 | int digit_start = 0; 166 | int alpha_large_start = (mask & DIGITS) ? 10 : 0; 167 | int alpha_small_start = (mask & ALPHA_LARGE) ? alpha_large_start + 26 : alpha_large_start; 168 | 169 | vector v(s.size()); 170 | for (int i = 0; i < s.size(); ++i) { 171 | if ('0' <= s[i] && s[i] <= '9') v[i] = s[i] - '0' + digit_start + 1; 172 | else if ('A' <= s[i] && s[i] <= 'Z') v[i] = s[i] - 'A' + alpha_large_start + 1; 173 | else v[i] = s[i] - 'a' + alpha_small_start + 1; 174 | } 175 | return suffix_array(v, alpha_small_start + ((mask & ALPHA_SMALL) ? 26 : 0)); 176 | } 177 | } 178 | 179 | template 180 | vector lcp(const T &s, const vector &suf_array) { 181 | int n = s.size(); 182 | vector lcp(n - 1); 183 | vector ind(n); 184 | for (int i = 0; i < n; ++i) { 185 | ind[suf_array[i]] = i; 186 | } 187 | int last = 1; 188 | for (int i = 0; i < n; ++i) { 189 | last = max(last - 1, 0); 190 | int i_cur = i; 191 | if (ind[i_cur] != 0) { 192 | int i_prev = suf_array[ind[i_cur] - 1]; 193 | while (i_cur + last < s.size() && i_prev + last < s.size() && s[i_cur + last] == s[i_prev + last]) 194 | ++last; 195 | lcp[ind[i_cur] - 1] = last; 196 | } 197 | } 198 | return lcp; 199 | } 200 | 201 | } 202 | -------------------------------------------------------------------------------- /suffix_tree.cpp: -------------------------------------------------------------------------------- 1 | int suf_inf = 1e7; 2 | string suf_string; 3 | struct SufNode; 4 | int suf_down = 0; 5 | struct SufEdge { 6 | SufNode* to = nullptr; 7 | int l; 8 | int r; 9 | 10 | SufEdge() {} 11 | SufEdge(int l, int r, SufNode* node = nullptr) : l(l), r(r), to(node) {} 12 | 13 | int len() { 14 | return r - l + 1; 15 | } 16 | }; 17 | struct SufNode { 18 | map to; 19 | SufNode* suflink = nullptr; 20 | ll cnt = 0; 21 | 22 | void count() { 23 | cnt = 1; 24 | for (auto [c, edge] : to) { 25 | if (edge->r + 1 == suf_string.size()) 26 | --edge->r; 27 | edge->to->count(); 28 | cnt += edge->to->cnt + edge->len() - 1; 29 | } 30 | } 31 | }; 32 | SufNode* suf_root = new SufNode(); 33 | SufNode* suf_cur = suf_root; 34 | SufNode* suf_saved = nullptr; 35 | void split_suf_edge(SufEdge* edge, int k) { 36 | SufNode* middle = new SufNode(); 37 | SufEdge* next = new SufEdge(edge->l + k, edge->r, edge->to); 38 | edge->to = middle; 39 | middle->to[suf_string[edge->l + k]] = next; 40 | edge->r = edge->l + k - 1; 41 | } 42 | void add_char(char c) { 43 | suf_string.pb(c); 44 | ++suf_down; 45 | suf_saved = nullptr; 46 | while (suf_down != 0) { 47 | while (suf_cur->to.find(suf_string[suf_string.size() - suf_down]) != suf_cur->to.end()) { 48 | SufEdge* edge = suf_cur->to[suf_string[suf_string.size() - suf_down]]; 49 | if (suf_down <= edge->len()) 50 | break; 51 | suf_down -= edge->len(); 52 | suf_cur = edge->to; 53 | } 54 | if (suf_cur->to.find(suf_string[suf_string.size() - suf_down]) == suf_cur->to.end()) { 55 | SufNode* new_node = new SufNode(); 56 | suf_cur->to[suf_string[suf_string.size() - suf_down]] = 57 | new SufEdge(suf_string.size() - suf_down, suf_inf, new_node); 58 | if (suf_saved != nullptr) 59 | suf_saved->suflink = suf_cur; 60 | suf_saved = nullptr; 61 | } else { 62 | SufEdge* edge = suf_cur->to[suf_string[suf_string.size() - suf_down]]; 63 | if (suf_string[edge->l + suf_down - 1] == c) { 64 | if (suf_saved != nullptr) 65 | suf_saved->suflink = suf_cur; 66 | break; 67 | } else { 68 | split_suf_edge(edge, suf_down - 1); 69 | edge->to->to[c] = new SufEdge(suf_string.size() - 1, suf_inf, new SufNode()); 70 | if (suf_saved != nullptr) 71 | suf_saved->suflink = edge->to; 72 | suf_saved = edge->to; 73 | } 74 | } 75 | if (suf_cur == suf_root) 76 | --suf_down; 77 | else 78 | suf_cur = suf_cur->suflink; 79 | } 80 | } 81 | void suf_build(string s) { 82 | for (auto c : s) { 83 | add_char(c); 84 | } 85 | suf_root->count(); 86 | --suf_root->cnt; 87 | } 88 | string get_lex(ll n) { 89 | string res; 90 | SufNode* node = suf_root; 91 | while (n > 0) { 92 | show(n, res); 93 | for (auto [c, edge] : node->to) { 94 | if (n <= edge->to->cnt + edge->len() - 1) { 95 | if (n <= edge->len()) { 96 | res += suf_string.substr(edge->l, n); 97 | return res; 98 | } else { 99 | res += suf_string.substr(edge->l, edge->len()); 100 | n -= edge->len(); 101 | node = edge->to; 102 | break; 103 | } 104 | } 105 | n -= (edge->to->cnt + edge->len() - 1); 106 | } 107 | } 108 | return res; 109 | } 110 | -------------------------------------------------------------------------------- /tensor.cpp: -------------------------------------------------------------------------------- 1 | namespace tensor_ns { 2 | template 3 | struct _Tensor_ { 4 | vector v; 5 | vector dims; 6 | vector sz; 7 | 8 | _Tensor_(const array &list, T value = T()) { 9 | dims = sz = vector(list.begin(), list.end()); 10 | dims.push_back(1); 11 | sz.push_back(1); 12 | for (int i = (int)sz.size() - 2; i >= 0; --i) 13 | sz[i] *= sz[i + 1]; 14 | v.assign(sz[0], value); 15 | } 16 | }; 17 | 18 | template 19 | struct Tensor { 20 | shared_ptr<_Tensor_> tensor; 21 | size_t l; 22 | size_t dim; 23 | 24 | Tensor(const array &list, T value = T()) : tensor(new _Tensor_(list, value)), l(0), dim(0) {} 25 | Tensor(shared_ptr<_Tensor_> tensor, size_t l, size_t dim) : tensor(tensor), l(l), dim(dim) {} 26 | 27 | Tensor operator [] (size_t i) { 28 | return Tensor(tensor, l + tensor->sz[dim + 1] * i, dim + 1); 29 | } 30 | const Tensor operator [] (size_t i) const { 31 | return Tensor(tensor, l + tensor->sz[dim + 1] * i, dim + 1); 32 | } 33 | void fill(T value) { 34 | std::fill(tensor->v.begin() + l, tensor->v.begin() + l + total_size(), value); 35 | } 36 | int size() const { 37 | return tensor->dims[M - N]; 38 | } 39 | int total_size() const { 40 | return tensor->sz[M - N]; 41 | } 42 | auto to_vector() const { 43 | vector res = {{(*this)[0].to_vector()}}; 44 | for (int i = 1; i < size(); ++i) 45 | res.push_back((*this)[i].to_vector()); 46 | return res; 47 | } 48 | }; 49 | 50 | template 51 | struct Tensor { 52 | shared_ptr<_Tensor_> tensor; 53 | size_t l; 54 | size_t dim; 55 | 56 | Tensor(const array &list, T value = T()) : tensor(new _Tensor_(list, value)), l(0), dim(0) {} 57 | Tensor(shared_ptr<_Tensor_> tensor, size_t l, size_t dim) : tensor(tensor), l(l), dim(dim) {} 58 | 59 | T &operator [] (size_t i) { 60 | return tensor->v[l + i]; 61 | } 62 | T &operator [] (size_t i) const { 63 | return tensor->v[l + i]; 64 | } 65 | void fill(T value) { 66 | std::fill(tensor->v.begin() + l, tensor->v.begin() + l + total_size(), value); 67 | } 68 | int size() const { 69 | return tensor->dims[M - 1]; 70 | } 71 | int total_size() const { 72 | return tensor->sz[M - 1]; 73 | } 74 | auto to_vector() const { 75 | return vector(tensor->v.begin() + l, tensor->v.begin() + l + size()); 76 | } 77 | }; 78 | 79 | template 80 | ostream &operator << (ostream &o, const Tensor &t) { 81 | for (int i = 0; i < t.size(); ++i) { 82 | o << endl; 83 | o << t[i]; 84 | } 85 | return o; 86 | } 87 | template 88 | ostream &operator << (ostream &o, const Tensor &t) { 89 | auto v = t.to_vector(); 90 | o << "["; 91 | for (int i = 0; i < v.size(); ++i) { 92 | if (i) o << ", "; 93 | o << v[i]; 94 | } 95 | o << "]"; 96 | return o; 97 | } 98 | template 99 | ostream &operator << (ostream &o, const Tensor &t) { 100 | auto v = t.to_vector(); 101 | vector> result(v.size()); 102 | for (int i = 0; i < v.size(); ++i) { 103 | for (int j = 0; j < v[i].size(); ++j) { 104 | stringstream ss; 105 | ss << v[i][j]; 106 | result[i].push_back(ss.str()); 107 | } 108 | } 109 | vector widths; 110 | for (int i = 0; i < result.size(); ++i) { 111 | widths.resize(max(widths.size(), result[i].size()), 0); 112 | for (int j = 0; j < result[i].size(); ++j) 113 | widths[j] = max(widths[j], (int)result[i][j].size()); 114 | } 115 | if (widths.empty()) return o; 116 | 117 | const int padding = 12; 118 | 119 | widths.assign(widths.size(), *max_element(widths.begin(), widths.end())); 120 | 121 | int total = accumulate(widths.begin(), widths.end(), 0); 122 | total += 2 * ((int)widths.size() - 1); 123 | o << endl; 124 | for (int i = 0; i < v.size(); ++i) { 125 | o << string(padding, ' '); 126 | o << "["; 127 | int left = total; 128 | for (int j = 0; j < v[i].size(); ++j) { 129 | o << setw(widths[j]) << result[i][j]; 130 | if (j + 1 != v[i].size()) 131 | o << ", "; 132 | left -= widths[j]; 133 | left -= 2; 134 | } 135 | if (!v[i].empty()) 136 | left += 2; 137 | if (v[i].size() != widths.size()) 138 | o << string(left, ' '); 139 | o << "]"; 140 | if (i + 1 != v.size()) 141 | o << ",\n"; 142 | } 143 | o << "]]"; 144 | 145 | return o; 146 | } 147 | } 148 | using namespace tensor_ns; 149 | -------------------------------------------------------------------------------- /tools/gen.cpp: -------------------------------------------------------------------------------- 1 | mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()); 2 | long long rnd (long long l, long long r) { return (long long)(rng() % (r - l + 1)) + l; } 3 | long long rnd (long long r) { return rng() % r; } 4 | long long rnd () { return rng(); } 5 | long double rndf() { return (long double)rng() / (long double)ULLONG_MAX; } 6 | long double rndf(long double l, long double r) { return rndf() * (r - l) + l; } 7 | 8 | pair gen_dif_pair(int l, int r) { 9 | while (true) { 10 | int u = rnd(l, r), v = rnd(l, r); 11 | if (u != v) 12 | return {u, v}; 13 | } 14 | } 15 | 16 | pair gen_lr(int l, int r, bool allow_same = true) { 17 | while (true) { 18 | int u = rnd(l, r), v = rnd(l, r); 19 | if (u == v && !allow_same) continue; 20 | if (u > v) swap(u, v); 21 | return {u, v}; 22 | } 23 | } 24 | 25 | vector> gen_tree(int n) { 26 | struct DSU { 27 | vector rk; 28 | vector p; 29 | int n; 30 | 31 | DSU(int n = 1) : n(n) { 32 | reset(n); 33 | } 34 | 35 | void reset(int n) { 36 | p.resize(n); 37 | iota(p.begin(), p.end(), 0); 38 | rk.assign(n, 1); 39 | } 40 | 41 | int par(int v) { 42 | return v == p[v] ? v : p[v] = par(p[v]); 43 | } 44 | 45 | bool un(int u, int v) { 46 | u = par(u); 47 | v = par(v); 48 | if (u == v) return false; 49 | if (rk[u] > rk[v]) swap(u, v); 50 | p[u] = v; 51 | rk[v] += rk[u]; 52 | return true; 53 | } 54 | }; 55 | 56 | DSU d(n); 57 | vector> res; 58 | int comps = n; 59 | while (comps > 1) { 60 | auto [u, v] = gen_dif_pair(0, n - 1); 61 | if (d.un(u, v)) { 62 | res.emplace_back(u, v); 63 | --comps; 64 | } 65 | } 66 | return res; 67 | } 68 | 69 | vector> gen_graph(int n, int m, bool connected = false) { 70 | set> has; 71 | vector> res; 72 | if (connected) { 73 | res = gen_tree(n); 74 | for (auto& [u, v] : res) 75 | if (u > v) 76 | swap(u, v); 77 | has.insert(res.begin(), res.end()); 78 | } 79 | while (res.size() < m) { 80 | auto p = gen_lr(0, n - 1, false); 81 | if (has.count(p)) continue; 82 | has.insert(p); 83 | res.push_back(p); 84 | } 85 | shuffle(res.begin(), res.end(), rng); 86 | for (auto& [u, v] : res) 87 | if (rnd(2)) 88 | swap(u, v); 89 | return res; 90 | } 91 | 92 | template 93 | vector gen_array(int n, T l, T r) { 94 | vector res(n); 95 | for (int i = 0; i < n; ++i) 96 | res[i] = rnd(l, r); 97 | return res; 98 | } 99 | -------------------------------------------------------------------------------- /tools/macro_map.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by William Swanson in 2012. 3 | * 4 | * I, William Swanson, dedicate this work to the public domain. 5 | * I waive all rights to the work worldwide under copyright law, 6 | * including all related and neighboring rights, 7 | * to the extent allowed by law. 8 | * 9 | * You can copy, modify, distribute and perform the work, 10 | * even for commercial purposes, all without asking permission. 11 | */ 12 | 13 | #ifndef MAP_H_INCLUDED 14 | #define MAP_H_INCLUDED 15 | 16 | #define EVAL0(...) __VA_ARGS__ 17 | #define EVAL1(...) EVAL0(EVAL0(EVAL0(__VA_ARGS__))) 18 | #define EVAL2(...) EVAL1(EVAL1(EVAL1(__VA_ARGS__))) 19 | #define EVAL3(...) EVAL2(EVAL2(EVAL2(__VA_ARGS__))) 20 | #define EVAL4(...) EVAL3(EVAL3(EVAL3(__VA_ARGS__))) 21 | #define EVAL(...) EVAL4(EVAL4(EVAL4(__VA_ARGS__))) 22 | 23 | #define MAP_END(...) 24 | #define MAP_OUT 25 | #define MAP_COMMA , 26 | 27 | #define MAP_GET_END2() 0, MAP_END 28 | #define MAP_GET_END1(...) MAP_GET_END2 29 | #define MAP_GET_END(...) MAP_GET_END1 30 | #define MAP_NEXT0(test, next, ...) next MAP_OUT 31 | #define MAP_NEXT1(test, next) MAP_NEXT0(test, next, 0) 32 | #define MAP_NEXT(test, next) MAP_NEXT1(MAP_GET_END test, next) 33 | 34 | #define MAP0(f, x, peek, ...) f(x) MAP_NEXT(peek, MAP1)(f, peek, __VA_ARGS__) 35 | #define MAP1(f, x, peek, ...) f(x) MAP_NEXT(peek, MAP0)(f, peek, __VA_ARGS__) 36 | 37 | #define MAP_LIST_NEXT1(test, next) MAP_NEXT0(test, MAP_COMMA next, 0) 38 | #define MAP_LIST_NEXT(test, next) MAP_LIST_NEXT1(MAP_GET_END test, next) 39 | 40 | #define MAP_LIST0(f, x, peek, ...) f(x) MAP_LIST_NEXT(peek, MAP_LIST1)(f, peek, __VA_ARGS__) 41 | #define MAP_LIST1(f, x, peek, ...) f(x) MAP_LIST_NEXT(peek, MAP_LIST0)(f, peek, __VA_ARGS__) 42 | 43 | /** 44 | * Applies the function macro `f` to each of the remaining parameters. 45 | */ 46 | #define MAP(f, ...) EVAL(MAP1(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) 47 | 48 | /** 49 | * Applies the function macro `f` to each of the remaining parameters and 50 | * inserts commas between the results. 51 | */ 52 | #define MAP_LIST(f, ...) EVAL(MAP_LIST1(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /tools/sublime/calculate.py: -------------------------------------------------------------------------------- 1 | import sublime 2 | import sublime_plugin 3 | from math import * 4 | from random import * 5 | from time import time 6 | 7 | rr = randrange 8 | fact = factorial 9 | 10 | timeout = 3 11 | 12 | def gcd(a, b): 13 | if a > b: 14 | a, b = b, a 15 | if a == 0: 16 | return b 17 | return gcd(b % a, a) 18 | 19 | def c(n, k): 20 | return fact(n) // (fact(k) * fact(n - k)) 21 | 22 | def factor(n): 23 | start_time = time() 24 | if n <= 1: 25 | return str(n) 26 | p = 3 27 | answer = [] 28 | while n % 2 == 0: 29 | answer.append("2") 30 | n //= 2 31 | while p * p <= n: 32 | while n % p == 0: 33 | n //= p 34 | answer.append(str(p)) 35 | p += 2 36 | if time() > start_time + timeout: 37 | if n != 1: 38 | answer.append("({0})".format(n)) 39 | n = 1 40 | break 41 | if n != 1: 42 | answer.append(str(n)) 43 | return ' * '.join([p for p in answer]) 44 | 45 | def primes_between(a, b): 46 | start_time = time() 47 | is_prime = [True for i in range(b - a + 1)] 48 | answer = [] 49 | for i in range(2, int(sqrt(b)) + 5): 50 | j = a // i * i 51 | while j < a: 52 | j += i 53 | while j <= b: 54 | is_prime[j - a] = False 55 | j += i 56 | if time() > start_time + timeout: 57 | answer.append(-1) 58 | break 59 | for i in range(b - a + 1): 60 | if is_prime[i]: 61 | answer.append(a + i) 62 | return answer 63 | 64 | # [name, parameters] 65 | commands = [["factor", 1], ["c", 2], ["fact", 1], ["sin", 1], ["cos", 1], ["rr", 2], ["primes_between", 2],\ 66 | ["log", 2], ["gcd", 2]] 67 | 68 | class InsertResultCommand(sublime_plugin.TextCommand): 69 | def run(self, edit, **args): 70 | if args.get("position") is None: 71 | position = self.view.sel()[0].begin() 72 | else: 73 | position = args["position"] 74 | self.view.insert(edit, position, args["text"]) 75 | self.view.sel().add(sublime.Region(position, position + len(args["text"]))) 76 | 77 | class CalculateCommand(sublime_plugin.TextCommand): 78 | def run(self, edit): 79 | if len(self.view.sel()) == 1 and self.view.sel()[0].empty(): 80 | self.view.window().show_input_panel("", "", self.done, None, None) 81 | else: 82 | for region in list(self.view.sel())[::-1]: 83 | text = self.view.substr(region) 84 | result = str(self.calculate(text)) 85 | if text[0] == '\n': 86 | result = '\n' + result 87 | if text[-1] == '\n': 88 | result = result + '\n' 89 | position = region.begin() 90 | self.view.erase(edit, region) 91 | self.view.run_command("insert_result", args={"text": result, "position": position}) 92 | 93 | def calculate(delf, text): 94 | for command in commands: 95 | if text.startswith(command[0]) and text[len(command[0])] != '(': 96 | if command[1] > 1: 97 | text = text[:len(command[0])] + '(' + text[len(command[0]) + 1:].replace(' ', ',') + ')' 98 | else: 99 | text = text[:len(command[0])] + '(' + text[len(command[0]) + 1:] + ')' 100 | break 101 | return eval(text) 102 | 103 | def done(self, text): 104 | self.view.run_command("insert_result", args={"text": str(self.calculate(text))}) 105 | -------------------------------------------------------------------------------- /tools/sublime/insert_code.py: -------------------------------------------------------------------------------- 1 | import sublime 2 | import sublime_plugin 3 | import os 4 | 5 | 6 | path = "C:/Libs/" 7 | ifdef_string = "#ifdef HOME" 8 | int_main_string = "int main(" 9 | test_case_string = "void test_case(" 10 | 11 | class InsertFromFileCommand(sublime_plugin.TextCommand): 12 | def run(self, edit, **args): 13 | lines = open(args["file"], "r").readlines() 14 | curtext = self.view.substr(sublime.Region(0, self.view.size())) 15 | after_string = int_main_string 16 | if test_case_string in curtext: 17 | after_string = test_case_string 18 | if after_string in curtext: 19 | self.view.insert(edit, curtext.index(after_string), "".join(lines) + '\n') 20 | else: 21 | self.view.insert(edit, self.view.sel()[0].begin(), "".join(lines) + '\n') 22 | 23 | class InsertTemplateCommand(sublime_plugin.TextCommand): 24 | def run(self, edit): 25 | self.files = list(filter(lambda file: ".exe" not in file, list(os.walk(path))[0][2])) 26 | self.view.window().show_quick_panel([file[:-4] for file in self.files], self.on_file_choose) 27 | 28 | def on_file_choose(self, index): 29 | if index == -1: 30 | return 31 | self.view.run_command("insert_from_file", {"file": path + self.files[index]}) 32 | 33 | class OpenTemplateCommand(sublime_plugin.TextCommand): 34 | def run(self, edit): 35 | self.files = list(filter(lambda file: ".exe" not in file, list(os.walk(path))[0][2])) 36 | self.view.window().show_quick_panel([file[:-4] for file in self.files], self.on_file_choose) 37 | 38 | def on_file_choose(self, index): 39 | if index == -1: 40 | return 41 | sublime.active_window().open_file(path + self.files[index]) 42 | -------------------------------------------------------------------------------- /treap.cpp: -------------------------------------------------------------------------------- 1 | struct treapNode { 2 | treapNode * left = nullptr; 3 | treapNode * right = nullptr; 4 | int value; 5 | int priority; 6 | int size; 7 | 8 | treapNode(int _value, int _priority) : value(_value), priority(_priority), size(1) {} 9 | 10 | void reset() { 11 | size = 1; 12 | if (left != nullptr) { 13 | size += left->size; 14 | } 15 | if (right != nullptr) { 16 | size += right->size; 17 | } 18 | } 19 | }; 20 | 21 | struct treap { 22 | treapNode * root = nullptr; 23 | mt19937 rnd; 24 | 25 | treap() { 26 | rnd = mt19937(chrono::steady_clock::now().time_since_epoch().count()); 27 | } 28 | treap(vector& a) { 29 | rnd = mt19937(chrono::steady_clock::now().time_since_epoch().count()); 30 | for (auto k : a) { 31 | insert(k); 32 | } 33 | } 34 | 35 | pair split(treapNode * node, int k) { 36 | if (node == nullptr) { 37 | return {nullptr, nullptr}; 38 | } if (k <= node->value) { 39 | auto ans = split(node->left, k); 40 | node->left = ans.second; 41 | node->reset(); 42 | return {ans.first, node}; 43 | } else { 44 | auto ans = split(node->right, k); 45 | node->right = ans.first; 46 | node->reset(); 47 | return {node, ans.second}; 48 | } 49 | } 50 | 51 | treapNode * merge(treapNode * a, treapNode * b) { 52 | if (a == nullptr) { 53 | return b; 54 | } else if (b == nullptr) { 55 | return a; 56 | } 57 | if (a->priority < b->priority) { 58 | a->right = merge(a->right, b); 59 | a->reset(); 60 | return a; 61 | } else { 62 | b->left = merge(a, b->left); 63 | b->reset(); 64 | return b; 65 | } 66 | } 67 | 68 | void insert(int k) { 69 | treapNode * newNode = new treapNode(k, rnd()); 70 | auto p = split(root, k); 71 | root = merge(merge(p.first, newNode), p.second); 72 | } 73 | 74 | treapNode * find(int k) { 75 | treapNode * node = root; 76 | while (node != nullptr && node->value != k) { 77 | if (node->value < k) { 78 | node = node->right; 79 | } else { 80 | node = node->left; 81 | } 82 | } 83 | return node; 84 | } 85 | 86 | treapNode * first() { 87 | if (root == nullptr) { 88 | return root; 89 | } 90 | treapNode * node = root; 91 | while (node->left != nullptr) { 92 | node = node->left; 93 | } 94 | return node; 95 | } 96 | 97 | treapNode * last() { 98 | if (root == nullptr) { 99 | return root; 100 | } 101 | treapNode * node = root; 102 | while (node->right != nullptr) { 103 | node = node->right; 104 | } 105 | return node; 106 | } 107 | 108 | treapNode * next(int k, treapNode * node) { 109 | if (node == nullptr) { 110 | return node; 111 | } 112 | if (node->value == k && node->right == nullptr) { 113 | return node; 114 | } 115 | if (node->value <= k) { 116 | return next(k, node->right); 117 | } else { 118 | auto p1 = next(k, node->left); 119 | if (p1 == nullptr) { 120 | p1 = node; 121 | } 122 | if (p1->value > k) { 123 | return p1; 124 | } else { 125 | return node; 126 | } 127 | } 128 | } 129 | 130 | treapNode * next(int k) { 131 | return next(k, root); 132 | } 133 | 134 | treapNode * prev(int k, treapNode * node) { 135 | if (node == nullptr) { 136 | return node; 137 | } 138 | if (node->value == k && node->left == nullptr) { 139 | return node; 140 | } 141 | if (node->value >= k) { 142 | return prev(k, node->left); 143 | } else { 144 | auto p1 = prev(k, node->right); 145 | if (p1 == nullptr) { 146 | p1 = node; 147 | } 148 | if (p1->value < k) { 149 | return p1; 150 | } else { 151 | return node; 152 | } 153 | } 154 | } 155 | 156 | treapNode * prev(int k) { 157 | return prev(k, root); 158 | } 159 | 160 | void erase(int k) { 161 | if (root == nullptr) { 162 | return; 163 | } 164 | auto p1 = split(root, k); 165 | auto p2 = split(p1.second, k + 1); 166 | root = merge(p1.first, p2.second); 167 | } 168 | 169 | void clear() { 170 | delete root; 171 | } 172 | 173 | ~treap() { 174 | delete root; 175 | } 176 | }; 177 | 178 | #ifdef HOME 179 | void print(treapNode * node, string spaces = "") { 180 | if (node == nullptr) { 181 | cout << spaces << "-\n"; 182 | return; 183 | } 184 | cout << spaces << "|--" << node->value << '(' << node->size << ')' << '\n'; 185 | if (node->left == nullptr && node->right == nullptr) { 186 | return; 187 | } 188 | print(node->left, spaces + "| "); 189 | print(node->right, spaces + "| "); 190 | } 191 | #endif 192 | -------------------------------------------------------------------------------- /treap_array.cpp: -------------------------------------------------------------------------------- 1 | mt19937 rnd = mt19937(chrono::steady_clock::now().time_since_epoch().count()); 2 | 3 | struct treapArNode { 4 | treapArNode * left = nullptr; 5 | treapArNode * right = nullptr; 6 | int value; 7 | int size; 8 | 9 | treapArNode(int _value) : value(_value), size(1) {} 10 | 11 | void reset() { 12 | size = 1; 13 | if (left != nullptr) { 14 | size += left->size; 15 | } 16 | if (right != nullptr) { 17 | size += right->size; 18 | } 19 | } 20 | }; 21 | 22 | struct treapAr { 23 | treapArNode * root = nullptr; 24 | 25 | treapAr() {} 26 | treapAr(treapArNode * _root) { 27 | root = _root; 28 | } 29 | 30 | pair split(treapArNode * node, int k) { 31 | if (node == nullptr) { 32 | return {nullptr, nullptr}; 33 | } 34 | int leftSize = 0; 35 | if (node->left != nullptr) { 36 | leftSize = node->left->size; 37 | } 38 | if (leftSize >= k) { 39 | auto ans = split(node->left, k); 40 | node->left = ans.second; 41 | node->reset(); 42 | return {ans.first, node}; 43 | } else { 44 | auto ans = split(node->right, k - 1 - leftSize); 45 | node->right = ans.first; 46 | node->reset(); 47 | return {node, ans.second}; 48 | } 49 | } 50 | 51 | treapArNode * merge(treapArNode * a, treapArNode * b) { 52 | if (a == nullptr) { 53 | return b; 54 | } else if (b == nullptr) { 55 | return a; 56 | } 57 | if (rnd() % (a->size + b->size) < a->size) { 58 | a->right = merge(a->right, b); 59 | a->reset(); 60 | return a; 61 | } else { 62 | b->left = merge(a, b->left); 63 | b->reset(); 64 | return b; 65 | } 66 | } 67 | 68 | void insert(int i, int k) { 69 | treapArNode * newNode = new treapArNode(k); 70 | auto p = split(root, i); 71 | root = merge(merge(p.first, newNode), p.second); 72 | } 73 | 74 | void insert(int i, treapArNode * node) { 75 | auto p = split(root, i); 76 | root = merge(merge(p.first, node), p.second); 77 | } 78 | 79 | treapArNode * get(int i) { 80 | treapArNode * node = root; 81 | while (node != nullptr) { 82 | if (node->left == nullptr) { 83 | if (i == 0) { 84 | return node; 85 | } else { 86 | --i; 87 | node = node->right; 88 | } 89 | } else { 90 | if (i == node->left->size) { 91 | return node; 92 | } else if (i < node->left->size) { 93 | node = node->left; 94 | } else { 95 | i -= node->left->size + 1; 96 | node = node->right; 97 | } 98 | } 99 | } 100 | } 101 | 102 | int operator[] (int i) { 103 | return get(i)->value; 104 | } 105 | 106 | vector toVector(treapArNode * node) { 107 | if (node == nullptr) { 108 | return vector({}); 109 | } 110 | vector vLeft = toVector(node->left); 111 | vector vRight = toVector(node->right); 112 | vLeft.push_back(node->value); 113 | vLeft.insert(vLeft.end(), vRight.begin(), vRight.end()); 114 | return vLeft; 115 | } 116 | 117 | vector toVector() { 118 | return toVector(root); 119 | } 120 | 121 | void erase(int k) { 122 | auto p1 = split(root, k); 123 | auto p2 = split(p1.second, 1); 124 | root = merge(p1.first, p2.second); 125 | } 126 | 127 | void erase(int l, int r) { 128 | auto p1 = split(root, l); 129 | auto p2 = split(p1.second, r + 1 - l); 130 | root = merge(p1.first, p2.second); 131 | } 132 | 133 | treapArNode * cut(int l, int r) { 134 | auto p1 = split(root, l); 135 | auto p2 = split(p1.second, r + 1 - l); 136 | root = merge(p1.first, p2.second); 137 | return p2.first; 138 | } 139 | 140 | void clear() { 141 | delete root; 142 | } 143 | }; 144 | 145 | #ifdef HOME 146 | void print(treapArNode * node, string spaces = "") { 147 | if (node == nullptr) { 148 | cout << spaces << "-\n"; 149 | return; 150 | } 151 | cout << spaces << "|--" << node->value << '(' << node->size << ')' << '\n'; 152 | if (node->left == nullptr && node->right == nullptr) { 153 | return; 154 | } 155 | print(node->left, spaces + "| "); 156 | print(node->right, spaces + "| "); 157 | } 158 | #endif 159 | -------------------------------------------------------------------------------- /treap_array_persistent.cpp: -------------------------------------------------------------------------------- 1 | mt19937 rnd = mt19937(chrono::steady_clock::now().time_since_epoch().count()); 2 | 3 | struct treapArNode { 4 | treapArNode * left = nullptr; 5 | treapArNode * right = nullptr; 6 | int value; 7 | int size; 8 | 9 | treapArNode(int _value) : value(_value), size(1) {} 10 | 11 | void resetSize() { 12 | size = 1; 13 | if (left != nullptr) { 14 | size += left->size; 15 | } 16 | if (right != nullptr) { 17 | size += right->size; 18 | } 19 | } 20 | }; 21 | 22 | pair split(treapArNode * node, int k); 23 | treapArNode * merge(treapArNode * a, treapArNode * b); 24 | 25 | struct treapAr { 26 | treapArNode * root = nullptr; 27 | 28 | treapAr(); 29 | treapAr(treapArNode * _root); 30 | 31 | void insert(int i, int k); 32 | 33 | void insert(int i, treapArNode * node); 34 | 35 | treapArNode * get(int i); 36 | 37 | int operator[] (int i); 38 | 39 | vector toVector(treapArNode * node); 40 | 41 | vector toVector(); 42 | 43 | void erase(int k); 44 | 45 | void erase(int l, int r); 46 | 47 | treapArNode * cut(int l, int r); 48 | 49 | void clear(); 50 | }; 51 | 52 | #ifdef HOME 53 | void print(treapArNode * node, string spaces = "") { 54 | if (node == nullptr) { 55 | cout << spaces << "-" << endl; 56 | return; 57 | } 58 | cout << spaces << "|--" << node->value << '(' << node->size << ')' << endl; 59 | if (node->left == nullptr && node->right == nullptr) { 60 | return; 61 | } 62 | print(node->left, spaces + "| "); 63 | print(node->right, spaces + "| "); 64 | } 65 | #endif 66 | 67 | struct treaps { 68 | vector versions; 69 | 70 | treaps() { 71 | versions.emplace_back(); 72 | } 73 | 74 | int insert(int version, int i, int k) { 75 | auto p = split(versions[version].root, i); 76 | versions.emplace_back(merge(merge(p.first, new treapArNode(k)), p.second)); 77 | return versions.size() - 1; 78 | } 79 | 80 | auto get(int version, int i) { 81 | return versions[version].get(i); 82 | } 83 | 84 | int erase(int version, int k) { 85 | auto p = split(versions[version].root, k); 86 | versions.emplace_back(merge(p.first, split(p.second, 1).second)); 87 | return versions.size() - 1; 88 | } 89 | 90 | int erase(int version, int l, int r) { 91 | auto p = split(versions[version].root, l); 92 | versions.emplace_back(merge(p.first, split(p.second, r - l + 1).second)); 93 | return versions.size() - 1; 94 | } 95 | 96 | auto& operator[] (int i) { 97 | return versions[i]; 98 | } 99 | 100 | int size() { 101 | return versions.size(); 102 | } 103 | 104 | auto& back() { 105 | return versions.back(); 106 | } 107 | }; 108 | 109 | treapArNode * treapAr::get(int i) { 110 | treapArNode * node = root; 111 | while (node != nullptr) { 112 | if (node->left == nullptr) { 113 | if (i == 0) { 114 | return node; 115 | } else { 116 | --i; 117 | node = node->right; 118 | } 119 | } else { 120 | if (i == node->left->size) { 121 | return node; 122 | } else if (i < node->left->size) { 123 | node = node->left; 124 | } else { 125 | i -= node->left->size + 1; 126 | node = node->right; 127 | } 128 | } 129 | } 130 | } 131 | 132 | int treapAr::operator[] (int i) { 133 | return get(i)->value; 134 | } 135 | 136 | treapAr::treapAr() {} 137 | treapAr::treapAr(treapArNode * _root) { 138 | root = _root; 139 | } 140 | 141 | pair split(treapArNode * node, int k) { 142 | if (node == nullptr) { 143 | return {nullptr, nullptr}; 144 | } 145 | int leftSize = 0; 146 | if (node->left != nullptr) { 147 | leftSize = node->left->size; 148 | } 149 | if (leftSize >= k) { 150 | auto ans = split(node->left, k); 151 | auto newNode = new treapArNode(node->value); 152 | newNode->left = ans.second; 153 | newNode->right = node->right; 154 | newNode->resetSize(); 155 | return {ans.first, newNode}; 156 | } else { 157 | auto ans = split(node->right, k - 1 - leftSize); 158 | treapArNode * newNode = new treapArNode(node->value); 159 | newNode->left = node->left; 160 | newNode->right = ans.first; 161 | newNode->resetSize(); 162 | return {newNode, ans.second}; 163 | } 164 | } 165 | 166 | treapArNode * merge(treapArNode * a, treapArNode * b) { 167 | if (a == nullptr) { 168 | return b; 169 | } else if (b == nullptr) { 170 | return a; 171 | } 172 | if (rnd() % (a->size + b->size) < a->size) { 173 | auto newA = new treapArNode(a->value); 174 | newA->left = a->left; 175 | newA->right = merge(a->right, b); 176 | newA->resetSize(); 177 | return newA; 178 | } else { 179 | auto newB = new treapArNode(b->value); 180 | newB->right = b->right; 181 | newB->left = merge(a, b->left); 182 | newB->resetSize(); 183 | return newB; 184 | } 185 | } 186 | 187 | vector treapAr::toVector(treapArNode * node) { 188 | if (node == nullptr) { 189 | return vector({}); 190 | } 191 | vector vLeft = toVector(node->left); 192 | vector vRight = toVector(node->right); 193 | vLeft.push_back(node->value); 194 | vLeft.insert(vLeft.end(), vRight.begin(), vRight.end()); 195 | return vLeft; 196 | } 197 | 198 | vector treapAr::toVector() { 199 | return toVector(root); 200 | } 201 | 202 | treapArNode * treapAr::cut(int l, int r) { 203 | auto p1 = split(root, l); 204 | auto p2 = split(p1.second, r + 1 - l); 205 | root = merge(p1.first, p2.second); 206 | return p2.first; 207 | } 208 | 209 | void treapAr::clear() { 210 | root = nullptr; 211 | } 212 | 213 | #ifdef HOME 214 | void print(treaps& t) { 215 | for (int i = 0; i < t.versions.size(); ++i) { 216 | cout << "version " << i << endl; 217 | print(t[i].root); 218 | cout << endl; 219 | } 220 | } 221 | #endif 222 | -------------------------------------------------------------------------------- /tree_to_line_save_max.cpp: -------------------------------------------------------------------------------- 1 | // returns vector of n vertices on a line and vector of n-1 edges between them 2 | template> 3 | pair, vector> tree_to_line_save_max(vector>> edges) { 4 | sort(edges.begin(), edges.end(), [&](const auto &a, const auto &b) { 5 | return OP()(a.first, b.first); 6 | }); 7 | int n = edges.size() + 1; 8 | vector p(n); 9 | iota(p.begin(), p.end(), 0); 10 | auto left = p, right = p; 11 | vector rk(n, 1); 12 | 13 | vector>> near(n); 14 | 15 | function par = [&](int v) { 16 | return v == p[v] ? v : p[v] = par(p[v]); 17 | }; 18 | 19 | auto un = [&](int u, int v) { 20 | u = par(u); 21 | v = par(v); 22 | if (u == v) return; 23 | if (rk[u] > rk[v]) swap(u, v); 24 | p[u] = v; 25 | rk[v] += rk[u]; 26 | }; 27 | 28 | for (auto [w, uv] : edges) { 29 | auto [u, v] = uv; 30 | u = par(u); 31 | v = par(v); 32 | assert(u != v); 33 | near[right[u]].emplace_back(left[v], w); 34 | near[left[v]].emplace_back(right[u], w); 35 | un(u, v); 36 | int k = par(u); 37 | left[k] = left[u]; 38 | right[k] = right[v]; 39 | } 40 | 41 | int x = par(0); 42 | assert(rk[x] == n); 43 | x = left[x]; 44 | 45 | vector vert = {x}; 46 | vector w; 47 | if (n == 1) 48 | return {vert, w}; 49 | assert(near[x].size() == 1); 50 | 51 | int prev = x; 52 | w.push_back(near[x][0].second); 53 | x = near[x][0].first; 54 | vert.push_back(x); 55 | for (int i = 0; i < n - 2; ++i) { 56 | int ind = 0; 57 | if (near[x][ind].first == prev) ind = 1; 58 | w.push_back(near[x][ind].second); 59 | prev = x; 60 | x = near[x][ind].first; 61 | vert.push_back(x); 62 | } 63 | 64 | return {vert, w}; 65 | } 66 | -------------------------------------------------------------------------------- /variable_mint.cpp: -------------------------------------------------------------------------------- 1 | namespace var_mint_ns { 2 | struct VarModular { 3 | using value_type = int; 4 | private: 5 | static value_type P; 6 | public: 7 | value_type value; 8 | 9 | VarModular(long long k = 0) : value(norm(k)) {} 10 | 11 | friend VarModular& operator += ( VarModular& n, const VarModular& m) { n.value += m.value; if (n.value >= P) n.value -= P; return n; } 12 | friend VarModular operator + (const VarModular& n, const VarModular& m) { VarModular r = n; return r += m; } 13 | 14 | friend VarModular& operator -= ( VarModular& n, const VarModular& m) { n.value -= m.value; if (n.value < 0) n.value += P; return n; } 15 | friend VarModular operator - (const VarModular& n, const VarModular& m) { VarModular r = n; return r -= m; } 16 | friend VarModular operator - (const VarModular& n) { return VarModular(-n.value); } 17 | 18 | friend VarModular& operator *= ( VarModular& n, const VarModular& m) { n.value = reduce(n.value * 1ll * m.value); return n; } 19 | friend VarModular operator * (const VarModular& n, const VarModular& m) { VarModular r = n; return r *= m; } 20 | 21 | friend VarModular& operator /= ( VarModular& n, const VarModular& m) { return n *= m.inv(); } 22 | friend VarModular operator / (const VarModular& n, const VarModular& m) { VarModular r = n; return r /= m; } 23 | 24 | VarModular& operator ++ ( ) { return *this += 1; } 25 | VarModular& operator -- ( ) { return *this -= 1; } 26 | VarModular operator ++ (int) { VarModular r = *this; *this += 1; return r; } 27 | VarModular operator -- (int) { VarModular r = *this; *this -= 1; return r; } 28 | 29 | friend bool operator == (const VarModular& n, const VarModular& m) { return n.value == m.value; } 30 | friend bool operator != (const VarModular& n, const VarModular& m) { return n.value != m.value; } 31 | 32 | explicit operator int() const { return value; } 33 | explicit operator bool() const { return value; } 34 | explicit operator long long() const { return value; } 35 | 36 | static value_type mod() { return P; } 37 | 38 | value_type norm(long long k) { 39 | if (!(-P <= k && k < P)) k %= P; 40 | if (k < 0) k += P; 41 | return k; 42 | } 43 | 44 | VarModular inv() const { 45 | value_type a = value, b = P, x = 0, y = 1; 46 | while (a != 0) { value_type k = b / a; b -= k * a; x -= k * y; swap(a, b); swap(x, y); } 47 | return VarModular(x); 48 | } 49 | 50 | private: 51 | static uint64_t m; 52 | public: 53 | static void set_mod(value_type mod) { 54 | m = (__uint128_t(1) << 64) / mod; 55 | P = mod; 56 | } 57 | 58 | static value_type reduce(uint64_t a) { 59 | uint64_t q = ((__uint128_t(m) * a) >> 64); 60 | a -= q * P; 61 | if (a >= P) 62 | a -= P; 63 | return a; 64 | } 65 | }; 66 | uint64_t VarModular::m = 0; 67 | VarModular pow(VarModular m, long long p) { 68 | VarModular r(1); 69 | while (p) { 70 | if (p & 1) r *= m; 71 | m *= m; 72 | p >>= 1; 73 | } 74 | return r; 75 | } 76 | VarModular::value_type VarModular::P; 77 | // use "VarModular::set_mod([your value])" later 78 | 79 | ostream& operator << (ostream& o, const VarModular& m) { return o << m.value; } 80 | istream& operator >> (istream& i, VarModular& m) { long long k; i >> k; m.value = m.norm(k); return i; } 81 | string to_string(const VarModular& m) { return to_string(m.value); } 82 | 83 | using Mint = VarModular; 84 | // using Mint = long double; 85 | 86 | vector f, fi; 87 | void init_C(int n) { 88 | f.assign(n, 1); fi.assign(n, 1); 89 | for (int i = 2; i < n; ++i) f[i] = f[i - 1] * i; 90 | fi.back() = Mint(1) / f.back(); 91 | for (int i = n - 2; i >= 0; --i) fi[i] = fi[i + 1] * (i + 1); 92 | } 93 | Mint C(int n, int k) { 94 | if (k < 0 || k > n) return 0; 95 | else return f[n] * fi[k] * fi[n - k]; 96 | } 97 | } 98 | using namespace var_mint_ns; 99 | -------------------------------------------------------------------------------- /y_combinator.cpp: -------------------------------------------------------------------------------- 1 | template 2 | class y_combinator_result { 3 | Fun fun_; 4 | public: 5 | template 6 | explicit y_combinator_result(T &&fun): fun_(std::forward(fun)) {} 7 | 8 | template 9 | decltype(auto) operator()(Args &&...args) { 10 | return fun_(std::ref(*this), std::forward(args)...); 11 | } 12 | }; 13 | template 14 | decltype(auto) y_combinator(Fun &&fun) { 15 | return y_combinator_result>(std::forward(fun)); 16 | } 17 | // auto gcd = std::y_combinator([](auto gcd, int a, int b) -> int { 18 | // return b == 0 ? a : gcd(b, a % b); 19 | // }); 20 | -------------------------------------------------------------------------------- /z_function.cpp: -------------------------------------------------------------------------------- 1 | template 2 | vector z_function(const T &s) { 3 | int n = s.size(); 4 | vector z(n, 0); 5 | int r = 0; 6 | int l = 0; 7 | for (int i = 1; i < n; ++i) { 8 | if (i <= r) 9 | z[i] = min(r - i + 1, z[i - l]); 10 | while (i + z[i] < n && s[z[i]] == s[i + z[i]]) 11 | ++z[i]; 12 | if (i + z[i] - 1 > r) { 13 | l = i; 14 | r = i + z[i] - 1; 15 | } 16 | } 17 | return z; 18 | } 19 | --------------------------------------------------------------------------------