├── .gitignore ├── README.md ├── include └── local.h └── source ├── algebra ├── mat.h ├── mod.h ├── poly.h ├── sos.h └── tridiagonal.h ├── data-structures ├── aug_treap.h ├── bit.h ├── bit_vector.h ├── depq.h ├── dp.h ├── dsu.h ├── hash_map.h ├── int_set.h ├── lazy_pq.h ├── lazy_segtree.h ├── noam.h ├── offline_deletion.h ├── rev_aug_treap.h ├── rev_treap.h ├── segtree.h ├── sparse.h └── treap.h ├── geometry └── pt.h ├── graphs ├── blossom.h ├── dinic.h ├── matroid_intersection.h ├── mcmf.h └── scc.h ├── strings └── suffix_array.h ├── template.cpp └── template_interactive.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | test/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Algorithms -------------------------------------------------------------------------------- /include/local.h: -------------------------------------------------------------------------------- 1 | 2 | #define dbg(...) __VA_ARGS__ 3 | 4 | template 5 | std::ostream& operator<<(std::ostream &os, const std::vector &ve) { 6 | if (os.rdbuf() == std::cerr.rdbuf()) { 7 | int n = std::min((int) ve.size(), 50); 8 | os << "[ "; 9 | for (int i = 0; i < n; i++) { 10 | os << ve[i]; 11 | if (i < n - 1) os << ", "; 12 | } 13 | if (n < (int) ve.size()) os << "..."; 14 | os << " ]"; 15 | } else { 16 | int n = ve.size(); 17 | for (int i = 0; i < n; i++) { 18 | os << ve[i]; 19 | if (i < n - 1) os << ' '; 20 | } 21 | } 22 | return os; 23 | } 24 | 25 | template 26 | std::ostream& operator<<(std::ostream &os, const std::vector> &ve) { 27 | if (os.rdbuf() == std::cerr.rdbuf()) { 28 | int n = std::min((int) ve.size(), 50); 29 | os << "[ "; 30 | for (int i = 0; i < n; i++) { 31 | os << ve[i]; 32 | if (i < n - 1) os << ", "; 33 | } 34 | if (n < (int) ve.size()) os << "..."; 35 | os << " ]"; 36 | } else { 37 | int n = ve.size(); 38 | for (int i = 0; i < n; i++) { 39 | os << ve[i]; 40 | if (i < n - 1) os << '\n'; 41 | } 42 | } 43 | return os; 44 | } 45 | 46 | template 47 | void _debug(const char *names, T &&head, V &&... tail) { 48 | int i = 0; 49 | while (names[i] != ',' && names[i] != '\0') i++; 50 | std::cerr.write(names, i); 51 | std::cerr << " = " << head; 52 | if constexpr (sizeof...(tail)) { 53 | std::cerr << ", "; 54 | _debug(names + i + 2, tail...); 55 | } else { 56 | std::cerr << std::endl; 57 | } 58 | } 59 | 60 | template 61 | void _log(T &&head, V &&... tail) { 62 | std::cerr << head << ' '; 63 | if constexpr (sizeof...(tail)) { 64 | _log(tail...); 65 | } 66 | } 67 | void _log() {} 68 | 69 | #define debug(...) {std::cerr << "\033[30m" "[" << __LINE__ << "] "; _debug(#__VA_ARGS__, __VA_ARGS__); std::cerr << "\033[0m";} 70 | #define error(x) {std::cerr << "\033[31m" "[" << __LINE__ << "] "; std::cerr << (x) << '\n'; std::cerr << "\033[0m";} 71 | #define log(...) {std::cerr << "\033[36m" "[" << __LINE__ << "] "; _log(__VA_ARGS__); std::cerr << "\n\033[0m";} 72 | -------------------------------------------------------------------------------- /source/algebra/mat.h: -------------------------------------------------------------------------------- 1 | 2 | template 3 | struct mat : array, N> { 4 | mat(T diag = T()) { 5 | for(size_t i = 0; i < N; i++) { 6 | for(size_t j = 0; j < M; j++) { 7 | if(i == j) { 8 | (*this)[i][j] = diag; 9 | }else { 10 | (*this)[i][j] = T(); 11 | } 12 | } 13 | } 14 | } 15 | mat operator+(const mat &o) const { 16 | mat X; 17 | for(size_t i = 0; i < N; i++) { 18 | for(size_t j = 0; j < M; j++) { 19 | X[i][j] = (*this)[i][j] + o[i][j]; 20 | } 21 | } 22 | return X; 23 | } 24 | template 25 | mat operator*(const mat &o) const { 26 | mat X; 27 | for(size_t i = 0; i < N; i++) { 28 | for(size_t j = 0; j < P; j++) { 29 | for(size_t k = 0; k < M; k++) { 30 | X[i][j] += (*this)[i][k] * o[k][j]; 31 | } 32 | } 33 | } 34 | return X; 35 | } 36 | mat operator*(const T &c) const { 37 | mat X; 38 | for(size_t i = 0; i < N; i++) { 39 | for(size_t j = 0; j < M; j++) { 40 | X[i][j] = (*this)[i][j] * c; 41 | } 42 | } 43 | return X; 44 | } 45 | array operator*(const array &x) const { 46 | array y{}; 47 | for(size_t i = 0; i < N; i++) { 48 | for(size_t j = 0; j < M; j++) { 49 | y[i] += (*this)[i][j] * x[j]; 50 | } 51 | } 52 | return y; 53 | } 54 | mat pow(size_t b) const { 55 | mat X(1), A = *this; 56 | while(b > 0) { 57 | if(b & 1) { 58 | X = X * A; 59 | } 60 | A = A * A; 61 | b /= 2; 62 | } 63 | return X; 64 | } 65 | mat t() const { 66 | mat X; 67 | for(size_t i = 0; i < N; i++) { 68 | for(size_t j = 0; j < M; j++) { 69 | X[j][i] = (*this)[i][j]; 70 | } 71 | } 72 | return X; 73 | } 74 | }; 75 | 76 | template 77 | ostream& operator<<(ostream &os, const mat &A) { 78 | for(size_t i = 0; i < N; i++) { 79 | for(size_t j = 0; j < M; j++) { 80 | os << A[i][j]; 81 | if(j < M - 1) { 82 | os << ' '; 83 | } 84 | } 85 | os << '\n'; 86 | } 87 | return os; 88 | } 89 | 90 | template 91 | ostream& operator<<(ostream &os, const array &v) { 92 | for(size_t i = 0; i < N; i++) { 93 | os << v[i]; 94 | if(i < N - 1) { 95 | os << ' '; 96 | } 97 | } 98 | return os; 99 | } 100 | -------------------------------------------------------------------------------- /source/algebra/mod.h: -------------------------------------------------------------------------------- 1 | 2 | template 3 | struct mod { 4 | long long x; 5 | mod() : x(0) {} 6 | mod(long long xx) : x(xx) { 7 | if(abs(x) >= m) x %= m; 8 | if(x < 0) x += m; 9 | } 10 | mod operator+(const mod &a) const { 11 | mod n; 12 | n.x = x + a.x; 13 | if(n.x >= m) n.x -= m; 14 | return n; 15 | } 16 | mod operator-(const mod &a) const { 17 | mod n; 18 | n.x = x - a.x; 19 | if(n.x < 0) n.x += m; 20 | return n; 21 | } 22 | mod operator*(const mod &a) const { 23 | return x * a.x; 24 | } 25 | mod operator+=(const mod &a) { 26 | x += a.x; 27 | if(x >= m) x -= m; 28 | return *this; 29 | } 30 | mod operator-=(const mod &a) { 31 | x -= a.x; 32 | if(x < 0) x += m; 33 | return *this; 34 | } 35 | mod operator*=(const mod &a) { 36 | x = (x * a.x) % m; 37 | return *this; 38 | } 39 | mod pow(long long b) const { 40 | mod ans = 1; 41 | mod a = *this; 42 | while(b > 0) { 43 | if(b & 1) ans *= a; 44 | a *= a; 45 | b /= 2; 46 | } 47 | return ans; 48 | } 49 | mod inv() const { 50 | return pow(m - 2); 51 | } 52 | mod operator/(const mod &a) const { 53 | return (*this) * a.inv(); 54 | } 55 | mod operator/=(const mod &a) { 56 | return (*this) *= a.inv(); 57 | } 58 | bool operator==(const mod &o) const { 59 | return x == o.x; 60 | } 61 | bool operator!=(const mod &o) const { 62 | return x != o.x; 63 | } 64 | long long operator()() const { 65 | return x; 66 | } 67 | }; 68 | 69 | template 70 | istream &operator>>(istream &is, mod &n) { 71 | long long x; 72 | is >> x; 73 | n = x; 74 | return is; 75 | } 76 | 77 | template 78 | ostream &operator<<(ostream &os, const mod &n) { 79 | return os << n(); 80 | } 81 | -------------------------------------------------------------------------------- /source/algebra/poly.h: -------------------------------------------------------------------------------- 1 | 2 | template 3 | T root(int n, bool inv = false); 4 | 5 | using ftype = double; 6 | using cd = complex; 7 | const ftype pi = acos(-1); 8 | 9 | template<> 10 | cd root<>(int n, bool inv) { 11 | return polar(1.0, 2 * pi / n * (inv ? -1 : 1)); 12 | } 13 | template<> 14 | mod<998244353> root<>(int n, bool inv) { 15 | return mod<998244353>(3).pow(1LL * (998244353 - 1) / n * (inv ? n - 1 : 1)); 16 | } 17 | 18 | template 19 | struct poly { 20 | vector a; 21 | size_t deg; 22 | poly(T a0 = T()) { 23 | a.assign(1, a0); 24 | deg = 0; 25 | } 26 | poly(vector t) : a(t) { 27 | assert(!t.empty()); 28 | resize(a.size()); 29 | deg = t.size() - 1; 30 | } 31 | void resize(size_t n) { 32 | deg = min(deg, n - 1); 33 | size_t s = 1; 34 | while(s < n) s <<= 1; 35 | a.resize(s); 36 | } 37 | size_t size() const { 38 | return a.size(); 39 | } 40 | const T operator[](size_t i) const { 41 | return i > deg ? T() : a[i]; 42 | } 43 | void set(size_t i, const T &t) { 44 | deg = max(deg, i); 45 | resize(deg + 1); 46 | a[i] = t; 47 | } 48 | poly operator+(const poly &A) const { 49 | poly P; 50 | P.resize(max(size(), A.size())); 51 | for(size_t i = 0; i < P.size(); i++) { 52 | P.a[i] = (*this)[i] + A[i]; 53 | } 54 | P.deg = max(deg, A.deg); 55 | return P; 56 | } 57 | poly operator+=(const poly A) { 58 | return *this = *this + A; 59 | } 60 | poly operator-(const poly A) const { 61 | poly P; 62 | P.resize(max(size(), A.size())); 63 | for(int i = 0; i < (int) P.size(); i++) { 64 | P.a[i] = (*this)[i] - A[i]; 65 | } 66 | P.deg = max(deg, A.deg); 67 | return P; 68 | } 69 | poly operator-=(const poly A) { 70 | return *this = *this - A; 71 | } 72 | void fft(bool inv = false) { 73 | int n = (int) size(); 74 | for(int i = 1, j = 0; i < n; i++) { 75 | int bit = n >> 1; 76 | for(; j & bit; bit >>= 1) j ^= bit; 77 | j ^= bit; 78 | if(i < j) swap(a[i], a[j]); 79 | } 80 | for(int len = 2; len <= n; len <<= 1) { 81 | T wn = root(len, inv); 82 | for(int i = 0; i < n; i += len) { 83 | T w = 1; 84 | for(int j = 0; j < len / 2; j++) { 85 | T u = a[i + j], v = a[i + j + len / 2] * w; 86 | a[i + j] = u + v; 87 | a[i + j + len / 2] = u - v; 88 | w *= wn; 89 | } 90 | } 91 | } 92 | if(inv) { 93 | T n_1 = T(1) / T(n); 94 | for(T &x : a) x *= n_1; 95 | } 96 | } 97 | poly mod_xk(size_t k) const { 98 | poly P; 99 | P.resize(k); 100 | for(size_t i = 0; i < k; i++) P.a[i] = (*this)[i]; 101 | P.deg = min(k - 1, deg); 102 | return P; 103 | } 104 | poly& operator*=(const poly &o) { 105 | size_t s = 2 * max(size(), o.size()); 106 | resize(s); 107 | poly B = o; 108 | B.resize(s); 109 | fft(); B.fft(); 110 | for(size_t i = 0; i < s; i++) { 111 | a[i] *= B.a[i]; 112 | } 113 | fft(true); 114 | deg = deg + o.deg; 115 | resize(deg + 1); 116 | return *this; 117 | } 118 | poly operator*(const poly &o) const { 119 | poly A = *this; 120 | A *= o; 121 | return A; 122 | } 123 | poly& operator*=(const T &t) { 124 | for(size_t i = 0; i <= deg; i++) { 125 | a[i] *= t; 126 | } 127 | return *this; 128 | } 129 | poly operator*(const T &t) const { 130 | poly A = *this; 131 | A *= t; 132 | return A; 133 | } 134 | poly deriv() const { 135 | poly P; 136 | P.resize(deg); 137 | for(int i = 1; i <= (int) deg; i++) { 138 | P.a[i - 1] = a[i] * T(i); 139 | } 140 | P.deg = max(size_t(1), deg) - 1; 141 | return P; 142 | } 143 | poly integ() const { 144 | poly P; 145 | P.resize(deg + 2); 146 | for(size_t i = 0; i <= deg; i++) { 147 | P.a[i + 1] = a[i] / T(i + 1); 148 | } 149 | P.deg = deg + 1; 150 | return P; 151 | } 152 | poly mul_xk(size_t k) const { 153 | poly P; 154 | P.resize(deg + k + 1); 155 | for(size_t i = 0; i <= deg; i++) { 156 | P.a[i + k] = a[i]; 157 | } 158 | P.deg = deg + k; 159 | return P; 160 | } 161 | poly div_xk(size_t k) const { 162 | k = min(k, size()); 163 | poly P; 164 | P.resize(deg - k + 1); 165 | for(size_t i = k; i <= deg; i++) { 166 | P.a[i - k] = a[i]; 167 | } 168 | P.deg = deg - k; 169 | return P; 170 | } 171 | poly inv(size_t n) const { 172 | poly Q = T(1) / a[0]; 173 | for(size_t s = 2; s < n * 2; s <<= 1) { 174 | Q *= (poly(2) - Q * mod_xk(s)); 175 | Q.resize(s); 176 | } 177 | Q.deg = n - 1; 178 | return Q; 179 | } 180 | poly log(size_t n) const { 181 | return (deriv().mod_xk(n) * inv(n)).integ().mod_xk(n); 182 | } 183 | poly exp(size_t n) const { 184 | poly Q = T(1); 185 | for(size_t s = 2; s < n * 2; s <<= 1) { 186 | Q *= (poly(1) + mod_xk(s) - Q.log(s)); 187 | Q.resize(s); 188 | } 189 | Q.deg = n - 1; 190 | return Q; 191 | } 192 | }; 193 | 194 | template 195 | void print(const poly> &P) { 196 | cout << P[0](); 197 | for(size_t i = 1; i <= P.deg; i++) { 198 | cout << " + " << P[i]() << " x^" << i; 199 | } 200 | cout << '\n'; 201 | } 202 | void print(const poly &P) { 203 | cout << round(P[0].real()); 204 | for(size_t i = 1; i <= P.deg; i++) { 205 | cout << " + " << round(P[i].real()) << " x^" << i; 206 | } 207 | cout << '\n'; 208 | } 209 | void printreal(const poly &P) { 210 | cout << round(P[0].real()); 211 | for(size_t i = 1; i <= P.deg; i++) { 212 | cout << " + " << P[i].real() << " x^" << i; 213 | } 214 | cout << '\n'; 215 | } 216 | -------------------------------------------------------------------------------- /source/algebra/sos.h: -------------------------------------------------------------------------------- 1 | 2 | template 3 | struct sos { 4 | int n; 5 | vector a; 6 | sos(size_t n) : n(n), a(1 << n) {} 7 | void clear() { 8 | fill(a.begin(), a.end(), T()); 9 | } 10 | void flip() { 11 | for(int i = 0; i < (1 << (n - 1)); i++) { 12 | swap(a[i], a[i ^ ((1 << n) - 1)]); 13 | } 14 | } 15 | void zeta() { 16 | for(int i = 0; i < n; i++) { 17 | for(int s = 0; s < (1 << n); s++) { 18 | if(s >> i & 1) { 19 | a[s] = a[s] + a[s ^ (1 << i)]; 20 | } 21 | } 22 | } 23 | } 24 | void supzeta() { 25 | for(int i = n - 1; i >= 0; i--) { 26 | for(int s = (1 << n) - 1; s >= 0; s--) { 27 | if(~s >> i & 1) { 28 | a[s] = a[s] + a[s ^ (1 << i)]; 29 | } 30 | } 31 | } 32 | } 33 | void mobius() { 34 | for(int i = n - 1; i >= 0; i--) { 35 | for(int s = (1 << n) - 1; s >= 0; s--) { 36 | if(s >> i & 1) { 37 | a[s] = a[s] - a[s ^ (1 << i)]; 38 | } 39 | } 40 | } 41 | } 42 | void supmobius() { 43 | for(int i = 0; i < n; i++) { 44 | for(int s = 0; s < n; s++) { 45 | if(~s >> i & 1) { 46 | a[s] = a[s] - a[s ^ (1 << i)]; 47 | } 48 | } 49 | } 50 | } 51 | }; -------------------------------------------------------------------------------- /source/algebra/tridiagonal.h: -------------------------------------------------------------------------------- 1 | 2 | template 3 | struct tridiagonal { 4 | struct row { 5 | array a; 6 | T b; 7 | }; 8 | vector rows; 9 | void push(const row &r) { 10 | rows.push_back(r); 11 | } 12 | void solve() { 13 | int n = sz(rows); 14 | rep(i, 0, n) { 15 | auto &R = rows[i]; 16 | if (i > 0) { 17 | // Subtract previous row * rows[i].a[0] 18 | auto &Pre = rows[i - 1]; 19 | base x = R.a[0]; 20 | R.a[0] -= Pre.a[1] * x; 21 | R.a[1] -= Pre.a[2] * x; 22 | R.b -= Pre.b * x; 23 | } 24 | // Normalize row 25 | assert(R.a[1] != 0); 26 | base inv = R.a[1].inv(); 27 | R.a[0] *= inv; 28 | R.a[1] *= inv; 29 | R.a[2] *= inv; 30 | R.b *= inv; 31 | } 32 | for (int i = n - 2; i >= 0; i--) { 33 | auto &R = rows[i]; 34 | auto &Next = rows[i + 1]; 35 | base x = R.a[2]; 36 | assert(Next.a[1] == 1); 37 | R.a[0] = 0; 38 | R.a[1] -= Next.a[0] * x; 39 | R.a[2] -= Next.a[1] * x; 40 | R.b -= Next.b * x; 41 | // Normalize row 42 | assert(R.a[1] != 0); 43 | base inv = R.a[1].inv(); 44 | R.a[0] *= inv; 45 | R.a[1] *= inv; 46 | R.a[2] *= inv; 47 | R.b *= inv; 48 | } 49 | } 50 | }; -------------------------------------------------------------------------------- /source/data-structures/aug_treap.h: -------------------------------------------------------------------------------- 1 | 2 | template 3 | struct aug_treap { 4 | public: 5 | struct node { 6 | T value; 7 | T aug; 8 | int cnt, y; 9 | node *l, *r, *p; 10 | node(T value, int cnt, int y) : value(value), aug(value), cnt(cnt), y(y), l(nullptr), r(nullptr), p(nullptr) {} 11 | }; 12 | private: 13 | Op op; 14 | T e; 15 | std::mt19937 rng; 16 | int rand() { 17 | std::uniform_int_distribution uni(0, INT_MAX); 18 | return uni(rng); 19 | } 20 | void update(node* a) { 21 | assert(a); 22 | a->cnt = 1 + size_of(a->l) + size_of(a->r); 23 | a->aug = op(op(aug(a->l), a->value), aug(a->r)); 24 | } 25 | void split(node* a, node*& l, node*& r, int k) { 26 | if (!a) return void(l = r = nullptr); 27 | if (size_of(a->l) < k) { 28 | split(a->r, a->r, r, k - size_of(a->l) - 1); 29 | if (a->r) a->r->p = a; 30 | l = a; 31 | update(a); 32 | } else { 33 | split(a->l, l, a->l, k); 34 | if (a->l) a->l->p = a; 35 | r = a; 36 | update(a); 37 | } 38 | } 39 | node* join(const std::vector& v, int l, int r) { 40 | assert(0 <= l && l <= r && r <= (int) v.size()); 41 | if (l == r) return nullptr; 42 | if (r - l == 1) return v[l]; 43 | int m = l + (r - l) / 2; 44 | return join(join(v, l, m), join(v, m, r)); 45 | } 46 | public: 47 | explicit aug_treap(T e, int seed = std::chrono::steady_clock::now().time_since_epoch().count()) : op(Op()), e(e), rng(seed) {} 48 | node* make(T value) { return new node(value, 1, rand()); } 49 | int size_of(node* a) const { 50 | return a ? a->cnt : 0; 51 | } 52 | T aug(node* a) const { 53 | return a ? a->aug : e; 54 | } 55 | node* root(node* a) const { 56 | if (!a) return nullptr; 57 | while (a->p) a = a->p; 58 | return a; 59 | } 60 | int index_of(node* a) const { 61 | assert(a); 62 | int idx = size_of(a->l); 63 | while (a->p) { 64 | node* p = a->p; 65 | if (p->r == a) idx += 1 + size_of(p->l); 66 | a = p; 67 | } 68 | return idx; 69 | } 70 | template std::pair lower_bound(node* a, F f) { 71 | int idx = 0; 72 | node* p = nullptr; 73 | while (a) { 74 | if (f(a)) { 75 | idx += 1 + size_of(a->l); 76 | a = a->r; 77 | } else { 78 | p = a; 79 | a = a->l; 80 | } 81 | } 82 | return {p, idx}; 83 | } 84 | node* at(node* a, int k) const { 85 | while (a) { 86 | int s = size_of(a->l); 87 | if (k == s) { 88 | return a; 89 | } else if (k < s) { 90 | a = a->l; 91 | } else { 92 | k -= 1 + s; 93 | a = a->r; 94 | } 95 | } 96 | return nullptr; 97 | } 98 | std::pair split(node* a, int k) { 99 | node *l, *r; 100 | split(a, l, r, k); 101 | if (l) l->p = nullptr; 102 | if (r) r->p = nullptr; 103 | return {l, r}; 104 | } 105 | node* join(node* a, node* b) { 106 | if (!a) return b; 107 | if (!b) return a; 108 | if (a->y > b->y) { 109 | a->r = join(a->r, b); 110 | if (a->r) a->r->p = a; 111 | return update(a), a; 112 | } else { 113 | b->l = join(a, b->l); 114 | if (b->l) b->l->p = b; 115 | return update(b), b; 116 | } 117 | } 118 | node* join(const std::vector& v) { 119 | return join(v, 0, v.size()); 120 | } 121 | template void for_each(node* a, F f) const { 122 | if (!a) return; 123 | if (a->l) for_each(a->l, f); 124 | f(a); 125 | if (a->r) for_each(a->r, f); 126 | } 127 | node* insert(node* root, int k, node* u) { 128 | node *l, *r; 129 | split(root, l, r, k); 130 | return join({l, u, r}); 131 | } 132 | node* erase(node* root, int k) { 133 | node *l, *m, *r; 134 | split(root, l, r, k); 135 | split(r, m, r, 1); 136 | return join(l, r); 137 | } 138 | void set(node* root, int k, T value) { 139 | node* x = at(root, k); 140 | if (!x) return; 141 | x->value = value; 142 | while (x) { 143 | update(x); 144 | x = x->p; 145 | } 146 | } 147 | T query(node* root, int l, int r) { 148 | if (r <= 0 || l >= size_of(root)) return e; 149 | if (l <= 0 && r >= size_of(root)) return aug(root); 150 | int k = size_of(root->l); 151 | T res = query(root->l, l, r); 152 | if (k >= l && k < r) { 153 | res = op(res, root->value); 154 | } 155 | res = op(res, query(root->r, l - k - 1, r - k - 1)); 156 | return res; 157 | } 158 | }; 159 | -------------------------------------------------------------------------------- /source/data-structures/bit.h: -------------------------------------------------------------------------------- 1 | 2 | template 3 | struct bit { 4 | int n, lg; 5 | vector a; 6 | bit(int n) : n(n), a(n) { 7 | lg = 0; 8 | while(2 * (1 << lg) < n) lg++; 9 | } 10 | void add(int i, T x) { 11 | while(i < n) { 12 | a[i] = a[i] + x; 13 | i += i & -i; 14 | } 15 | } 16 | T get(int i) { 17 | T x = T(); 18 | while(i > 0) { 19 | x = x + a[i]; 20 | i -= i & -i; 21 | } 22 | return x; 23 | } 24 | int lower_bound(T val) { 25 | int i = 0; 26 | T sum = T(); 27 | for(int k = lg; k >= 0; k--) { 28 | if(i + (1 << k) < n && sum + a[i + (1 << k)] < val) { 29 | i += (1 << k); 30 | sum = sum + a[i]; 31 | } 32 | } 33 | return i + 1; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /source/data-structures/bit_vector.h: -------------------------------------------------------------------------------- 1 | 2 | inline size_t BLOCK(size_t i) { return i >> 6; } 3 | inline size_t BIT(size_t i) { return i & 63; } 4 | inline uint64_t FLAG(size_t bit) { return 1ull << bit; } 5 | inline uint64_t LAST_MASK(size_t n) { return 0xFFFF'FFFF'FFFF'FFFFull >> (63 - BIT(n - 1)); } 6 | 7 | class bit_vector { 8 | private: 9 | vector _a; 10 | size_t _n; 11 | public: 12 | bit_vector(size_t n = 0) { 13 | _n = n; 14 | size_t m = (n + 63) / 64; 15 | _a.assign(m, 0); 16 | } 17 | bit_vector(vector v) : _a(v) { _n = v.size() * 64; } 18 | bool test(size_t i) const { return _a[BLOCK(i)] >> BIT(i) & 1; } 19 | void reset(size_t i) { _a[BLOCK(i)] &= ~FLAG(BIT(i)); } 20 | void set(size_t i) { _a[BLOCK(i)] |= FLAG(BIT(i)); } 21 | void set(size_t i, bool val) { 22 | size_t k = BLOCK(i); 23 | size_t bit = BIT(i); 24 | if (val) _a[k] |= FLAG(bit); 25 | else _a[k] &= ~FLAG(bit); 26 | } 27 | void flip(size_t i) { _a[BLOCK(i)] ^= FLAG(BIT(i)); } 28 | size_t size() const { return _n; } 29 | size_t count() const { 30 | size_t ans = 0; 31 | for (size_t k = 0; k < _a.size(); k++) 32 | ans += __builtin_popcountll(_a[k]); 33 | return ans; 34 | } 35 | bool is_all() const { 36 | if (_n == 0) return true; 37 | size_t l = _a.size() - 1; 38 | for (size_t k = 0; k < l; k++) 39 | if (_a[k] != ~0ull) return false; 40 | return _a[l] == LAST_MASK(_n); 41 | } 42 | bool is_any() const { 43 | for (size_t k = 0; k < _a.size(); k++) 44 | if (_a[k] != 0ull) return true; 45 | return false; 46 | } 47 | bool is_none() const { 48 | for (size_t k = 0; k < _a.size(); k++) { 49 | if (_a[k] != 0ull) { 50 | return false; 51 | } 52 | } 53 | return true; 54 | } 55 | bit_vector operator~() const { 56 | bit_vector out(_n); 57 | if (_n == 0) return out; 58 | size_t l = _a.size() - 1; 59 | for (size_t k = 0; k < l; k++) out._a[k] = ~_a[k]; 60 | out._a[l] = ~_a[l] & LAST_MASK(_n); 61 | return out; 62 | } 63 | bit_vector operator|(const bit_vector &b) const { 64 | bit_vector out(max(_n, b._n)); 65 | size_t m = min(_a.size(), b._a.size()); 66 | for (size_t k = 0; k < m; k++) { 67 | out._a[k] = _a[k] | b._a[k]; 68 | } 69 | if (_a.size() > m) { 70 | copy(_a.begin() + m, _a.end(), out._a.begin() + m); 71 | } else if (b._a.size() > m) { 72 | copy(b._a.begin() + m, b._a.end(), out._a.begin() + m); 73 | } 74 | return out; 75 | } 76 | bit_vector operator&(const bit_vector &b) const { 77 | bit_vector out(max(_n, b._n)); 78 | size_t m = min(_a.size(), b._a.size()); 79 | for (size_t k = 0; k < m; k++) out._a[k] = _a[k] & b._a[k]; 80 | return out; 81 | } 82 | bit_vector operator^(const bit_vector &b) const { 83 | bit_vector out(max(_n, b._n)); 84 | size_t m = min(_a.size(), b._a.size()); 85 | for (size_t k = 0; k < m; k++) out._a[k] = _a[k] ^ b._a[k]; 86 | return out; 87 | } 88 | bit_vector& operator|=(const bit_vector &b) { 89 | if (_n == 0) return *this; 90 | size_t m = min(_a.size(), b._a.size()); 91 | for (size_t k = 0; k < m; k++) _a[k] |= b._a[k]; 92 | size_t l = _a.size() - 1; 93 | _a[l] &= LAST_MASK(_n); 94 | return *this; 95 | } 96 | bit_vector& operator&=(const bit_vector &b) { 97 | size_t m = min(_a.size(), b._a.size()); 98 | for (size_t k = 0; k < m; k++) _a[k] &= b._a[k]; 99 | fill(_a.begin() + m, _a.end(), 0ull); 100 | return *this; 101 | } 102 | bit_vector& operator^=(const bit_vector &b) { 103 | size_t m = min(_a.size(), b._a.size()); 104 | for (size_t k = 0; k < m; k++) _a[k] ^= b._a[k]; 105 | return *this; 106 | } 107 | bit_vector operator<<(const size_t i) const { 108 | bit_vector out(_n); 109 | size_t s = BLOCK(i); 110 | size_t m = _a.size(); 111 | if (_n == 0 || s >= m) return out; 112 | size_t t = BIT(i); 113 | if (t == 0) { 114 | copy(_a.begin(), _a.begin() + m, out._a.begin() + s); 115 | } else { 116 | out._a[s] = _a[0] << t; 117 | for (size_t k = s + 1; k < m; k++) 118 | out._a[k] = (_a[k - s] << t) | (_a[k - s - 1] >> (64 - t)); 119 | } 120 | size_t l = _a.size() - 1; 121 | out._a[l] &= LAST_MASK(_n); 122 | return out; 123 | } 124 | bit_vector operator>>(size_t i) const { 125 | bit_vector out(_n); 126 | size_t s = BLOCK(i); 127 | size_t m = _a.size(); 128 | if (_n == 0 || s >= m) return out; 129 | size_t t = BIT(i); 130 | if (t == 0) { 131 | copy(_a.begin() + s, _a.end(), out._a.begin()); 132 | } else { 133 | for (size_t k = 0; k < m - s - 1; k++) 134 | out._a[k] = (_a[k + s] >> t) | (_a[k + s + 1] << (64 - t)); 135 | out._a[m - s - 1] = _a[m - 1] >> t; 136 | } 137 | return out; 138 | } 139 | bit_vector& operator<<=(size_t i) { return *this = *this << i; } 140 | bit_vector& operator>>=(size_t i) { return *this = *this >> i; } 141 | void resize(size_t n) { 142 | size_t m = (n + 63) / 64; 143 | if (n < _n && n > 0) _a[m - 1] &= LAST_MASK(n); 144 | _n = n; 145 | _a.resize(m); 146 | } 147 | uint64_t block(size_t i) const { return i < _a.size() ? _a[i] : 0; } 148 | void paste_block(size_t i, uint64_t value) { 149 | if (i >= _a.size()) return; 150 | _a[i] = value; 151 | if (i == _a.size() - 1) _a[i] &= LAST_MASK(_n); 152 | } 153 | }; -------------------------------------------------------------------------------- /source/data-structures/depq.h: -------------------------------------------------------------------------------- 1 | 2 | #include "lazy_pq.h" 3 | 4 | template 5 | struct depq { 6 | lazy_pq q_max; 7 | lazy_pq> q_min; 8 | 9 | depq() {} 10 | depq(const vector &ve) : q_max(ve), q_min(ve) {} 11 | 12 | size_t size() { 13 | return q_max.size(); 14 | } 15 | void push(T x) { 16 | q_max.push(x); 17 | q_min.push(x); 18 | } 19 | T get_min() { 20 | return q_min.top(); 21 | } 22 | T get_max() { 23 | return q_max.top(); 24 | } 25 | void pop_min() { 26 | q_max.erase(q_min.top()); 27 | q_min.pop(); 28 | } 29 | void pop_max() { 30 | q_min.erase(q_max.top()); 31 | q_max.pop(); 32 | } 33 | void erase(T x) { 34 | q_min.erase(x); 35 | q_max.erase(x); 36 | } 37 | }; -------------------------------------------------------------------------------- /source/data-structures/dp.h: -------------------------------------------------------------------------------- 1 | 2 | template 3 | struct DPNode { 4 | T val; 5 | std::optional data; 6 | std::vector children; 7 | 8 | static std::vector nodes; 9 | static int make(const DPNode& node); 10 | void dfs(std::vector &out) { 11 | if (data) { 12 | out.push_back(data.value()); 13 | } 14 | for (int child : children) { 15 | nodes[child].dfs(out); 16 | } 17 | } 18 | }; 19 | 20 | template 21 | std::vector> DPNode::nodes; 22 | 23 | template 24 | int DPNode::make(const DPNode& node) { 25 | int id = nodes.size(); 26 | nodes.push_back(node); 27 | return id; 28 | } 29 | 30 | template 31 | struct DP { 32 | using Node = DPNode; 33 | int id; 34 | DP(T val, std::optional data = std::nullopt, std::vector children = {}) { 35 | id = Node::make({val, data, children}); 36 | } 37 | operator T() const { 38 | return Node::nodes[id].val; 39 | } 40 | T operator()() const { 41 | return Node::nodes[id].val; 42 | } 43 | DP operator+(const DP &o) const { 44 | return DP(Node::nodes[id].val + Node::nodes[o.id].val, std::nullopt, {id, o.id}); 45 | } 46 | DP operator-(const DP &o) const { 47 | return DP(Node::nodes[id].val - Node::nodes[o.id].val, std::nullopt, {id, o.id}); 48 | } 49 | DP operator*(const DP &o) const { 50 | return DP(Node::nodes[id].val * Node::nodes[o.id].val, std::nullopt, {id, o.id}); 51 | } 52 | DP operator/(const DP &o) const { 53 | return DP(Node::nodes[id].val / Node::nodes[o.id].val, std::nullopt, {id, o.id}); 54 | } 55 | DP operator%(const DP &o) const { 56 | return DP(Node::nodes[id].val % Node::nodes[o.id].val, std::nullopt, {id, o.id}); 57 | } 58 | DP operator^(const DP &o) const { 59 | return DP(Node::nodes[id].val ^ Node::nodes[o.id].val, std::nullopt, {id, o.id}); 60 | } 61 | DP operator|(const DP &o) const { 62 | return DP(Node::nodes[id].val | Node::nodes[o.id].val, std::nullopt, {id, o.id}); 63 | } 64 | DP operator&(const DP &o) const { 65 | return DP(Node::nodes[id].val & Node::nodes[o.id].val, std::nullopt, {id, o.id}); 66 | } 67 | bool operator<(const DP &o) const { 68 | return Node::nodes[id].val < Node::nodes[o.id].val; 69 | } 70 | bool operator>(const DP &o) const { 71 | return Node::nodes[id].val > Node::nodes[o.id].val; 72 | } 73 | bool operator<=(const DP &o) const { 74 | return Node::nodes[id].val <= Node::nodes[o.id].val; 75 | } 76 | bool operator>=(const DP &o) const { 77 | return Node::nodes[id].val >= Node::nodes[o.id].val; 78 | } 79 | bool operator==(const DP &o) const { 80 | return Node::nodes[id].val == Node::nodes[o.id].val; 81 | } 82 | bool operator!=(const DP &o) const { 83 | return Node::nodes[id].val != Node::nodes[o.id].val; 84 | } 85 | DP& tag(D data) { 86 | Node::nodes[id].data = data; 87 | return *this; 88 | } 89 | std::vector trace() const { 90 | std::vector out; 91 | Node::nodes[id].dfs(out); 92 | return out; 93 | } 94 | }; 95 | -------------------------------------------------------------------------------- /source/data-structures/dsu.h: -------------------------------------------------------------------------------- 1 | 2 | struct dsu { 3 | vector a; 4 | dsu(int n) : a(n, -1) {} 5 | int find(int x) { 6 | return a[x] < 0 ? x : a[x] = find(a[x]); 7 | } 8 | int size(int x) { 9 | return -a[find(x)]; 10 | } 11 | bool join(int x, int y) { 12 | if((x = find(x)) == (y = find(y))) return false; 13 | if(a[x] > a[y]) swap(x, y); 14 | a[x] += a[y]; 15 | a[y] = x; 16 | return true; 17 | } 18 | }; -------------------------------------------------------------------------------- /source/data-structures/hash_map.h: -------------------------------------------------------------------------------- 1 | 2 | struct custom_hash { 3 | static inline uint64_t splitmix64(uint64_t x) { 4 | // http://xorshift.di.unimi.it/splitmix64.c 5 | x += 0x9e3779b97f4a7c15; 6 | x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; 7 | x = (x ^ (x >> 27)) * 0x94d049bb133111eb; 8 | return x ^ (x >> 31); 9 | } 10 | 11 | size_t operator()(uint64_t x) const { 12 | static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); 13 | return splitmix64(x + FIXED_RANDOM); 14 | } 15 | }; 16 | 17 | template 18 | struct hash_map : unordered_map { 19 | T get(long long i) const { 20 | auto it = this->find(i); 21 | return it != this->end() ? it->second : T(); 22 | } 23 | }; -------------------------------------------------------------------------------- /source/data-structures/int_set.h: -------------------------------------------------------------------------------- 1 | 2 | template 3 | struct int_set { 4 | int lg; 5 | int n_blocks; 6 | bitset b; 7 | vector a; 8 | bit() { 9 | n_blocks = (N + 63) / 64; 10 | lg = 0; 11 | while(2 * (1 << lg) < n_blocks) lg++; 12 | a.assign(n_blocks, 0); 13 | } 14 | void build() { 15 | 16 | } 17 | void _add(int i, int x) { 18 | while(i < n) { 19 | a[i] = a[i] + x; 20 | i += i & -i; 21 | } 22 | } 23 | T _get(int i) const { 24 | T x = T(); 25 | while(i > 0) { 26 | x = x + a[i]; 27 | i -= i & -i; 28 | } 29 | return x; 30 | } 31 | int _lower_bound(int val) { 32 | int i = 0; 33 | int sum = 0; 34 | for(int k = lg; k >= 0; k--) { 35 | if(i + (1 << k) < n && sum + a[i + (1 << k)] < val) { 36 | i += (1 << k); 37 | sum = sum + a[i]; 38 | } 39 | } 40 | return i + 1; 41 | } 42 | }; 43 | 44 | istream& operator>>(istream& in, int_set s) { 45 | in >> s.b; 46 | s.build(); 47 | return in; 48 | } 49 | -------------------------------------------------------------------------------- /source/data-structures/lazy_pq.h: -------------------------------------------------------------------------------- 1 | 2 | template > 3 | struct lazy_pq { 4 | priority_queue, Compare> q, d; 5 | lazy_pq() {} 6 | lazy_pq(const vector &ve) : q(Compare(), ve) {} 7 | size_t size() { return q.size() - d.size(); } 8 | void push(T x) { q.push(x); } 9 | void clean() { 10 | Compare comp; 11 | while (!q.empty() && !d.empty() && !comp(d.top(), q.top())) { 12 | q.pop(); 13 | d.pop(); 14 | } 15 | } 16 | T top() { 17 | clean(); 18 | return q.top(); 19 | } 20 | void pop() { 21 | clean(); 22 | q.pop(); 23 | } 24 | void erase(T x) { 25 | d.push(x); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /source/data-structures/lazy_segtree.h: -------------------------------------------------------------------------------- 1 | 2 | template > 3 | struct min_op { 4 | Compare comp; 5 | inline T operator()(const T& a, const T& b) const { return comp(a, b) ? a : b; } 6 | }; 7 | template > 8 | struct max_op { 9 | Compare comp; 10 | inline T operator()(const T& a, const T& b) const { return comp(a, b) ? b : a; } 11 | }; 12 | template 13 | struct gcd_op { 14 | inline T operator()(const T& a, const T& b) const { return std::gcd(a, b); } 15 | }; 16 | template 17 | struct lazy_segtree { 18 | private: 19 | int n, si, lg; 20 | Op op; 21 | Apply apply; 22 | Compose compose; 23 | T e; 24 | F id; 25 | std::vector d; 26 | std::vector z; 27 | void upd(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); } 28 | void all_apply(int k, F f) { 29 | d[k] = apply(f, d[k]); 30 | if (k < si) z[k] = compose(f, z[k]); 31 | } 32 | void push(int k) { 33 | all_apply(2 * k, z[k]); 34 | all_apply(2 * k + 1, z[k]); 35 | z[k] = id; 36 | } 37 | public: 38 | explicit lazy_segtree(int n, T e, F id) : lazy_segtree(std::vector(n, e), e, id) {} 39 | explicit lazy_segtree(const std::vector& v, T e, F id) : n(v.size()), e(e), id(id) { 40 | si = 1; 41 | lg = 0; 42 | while (si < n) { 43 | lg++; 44 | si <<= 1; 45 | } 46 | d.assign(2 * si, e); 47 | z.assign(si, id); 48 | std::copy(v.begin(), v.end(), d.begin() + si); 49 | for (int i = si - 1; i >= 1; i--) upd(i); 50 | } 51 | int size() const { return n; } 52 | T get(int p) { 53 | assert(0 <= p && p < n); 54 | p += si; 55 | for (int i = lg; i >= 1; i--) push(p >> i); 56 | return d[p]; 57 | } 58 | void set(int p, T x) { 59 | assert(0 <= p && p < n); 60 | p += si; 61 | for (int i = lg; i >>= 1; i--) push(p >> i); 62 | d[p] = x; 63 | for (int i = 1; i <= lg; i++) upd(p >> i); 64 | } 65 | T query(int l, int r) { 66 | assert(0 <= l && l <= r && r <= n); 67 | if (l == r) return e; 68 | l += si; r += si; 69 | for (int i = lg; i >= 1; i--) { 70 | if (((l >> i) << i) != l) push(l >> i); 71 | if (((r >> i) << i) != r) push((r - 1) >> i); 72 | } 73 | T le = e, ri = e; 74 | while (l < r) { 75 | if (l & 1) le = op(le, d[l++]); 76 | if (r & 1) ri = op(d[--r], ri); 77 | l >>= 1; r >>= 1; 78 | } 79 | return op(le, ri); 80 | } 81 | T query() const { return d[1]; } 82 | void update(int p, F f) { 83 | assert(0 <= p && p < n); 84 | p += si; 85 | for (int i = lg; i >= 1; i--) push(p >> i); 86 | d[p] = apply(f, d[p]); 87 | for (int i = 1; i <= lg; i++) upd(p >> i); 88 | } 89 | void update(int l, int r, F f) { 90 | assert(0 <= l && l <= r && r <= n); 91 | if (l == r) return; 92 | l += si; r += si; 93 | for (int i = lg; i >= 1; i--) { 94 | if (((l >> i) << i) != l) push(l >> i); 95 | if (((r >> i) << i) != r) push((r - 1) >> i); 96 | } 97 | int l2 = l, r2 = r; 98 | while (l < r) { 99 | if (l & 1) all_apply(l++, f); 100 | if (r & 1) all_apply(--r, f); 101 | l >>= 1; r >>= 1; 102 | } 103 | l = l2; 104 | r = r2; 105 | for (int i = 1; i <= lg; i++) { 106 | if (((l >> i) << i) != l) upd(l >> i); 107 | if (((r >> i) << i) != r) upd((r - 1) >> i); 108 | } 109 | } 110 | template int max_right(int l, G g) { 111 | assert(0 <= l && l <= n); 112 | assert(g(e)); 113 | if (l == n) return n; 114 | l += si; 115 | for (int i = lg; i >= 1; i--) push(l >> i); 116 | T sm = e; 117 | do { 118 | while (l % 2 == 0) l >>= 1; 119 | if (!g(op(sm, d[l]))) { 120 | while (l < si) { 121 | push(l); 122 | l = 2 * l; 123 | if (g(op(sm, d[l]))) { 124 | sm = op(sm, d[l]); 125 | l++; 126 | } 127 | } 128 | return l - si; 129 | } 130 | sm = op(sm, d[l]); 131 | l++; 132 | } while ((l & -l) != l); 133 | return n; 134 | } 135 | template int min_left(int r, G g) { 136 | assert(0 <= r && r <= n); 137 | assert(g(e)); 138 | if (r == 0) return 0; 139 | r += si; 140 | for (int i = log; i >= 1; i--) push((r - 1) >> i); 141 | T sm = e; 142 | do { 143 | r--; 144 | while (r > 1 && (r % 2)) r >>= 1; 145 | if (!g(op(d[r], sm))) { 146 | while (r < si) { 147 | push(r); 148 | r = 2 * r + 1; 149 | if (g(op(d[r], sm))) { 150 | sm = op(d[r], sm); 151 | r--; 152 | } 153 | } 154 | return r + 1 - size; 155 | } 156 | sm = op(d[r], sm); 157 | } while ((r & -r) != r); 158 | return 0; 159 | } 160 | }; 161 | -------------------------------------------------------------------------------- /source/data-structures/noam.h: -------------------------------------------------------------------------------- 1 | 2 | // struct update { 3 | // bool type; 4 | // update() { 5 | // type = 0; 6 | // } 7 | // }; 8 | 9 | template 10 | struct noam : public D { 11 | vector s; 12 | void push(const U &u) { 13 | D::push(u); 14 | s.push_back(u); 15 | } 16 | void pop() { 17 | auto i = s.end(); 18 | int c = 0; 19 | do { 20 | c += (--i)->type ? 1 : -1; 21 | D::pop(); 22 | }while(c < 0 && i != s.begin()); 23 | auto j = stable_partition(i, s.end(), [](auto &x) { return !x.type; }); 24 | if(i == s.begin()) { 25 | reverse(i, j); 26 | for_each(i, j, [](auto &x) { x.type = 1; }); 27 | } 28 | s.pop_back(); 29 | while(i != s.end()) D::push(*i), i++; 30 | } 31 | }; -------------------------------------------------------------------------------- /source/data-structures/offline_deletion.h: -------------------------------------------------------------------------------- 1 | 2 | // struct ds { 3 | // void push(U u); 4 | // void pop(); 5 | // Q query(); 6 | // }; 7 | 8 | template 9 | struct offline_deletion : public D { 10 | vector ans; 11 | vector> updates; 12 | int q; 13 | offline_deletion(int queries) : q(queries), ans(q) { 14 | int lg = 0; 15 | while((1 << lg) < q) lg++; 16 | updates.resize(1 << (lg + 1)); 17 | } 18 | void update(int i, int l, int r, int L, int R, U u) { 19 | if(r < L || R < l) return; 20 | if(L <= l && r <= R) { 21 | updates[i].push_back(u); 22 | return; 23 | } 24 | int m = (l + r) / 2; 25 | update(2 * i + 1, l, m, L, R, u); 26 | update(2 * i + 2, m + 1, r, L, R, u); 27 | } 28 | void insert(U u, int l, int r) { 29 | update(0, 0, q - 1, l, r, u); 30 | } 31 | void insert(U u, int l) { 32 | insert(u, l, q - 1); 33 | } 34 | void solve(int i, int l, int r) { 35 | for(auto &u : updates[i]) { 36 | D::push(u); 37 | } 38 | if(l == r) { 39 | ans[l] = D::query(); 40 | }else { 41 | int m = (l + r) / 2; 42 | solve(2 * i + 1, l, m); 43 | solve(2 * i + 2, m + 1, r); 44 | } 45 | for(int j = 0; j < (int) updates[i].size(); j++) { 46 | D::pop(); 47 | } 48 | } 49 | void solve() { 50 | solve(0, 0, q - 1); 51 | } 52 | }; 53 | -------------------------------------------------------------------------------- /source/data-structures/rev_aug_treap.h: -------------------------------------------------------------------------------- 1 | 2 | template 3 | struct rev_aug_treap { 4 | public: 5 | struct node { 6 | T value; 7 | T aug; 8 | int cnt, y; 9 | node *l, *r, *p; 10 | bool flip; 11 | node(T value, int cnt, int y) : value(value), aug(value), cnt(cnt), y(y), l(nullptr), r(nullptr), p(nullptr), flip(false) {} 12 | }; 13 | private: 14 | Op op; 15 | Flop flop; 16 | T e; 17 | std::mt19937 rng; 18 | int rand() { 19 | std::uniform_int_distribution uni(0, INT_MAX); 20 | return uni(rng); 21 | } 22 | void update(node* a) { 23 | assert(a); 24 | a->cnt = 1 + size_of(a->l) + size_of(a->r); 25 | a->aug = op(op(aug(a->l), a->value), aug(a->r)); 26 | } 27 | void push(node* a) { 28 | if (!a->flip) return; 29 | if (a->l) flip(a->l); 30 | if (a->r) flip(a->r); 31 | a->flip = false; 32 | } 33 | void split(node* a, node*& l, node*& r, int k) { 34 | if (!a) return void(l = r = nullptr); 35 | push(a); 36 | if (size_of(a->l) < k) { 37 | split(a->r, a->r, r, k - size_of(a->l) - 1); 38 | if (a->r) a->r->p = a; 39 | l = a; 40 | update(a); 41 | } else { 42 | split(a->l, l, a->l, k); 43 | if (a->l) a->l->p = a; 44 | r = a; 45 | update(a); 46 | } 47 | } 48 | node* join(const std::vector& v, int l, int r) { 49 | assert(0 <= l && l <= r && r <= (int) v.size()); 50 | if (l == r) return nullptr; 51 | if (r - l == 1) return v[l]; 52 | int m = l + (r - l) / 2; 53 | return join(join(v, l, m), join(v, m, r)); 54 | } 55 | void access(node* a) { 56 | if (!a) return; 57 | access(a->p); 58 | push(a); 59 | } 60 | public: 61 | explicit rev_aug_treap(T e, int seed = std::chrono::steady_clock::now().time_since_epoch().count()) : op(Op()), flop(Flop()), e(e), rng(seed) {} 62 | node* make(T value) { return new node(value, 1, rand()); } 63 | int size_of(node* a) const { 64 | return a ? a->cnt : 0; 65 | } 66 | T aug(node* a) const { 67 | return a ? a->aug : e; 68 | } 69 | node* root(node* a) const { 70 | if (!a) return nullptr; 71 | while (a->p) a = a->p; 72 | return a; 73 | } 74 | void flip(node* a) { 75 | if (!a) return; 76 | swap(a->l, a->r); 77 | a->flip = !a->flip; 78 | if (a->flip) { 79 | a->aug = op(op(flop(aug(a->l)), a->value), flop(aug(a->r))); 80 | } else { 81 | a->aug = op(op(aug(a->l), a->value), aug(a->r)); 82 | } 83 | } 84 | int index_of(node* a) { 85 | assert(a); 86 | access(a); 87 | int idx = size_of(a->l); 88 | while (a->p) { 89 | node* p = a->p; 90 | if (p->r == a) idx += 1 + size_of(p->l); 91 | a = p; 92 | } 93 | return idx; 94 | } 95 | template std::pair lower_bound(node* a, F f) { 96 | int idx = 0; 97 | node* p = nullptr; 98 | while (a) { 99 | push(a); 100 | if (f(a)) { 101 | idx += 1 + size_of(a->l); 102 | a = a->r; 103 | } else { 104 | p = a; 105 | a = a->l; 106 | } 107 | } 108 | return {p, idx}; 109 | } 110 | node* at(node* a, int k) { 111 | while (a) { 112 | push(a); 113 | int s = size_of(a->l); 114 | if (k == s) { 115 | return a; 116 | } else if (k < s) { 117 | a = a->l; 118 | } else { 119 | k -= 1 + s; 120 | a = a->r; 121 | } 122 | } 123 | return nullptr; 124 | } 125 | std::pair split(node* a, int k) { 126 | node *l, *r; 127 | split(a, l, r, k); 128 | if (l) l->p = nullptr; 129 | if (r) r->p = nullptr; 130 | return {l, r}; 131 | } 132 | node* join(node* a, node* b) { 133 | if (!a) return b; 134 | if (!b) return a; 135 | if (a->y > b->y) { 136 | push(a); 137 | a->r = join(a->r, b); 138 | if (a->r) a->r->p = a; 139 | return update(a), a; 140 | } else { 141 | push(b); 142 | b->l = join(a, b->l); 143 | if (b->l) b->l->p = b; 144 | return update(b), b; 145 | } 146 | } 147 | node* join(const std::vector& v) { 148 | return join(v, 0, v.size()); 149 | } 150 | template void for_each(node* a, F f) { 151 | if (!a) return; 152 | push(a); 153 | if (a->l) for_each(a->l, f); 154 | f(a); 155 | if (a->r) for_each(a->r, f); 156 | } 157 | node* insert(node* root, int k, node* u) { 158 | node *l, *r; 159 | split(root, l, r, k); 160 | return join({l, u, r}); 161 | } 162 | node* erase(node* root, int k) { 163 | node *l, *m, *r; 164 | split(root, l, r, k); 165 | split(r, m, r, 1); 166 | return join(l, r); 167 | } 168 | void set(node* root, int k, T value) { 169 | node* x = at(root, k); 170 | if (!x) return; 171 | x->value = value; 172 | while (x) { 173 | update(x); 174 | x = x->p; 175 | } 176 | } 177 | T query(node* root, int l, int r) { 178 | if (r <= 0 || l >= size_of(root)) return e; 179 | if (l <= 0 && r >= size_of(root)) return aug(root); 180 | push(root); 181 | int k = size_of(root->l); 182 | T res = query(root->l, l, r); 183 | if (k >= l && k < r) { 184 | res = op(res, root->value); 185 | } 186 | res = op(res, query(root->r, l - k - 1, r - k - 1)); 187 | return res; 188 | } 189 | }; 190 | -------------------------------------------------------------------------------- /source/data-structures/rev_treap.h: -------------------------------------------------------------------------------- 1 | 2 | template 3 | struct rev_treap { 4 | public: 5 | struct node { 6 | T value; 7 | int cnt, y; 8 | node *l, *r, *p; 9 | bool flip; 10 | node(T value, int cnt, int y) : value(value), cnt(cnt), y(y), l(nullptr), r(nullptr), p(nullptr), flip(false) {} 11 | }; 12 | private: 13 | std::mt19937 rng; 14 | int rand() { 15 | std::uniform_int_distribution uni(0, INT_MAX); 16 | return uni(rng); 17 | } 18 | void update(node* a) { 19 | assert(a); 20 | a->cnt = 1 + size_of(a->l) + size_of(a->r); 21 | } 22 | void push(node* a) { 23 | if (!a->flip) return; 24 | if (a->l) flip(a->l); 25 | if (a->r) flip(a->r); 26 | a->flip = false; 27 | } 28 | void split(node* a, node*& l, node*& r, int k) { 29 | if (!a) return void(l = r = nullptr); 30 | push(a); 31 | if (size_of(a->l) < k) { 32 | split(a->r, a->r, r, k - size_of(a->l) - 1); 33 | if (a->r) a->r->p = a; 34 | l = a; 35 | update(a); 36 | } else { 37 | split(a->l, l, a->l, k); 38 | if (a->l) a->l->p = a; 39 | r = a; 40 | update(a); 41 | } 42 | } 43 | node* join(const std::vector& v, int l, int r) { 44 | assert(0 <= l && l <= r && r <= (int) v.size()); 45 | if (l == r) return nullptr; 46 | if (r - l == 1) return v[l]; 47 | int m = l + (r - l) / 2; 48 | return join(join(v, l, m), join(v, m, r)); 49 | } 50 | void access(node* a) { 51 | if (!a) return; 52 | access(a->p); 53 | push(a); 54 | } 55 | public: 56 | explicit rev_treap(int seed = std::chrono::steady_clock::now().time_since_epoch().count()) : rng(seed) {} 57 | node* make(T value) { return new node(value, 1, rand()); } 58 | int size_of(node* a) const { 59 | return a ? a->cnt : 0; 60 | } 61 | node* root(node* a) const { 62 | if (!a) return nullptr; 63 | while (a->p) a = a->p; 64 | return a; 65 | } 66 | void flip(node* a) { 67 | if (!a) return; 68 | swap(a->l, a->r); 69 | a->flip = !a->flip; 70 | } 71 | int index_of(node* a) { 72 | assert(a); 73 | access(a); 74 | int idx = size_of(a->l); 75 | while (a->p) { 76 | node* p = a->p; 77 | if (p->r == a) idx += 1 + size_of(p->l); 78 | a = p; 79 | } 80 | return idx; 81 | } 82 | template std::pair lower_bound(node* a, F f) { 83 | int idx = 0; 84 | node* p = nullptr; 85 | while (a) { 86 | push(a); 87 | if (f(a)) { 88 | idx += 1 + size_of(a->l); 89 | a = a->r; 90 | } else { 91 | p = a; 92 | a = a->l; 93 | } 94 | } 95 | return {p, idx}; 96 | } 97 | node* at(node* a, int k) { 98 | while (a) { 99 | push(a); 100 | int s = size_of(a->l); 101 | if (k == s) { 102 | return a; 103 | } else if (k < s) { 104 | a = a->l; 105 | } else { 106 | k -= 1 + s; 107 | a = a->r; 108 | } 109 | } 110 | return nullptr; 111 | } 112 | std::pair split(node* a, int k) { 113 | node *l, *r; 114 | split(a, l, r, k); 115 | if (l) l->p = nullptr; 116 | if (r) r->p = nullptr; 117 | return {l, r}; 118 | } 119 | node* join(node* a, node* b) { 120 | if (!a) return b; 121 | if (!b) return a; 122 | if (a->y > b->y) { 123 | push(a); 124 | a->r = join(a->r, b); 125 | if (a->r) a->r->p = a; 126 | return update(a), a; 127 | } else { 128 | push(b); 129 | b->l = join(a, b->l); 130 | if (b->l) b->l->p = b; 131 | return update(b), b; 132 | } 133 | } 134 | node* join(const std::vector& v) { 135 | return join(v, 0, v.size()); 136 | } 137 | template void for_each(node* a, F f) { 138 | if (!a) return; 139 | push(a); 140 | if (a->l) for_each(a->l, f); 141 | f(a); 142 | if (a->r) for_each(a->r, f); 143 | } 144 | node* insert(node* root, int k, node* u) { 145 | node *l, *r; 146 | split(root, l, r, k); 147 | return join({l, u, r}); 148 | } 149 | node* erase(node* root, int k) { 150 | node *l, *m, *r; 151 | split(root, l, r, k); 152 | split(r, m, r, 1); 153 | return join(l, r); 154 | } 155 | }; 156 | -------------------------------------------------------------------------------- /source/data-structures/segtree.h: -------------------------------------------------------------------------------- 1 | 2 | template > 3 | struct min_op { 4 | Compare comp; 5 | inline T operator()(const T& a, const T& b) const { return comp(a, b) ? a : b; } 6 | }; 7 | template > 8 | struct max_op { 9 | Compare comp; 10 | inline T operator()(const T& a, const T& b) const { return comp(a, b) ? b : a; } 11 | }; 12 | template 13 | struct gcd_op { 14 | inline T operator()(const T& a, const T& b) const { return std::gcd(a, b); } 15 | }; 16 | template 17 | struct segtree { 18 | private: 19 | int n, si, lg; 20 | Op op; 21 | T e; 22 | std::vector d; 23 | void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); } 24 | public: 25 | explicit segtree(int n, T e) : segtree(std::vector(n, e), e) {} 26 | explicit segtree(const std::vector& v, T e) : n(v.size()), op(Op()), e(e) { 27 | si = 1; 28 | lg = 0; 29 | while (si < n) { 30 | lg++; 31 | si <<= 1; 32 | } 33 | d.assign(2 * si, e); 34 | std::copy(v.begin(), v.end(), d.begin() + si); 35 | for (int i = si - 1; i > 0; i--) update(i); 36 | } 37 | int size() const { return n; } 38 | T get(int p) const { 39 | assert(0 <= p && p < n); 40 | return d[si + p]; 41 | } 42 | void set(int p, T x) { 43 | assert(0 <= p && p < n); 44 | p += si; 45 | d[p] = x; 46 | for (int i = 1; i <= lg; i++) update(p >> i); 47 | } 48 | T query(int l, int r) { 49 | assert(0 <= l && l <= r && r <= n); 50 | T le = e, ri = e; 51 | l += si; r += si; 52 | while (l < r) { 53 | if (l & 1) le = op(le, d[l++]); 54 | if (r & 1) ri = op(d[--r], ri); 55 | l >>= 1; r >>= 1; 56 | } 57 | return op(le, ri); 58 | } 59 | T query() const { return d[1]; } 60 | template int max_right(int l, F f) const { 61 | assert(0 <= l && l <= n); 62 | assert(f(e)); 63 | if (l == n) return n; 64 | l += si; 65 | T sm = e; 66 | do { 67 | while (l % 2 == 0) l >>= 1; 68 | if (!f(op(sm, d[l]))) { 69 | while (l < si) { 70 | l = 2 * l; 71 | if (f(op(sm, d[l]))) { 72 | sm = op(sm, d[l]); 73 | l++; 74 | } 75 | } 76 | return l - si; 77 | } 78 | sm = op(sm, d[l]); 79 | l++; 80 | } while ((l & -l) != l); 81 | return n; 82 | } 83 | template int min_left(int r, F f) const { 84 | assert(0 <= r && r <= n); 85 | assert(f(e)); 86 | if (r == 0) return 0; 87 | r += si; 88 | T sm = e; 89 | do { 90 | r--; 91 | while (r > 1 && (r % 2)) r >>= 1; 92 | if (!f(op(d[r], sm))) { 93 | while (r < si) { 94 | r = 2 * r + 1; 95 | if (f(op(d[r], sm))) { 96 | sm = op(d[r], sm); 97 | r--; 98 | } 99 | } 100 | return r + 1 - si; 101 | } 102 | sm = op(d[r], sm); 103 | } while ((r & -r) != r); 104 | return 0; 105 | } 106 | }; 107 | -------------------------------------------------------------------------------- /source/data-structures/sparse.h: -------------------------------------------------------------------------------- 1 | 2 | template> 3 | struct sparse { 4 | vector> st; 5 | vector log; 6 | int n; 7 | sparse(vector a) { 8 | n = a.size(); 9 | log.assign(n + 1, 0); 10 | log[1] = 0; 11 | for(int i = 2; i <= n; i++) { 12 | log[i] = log[i / 2] + 1; 13 | } 14 | int lg = log[n] + 1; 15 | st.assign(n, vector(lg)); 16 | for(int i = 0; i < n; i++) { 17 | st[i][0] = a[i]; 18 | } 19 | for(int j = 1; j < lg; j++) { 20 | for(int i = 0; i + (1 << j) <= n; i++) { 21 | st[i][j] = min(st[i][j - 1], st[i + (1 << (j - 1))][j - 1], Compare{}); 22 | } 23 | } 24 | } 25 | T query(int l, int r) { 26 | int j = log[r - l + 1]; 27 | return min(st[l][j], st[r - (1 << j) + 1][j], Compare{}); 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /source/data-structures/treap.h: -------------------------------------------------------------------------------- 1 | 2 | template 3 | struct treap { 4 | public: 5 | struct node { 6 | T value; 7 | int cnt, y; 8 | node *l, *r, *p; 9 | node(T value, int cnt, int y) : value(value), cnt(cnt), y(y), l(nullptr), r(nullptr), p(nullptr) {} 10 | }; 11 | private: 12 | std::mt19937 rng; 13 | int rand() { 14 | std::uniform_int_distribution uni(0, INT_MAX); 15 | return uni(rng); 16 | } 17 | void update(node* a) { 18 | assert(a); 19 | a->cnt = 1 + size_of(a->l) + size_of(a->r); 20 | } 21 | void split(node* a, node*& l, node*& r, int k) { 22 | if (!a) return void(l = r = nullptr); 23 | if (size_of(a->l) < k) { 24 | split(a->r, a->r, r, k - size_of(a->l) - 1); 25 | if (a->r) a->r->p = a; 26 | l = a; 27 | update(a); 28 | } else { 29 | split(a->l, l, a->l, k); 30 | if (a->l) a->l->p = a; 31 | r = a; 32 | update(a); 33 | } 34 | } 35 | node* join(const std::vector& v, int l, int r) { 36 | assert(0 <= l && l <= r && r <= (int) v.size()); 37 | if (l == r) return nullptr; 38 | if (r - l == 1) return v[l]; 39 | int m = l + (r - l) / 2; 40 | return join(join(v, l, m), join(v, m, r)); 41 | } 42 | public: 43 | explicit treap(int seed = std::chrono::steady_clock::now().time_since_epoch().count()) : rng(seed) {} 44 | node* make(T value) { return new node(value, 1, rand()); } 45 | int size_of(node* a) const { 46 | return a ? a->cnt : 0; 47 | } 48 | node* root(node* a) const { 49 | if (!a) return nullptr; 50 | while (a->p) a = a->p; 51 | return a; 52 | } 53 | int index_of(node* a) const { 54 | assert(a); 55 | int idx = size_of(a->l); 56 | while (a->p) { 57 | node* p = a->p; 58 | if (p->r == a) idx += 1 + size_of(p->l); 59 | a = p; 60 | } 61 | return idx; 62 | } 63 | template std::pair lower_bound(node* a, F f) { 64 | int idx = 0; 65 | node* p = nullptr; 66 | while (a) { 67 | if (f(a)) { 68 | idx += 1 + size_of(a->l); 69 | a = a->r; 70 | } else { 71 | p = a; 72 | a = a->l; 73 | } 74 | } 75 | return {p, idx}; 76 | } 77 | node* at(node* a, int k) const { 78 | while (a) { 79 | int s = size_of(a->l); 80 | if (k == s) { 81 | return a; 82 | } else if (k < s) { 83 | a = a->l; 84 | } else { 85 | k -= 1 + s; 86 | a = a->r; 87 | } 88 | } 89 | return nullptr; 90 | } 91 | std::pair split(node* a, int k) { 92 | node *l, *r; 93 | split(a, l, r, k); 94 | if (l) l->p = nullptr; 95 | if (r) r->p = nullptr; 96 | return {l, r}; 97 | } 98 | node* join(node* a, node* b) { 99 | if (!a) return b; 100 | if (!b) return a; 101 | if (a->y > b->y) { 102 | a->r = join(a->r, b); 103 | if (a->r) a->r->p = a; 104 | return update(a), a; 105 | } else { 106 | b->l = join(a, b->l); 107 | if (b->l) b->l->p = b; 108 | return update(b), b; 109 | } 110 | } 111 | node* join(const std::vector& v) { 112 | return join(v, 0, v.size()); 113 | } 114 | template void for_each(node* a, F f) const { 115 | if (!a) return; 116 | if (a->l) for_each(a->l, f); 117 | f(a); 118 | if (a->r) for_each(a->r, f); 119 | } 120 | node* insert(node* root, int k, node* u) { 121 | node *l, *r; 122 | split(root, l, r, k); 123 | return join({l, u, r}); 124 | } 125 | node* erase(node* root, int k) { 126 | node *l, *m, *r; 127 | split(root, l, r, k); 128 | split(r, m, r, 1); 129 | return join(l, r); 130 | } 131 | }; 132 | -------------------------------------------------------------------------------- /source/geometry/pt.h: -------------------------------------------------------------------------------- 1 | 2 | template 3 | int sgn(T x) { 4 | return (x > 0 ? 1 : x < 0 ? -1 : 0); 5 | } 6 | 7 | template 8 | struct pt { 9 | T x, y; 10 | pt(T x = T(), T y = T()) : x(x), y(y) {} 11 | pt operator+(const pt &o) const { 12 | return pt(x + o.x, y + o.y); 13 | } 14 | pt& operator+=(const pt &o) { 15 | x += o.x; 16 | y += o.y; 17 | return *this; 18 | } 19 | pt operator-(const pt &o) const { 20 | return pt(x - o.x, y - o.y); 21 | } 22 | pt& operator-=(const pt &o) { 23 | x -= o.x; 24 | y -= o.y; 25 | return *this; 26 | } 27 | pt operator*(const T &c) const { 28 | return pt(x * c, y * c); 29 | } 30 | pt& operator*=(const T &c) { 31 | x *= c; 32 | y *= c; 33 | return *this; 34 | } 35 | T dot(const pt &o) const { 36 | return x * o.x + y * o.y; 37 | } 38 | T cross(const pt &o) const { 39 | return x * o.y - y * o.x; 40 | } 41 | }; 42 | 43 | template 44 | int o(const pt &a, const pt &b, const pt &c) { 45 | return sgn((b - a).cross(c - a)); 46 | } 47 | 48 | template 49 | istream& operator>>(istream &is, pt &p) { 50 | T x, y; 51 | is >> x >> y; 52 | p = pt(x, y); 53 | return is; 54 | } 55 | 56 | template 57 | ostream& operator<<(ostream &os, const pt &p) { 58 | return os << p.x << ' ' << p.y; 59 | } 60 | 61 | template 62 | bool segseg1(T l, T r, T L, T R) { 63 | if(l > r) swap(l, r); 64 | if(L > R) swap(L, R); 65 | return r < L || R < l; 66 | } 67 | 68 | template 69 | bool segseg(pt a, pt b, pt c, pt d) { 70 | return segseg1(a.x, b.x, c.x, d.x) && segseg1(a.y, b.y, c.y, d.y) && 71 | o(a, b, c) * o(a, b, d) <= 0 && o(c, d, a) * o(c, d, b) <= 0; 72 | } 73 | 74 | template 75 | T signed_area2(const vector> &p) { 76 | int n = (int) p.size(); 77 | T ans = 0; 78 | for(int i = 0; i < n; i++) { 79 | ans += p[i].cross(p[(i + 1) % n]); 80 | } 81 | return ans; 82 | } 83 | 84 | template 85 | T area2(const vector> &p) { 86 | return abs(signed_area2(p)); 87 | } 88 | -------------------------------------------------------------------------------- /source/graphs/blossom.h: -------------------------------------------------------------------------------- 1 | 2 | struct blossom { 3 | int n, m; 4 | vector mate; 5 | vector> b; 6 | vector p, d, bl; 7 | vector> g; 8 | blossom(int n) : n(n), mate(n, -1), b(n+n/2), p(n+n/2), d(n+n/2), bl(n+n/2), g(n+n/2, vector(n+n/2, -1)) {} 9 | void add_edge(int u, int v) { 10 | g[u][v] = u; 11 | g[v][u] = v; 12 | } 13 | void match(int u, int v) { 14 | g[u][v] = g[v][u] = -1; 15 | mate[u] = v; 16 | mate[v] = u; 17 | } 18 | vector trace(int x) { 19 | vector vx; 20 | while(true) { 21 | while(bl[x] != x) x = bl[x]; 22 | if(!vx.empty() && vx.back() == x) break; 23 | vx.push_back(x); 24 | x = p[x]; 25 | } 26 | return vx; 27 | } 28 | void contract(int c, int x, int y, vector &vx, vector &vy) { 29 | b[c].clear(); 30 | int r = vx.back(); 31 | while(!vx.empty() && !vy.empty() && vx.back() == vy.back()) { 32 | r = vx.back(); 33 | vx.pop_back(); 34 | vy.pop_back(); 35 | } 36 | b[c].push_back(r); 37 | b[c].insert(b[c].end(), vx.rbegin(), vx.rend()); 38 | b[c].insert(b[c].end(), vy.begin(), vy.end()); 39 | for(int i = 0; i <= c; i++) { 40 | g[c][i] = g[i][c] = -1; 41 | } 42 | for(int z : b[c]) { 43 | bl[z] = c; 44 | for(int i = 0; i < c; i++) { 45 | if(g[z][i] != -1) { 46 | g[c][i] = z; 47 | g[i][c] = g[i][z]; 48 | } 49 | } 50 | } 51 | } 52 | vector lift(vector &vx) { 53 | vector A; 54 | while(vx.size() >= 2) { 55 | int z = vx.back(); vx.pop_back(); 56 | if(z < n) { 57 | A.push_back(z); 58 | continue; 59 | } 60 | int w = vx.back(); 61 | int i = (A.size() % 2 == 0 ? find(b[z].begin(), b[z].end(), g[z][w]) - b[z].begin() : 0); 62 | int j = (A.size() % 2 == 1 ? find(b[z].begin(), b[z].end(), g[z][A.back()]) - b[z].begin() : 0); 63 | int k = b[z].size(); 64 | int dif = (A.size() % 2 == 0 ? i % 2 == 1 : j % 2 == 0) ? 1 : k - 1; 65 | while(i != j) { 66 | vx.push_back(b[z][i]); 67 | i = (i + dif) % k; 68 | } 69 | vx.push_back(b[z][i]); 70 | } 71 | return A; 72 | } 73 | int solve() { 74 | for(int ans = 0; ; ans++) { 75 | fill(d.begin(), d.end(), 0); 76 | queue Q; 77 | for(int i = 0; i < m; i++) bl[i] = i; 78 | for(int i = 0; i < n; i++) { 79 | if(mate[i] == -1) { 80 | Q.push(i); 81 | p[i] = i; 82 | d[i] = 1; 83 | } 84 | } 85 | int c = n; 86 | bool aug = false; 87 | while(!Q.empty() && !aug) { 88 | int x = Q.front(); Q.pop(); 89 | if(bl[x] != x) continue; 90 | for(int y = 0; y < c; y++) { 91 | if(bl[y] == y && g[x][y] != -1) { 92 | if(d[y] == 0) { 93 | p[y] = x; 94 | d[y] = 2; 95 | p[mate[y]] = y; 96 | d[mate[y]] = 1; 97 | Q.push(mate[y]); 98 | }else if(d[y] == 1) { 99 | vector vx = trace(x); 100 | vector vy = trace(y); 101 | if(vx.back() == vy.back()) { 102 | contract(c, x, y, vx, vy); 103 | Q.push(c); 104 | p[c] = p[b[c][0]]; 105 | d[c] = 1; 106 | c++; 107 | }else { 108 | aug = true; 109 | vx.insert(vx.begin(), y); 110 | vy.insert(vy.begin(), x); 111 | vector A = lift(vx); 112 | vector B = lift(vy); 113 | A.insert(A.end(), B.rbegin(), B.rend()); 114 | for(int i = 0; i < (int) A.size(); i += 2) { 115 | match(A[i], A[i + 1]); 116 | if(i + 2 < (int) A.size()) add_edge(A[i + 1], A[i + 2]); 117 | } 118 | } 119 | break; 120 | } 121 | } 122 | } 123 | } 124 | if(!aug) return ans; 125 | } 126 | } 127 | }; 128 | -------------------------------------------------------------------------------- /source/graphs/dinic.h: -------------------------------------------------------------------------------- 1 | 2 | template 3 | struct dinic { 4 | struct edge { 5 | int v; 6 | C cap, flow; 7 | }; 8 | int n; 9 | vector e; 10 | vector> g; 11 | vector level, p; 12 | dinic(int n) : g(n), p(n), level(n) {} 13 | void add_edge(int u, int v, C c) { 14 | int k = (int) e.size(); 15 | e.push_back({v, c, 0}); 16 | e.push_back({u, c, c}); 17 | g[u].push_back(k); 18 | g[v].push_back(k ^ 1); 19 | } 20 | bool bfs(int s, int t) { 21 | fill(level.begin(), level.end(), -1); 22 | queue Q; 23 | Q.push(s); 24 | level[s] = 0; 25 | while(!Q.empty()) { 26 | int x = Q.front(); Q.pop(); 27 | for(int i : g[x]) { 28 | if(level[e[i].v] == -1 && e[i].flow < e[i].cap) { 29 | level[e[i].v] = level[x] + 1; 30 | Q.push(e[i].v); 31 | } 32 | } 33 | } 34 | return level[t] != -1; 35 | } 36 | C dfs(int x, int t, C amt) { 37 | if(x == t) return amt; 38 | for(int &i = p[x]; i < (int) g[x].size(); i++) { 39 | int idx = g[x][i]; 40 | if(level[e[idx].v] == level[x] + 1 && e[idx].flow < e[idx].cap) { 41 | C a = dfs(e[idx].v, t, min(amt, e[idx].cap - e[idx].flow)); 42 | if(a > 0) { 43 | e[idx].flow += a; 44 | e[idx ^ 1].flow -= a; 45 | return a; 46 | } 47 | } 48 | } 49 | return 0; 50 | } 51 | C flow(int s, int t, C mx) { 52 | C f = 0; 53 | while(bfs(s, t)) { 54 | fill(p.begin(), p.end(), 0); 55 | while(true) { 56 | C d = dfs(s, t, mx - f); 57 | if(d == 0) break; 58 | f += d; 59 | } 60 | } 61 | return f; 62 | } 63 | }; 64 | -------------------------------------------------------------------------------- /source/graphs/matroid_intersection.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | struct edge { 4 | information for a matroid element 5 | }; 6 | struct matroid { 7 | void clear(); -> remove all edges from the independent set 8 | void add(const edge &e); -> add an edge to the independent set 9 | void prepare(); -> prepare the added edges for queries 10 | bool free(const edge &e); -> can we add e and still be independent? 11 | bool exchange(const edge &x, const edge &y); -> can we remove x, add y, and still be independent? 12 | }; 13 | */ 14 | 15 | struct color { 16 | int c; 17 | color(int c) : c(c) {} 18 | }; 19 | 20 | struct color_matroid { 21 | vector cnt, a; 22 | color_matroid(vector cnt) : cnt(cnt.begin(), cnt.end()), a(cnt.size()) {} 23 | void clear() { 24 | fill(a.begin(), a.end(), 0); 25 | } 26 | void add(const color &x) { 27 | a[x.c]++; 28 | } 29 | void prepare() {} 30 | bool free(const color &x) { 31 | return a[x.c] < cnt[x.c]; 32 | } 33 | bool exchange(const color &x, const color &y) { 34 | a[x.c]--; 35 | bool ans = (a[y.c] < cnt[y.c]); 36 | a[x.c]++; 37 | return ans; 38 | } 39 | }; 40 | 41 | struct edge { 42 | int u, v; 43 | edge(int u, int v) : u(u), v(v) {} 44 | }; 45 | 46 | struct graph_matroid { 47 | int n; 48 | vector> g; 49 | vector tin, tout, comp; 50 | int ti; 51 | graph_matroid(int n) : n(n), g(n), tin(n), tout(n), comp(n) {} 52 | void clear() { 53 | for(int i = 0; i < n; i++) { 54 | g[i].clear(); 55 | } 56 | } 57 | void add(const edge &x) { 58 | g[x.u].push_back(x.v); 59 | g[x.v].push_back(x.u); 60 | } 61 | void dfs(int x) { 62 | tin[x] = ti++; 63 | for(int y : g[x]) { 64 | if(tin[y] == 0) { 65 | comp[y] = comp[x]; 66 | dfs(y); 67 | } 68 | } 69 | tout[x] = ti++; 70 | } 71 | void prepare() { 72 | fill(tin.begin(), tin.end(), 0); 73 | ti = 1; 74 | for(int i = 0; i < n; i++) { 75 | if(tin[i] == 0) { 76 | comp[i] = i; 77 | dfs(i); 78 | } 79 | } 80 | } 81 | bool anc(int x, int y) const { 82 | return tin[x] <= tin[y] && tout[y] <= tout[x]; 83 | } 84 | bool free(const edge &x) const { 85 | return comp[x.u] != comp[x.v]; 86 | } 87 | bool exchange(const edge &x, const edge &y) const { 88 | if(comp[y.u] != comp[y.v]) return true; 89 | int u = (tin[x.u] < tin[x.v] ? x.v : x.u); 90 | return anc(u, y.u) ^ anc(u, y.v); 91 | } 92 | }; 93 | 94 | template 95 | struct matroid_intersection { 96 | M1 m1; 97 | M2 m2; 98 | matroid_intersection(M1 m1, M2 m2) : m1(m1), m2(m2) {} 99 | vector solve(const vector> &e) { 100 | int rank = 0, n = (int) e.size(); 101 | vector par(n, -1); 102 | vector used(n, false); 103 | vector basis; 104 | while(true) { 105 | queue Q; 106 | m1.clear(); m2.clear(); basis.clear(); 107 | fill(par.begin(), par.end(), -1); 108 | for(int i = 0; i < n; i++) { 109 | if(used[i]) { 110 | basis.push_back(i); 111 | m1.add(e[i].first); 112 | m2.add(e[i].second); 113 | } 114 | } 115 | m1.prepare(); m2.prepare(); 116 | 117 | bool aug = false; 118 | auto enqueue = [&](int i, int j) { 119 | par[j] = i; 120 | Q.push(j); 121 | if(!used[j] && m2.free(e[j].second)) { 122 | do { 123 | used[j] = !used[j]; 124 | j = par[j]; 125 | }while(j != par[j]); 126 | aug = true; 127 | } 128 | return aug; 129 | }; 130 | for(int i = 0; i < n; i++) { 131 | if(!used[i] && m1.free(e[i].first)) { 132 | if(enqueue(i, i)) break; 133 | } 134 | } 135 | while(!Q.empty() && !aug) { 136 | int i = Q.front(); Q.pop(); 137 | if(used[i]) { 138 | for(int j = 0; j < n; j++) { 139 | if(!used[j] && par[j] == -1 && m1.exchange(e[i].first, e[j].first)) { 140 | if(enqueue(i, j)) break; 141 | } 142 | } 143 | }else { 144 | for(int j : basis) { 145 | if(par[j] == -1 && m2.exchange(e[j].second, e[i].second)) { 146 | if(enqueue(i, j)) break; 147 | } 148 | } 149 | } 150 | } 151 | if(aug) rank++; 152 | else break; 153 | } 154 | return basis; 155 | } 156 | template 157 | vector solve(const vector> &e, const vector &cost) { 158 | int rank = 0, n = (int) e.size(); 159 | vector used(n, false); 160 | const Cost MX = numeric_limits::max(); 161 | vector> dist(2, vector(n, MX)); 162 | vector par(n, -1); 163 | vector> g(n); 164 | while(true) { 165 | m1.clear(); m2.clear(); 166 | for(int i = 0; i < n; i++) { 167 | g[i].clear(); 168 | if(used[i]) { 169 | m1.add(e[i].first); 170 | m2.add(e[i].second); 171 | } 172 | } 173 | m1.prepare(); m2.prepare(); 174 | 175 | for(int i = 0; i < n; i++) { 176 | if(!used[i] && m2.free(e[i].second)) { 177 | dist[0][i] = cost[i]; 178 | par[i] = i; 179 | }else { 180 | dist[0][i] = MX; 181 | par[i] = -1; 182 | } 183 | if(used[i]) { 184 | for(int j = 0; j < n; j++) { 185 | if(!used[j]) { 186 | if(m1.exchange(e[i].first, e[j].first)) { 187 | g[i].push_back(j); 188 | } 189 | if(m2.exchange(e[i].second, e[j].second)) { 190 | g[j].push_back(i); 191 | } 192 | } 193 | } 194 | } 195 | } 196 | Cost best = MX; 197 | int idx = -1; 198 | bool go = true; 199 | while(go) { 200 | go = false; 201 | for(int i = 0; i < n; i++) { 202 | if(dist[0][i] < best && m1.free(e[i].first)) { 203 | best = dist[0][i]; 204 | idx = i; 205 | } 206 | dist[1][i] = dist[0][i]; 207 | Cost c = (used[i] ? -cost[i] : cost[i]); 208 | for(int j : g[i]) { 209 | if(dist[0][j] != MX && c + dist[0][j] < dist[1][i]) { 210 | go = true; 211 | dist[1][i] = c + dist[0][j]; 212 | par[i] = j; 213 | } 214 | } 215 | } 216 | dist[0].swap(dist[1]); 217 | } 218 | if(idx == -1) break; 219 | rank++; 220 | while(par[idx] != idx) { 221 | used[idx] = !used[idx]; 222 | idx = par[idx]; 223 | } 224 | used[idx] = !used[idx]; 225 | } 226 | vector basis; 227 | for(int i = 0; i < n; i++) { 228 | if(used[i]) { 229 | basis.push_back(i); 230 | } 231 | } 232 | return basis; 233 | } 234 | }; 235 | -------------------------------------------------------------------------------- /source/graphs/mcmf.h: -------------------------------------------------------------------------------- 1 | 2 | template 3 | struct mcmf { 4 | struct edge { 5 | int v; 6 | Cap cap, flow; 7 | Cost cost; 8 | }; 9 | int n; 10 | vector e; 11 | vector> g; 12 | vector dist, pot; 13 | vector f; 14 | vector vis; 15 | vector par; 16 | bool n2dijkstra = false; 17 | mcmf(int n) : n(n), g(n), dist(n), pot(n), f(n), vis(n), par(n) {} 18 | void add_edge(int u, int v, Cap cap, Cost cost) { 19 | int k = e.size(); 20 | e.push_back({v, cap, 0, cost}); 21 | e.push_back({u, cap, cap, -cost}); 22 | g[u].push_back(k); 23 | g[v].push_back(k ^ 1); 24 | } 25 | pair solve(int s, int t) { 26 | Cap flow = 0; 27 | Cost cost = 0; 28 | while(true) { 29 | fill(dist.begin(), dist.end(), numeric_limits::max()); 30 | fill(vis.begin(), vis.end(), false); 31 | dist[s] = 0; 32 | f[s] = numeric_limits::max(); 33 | if(n2dijkstra) { 34 | while(true) { 35 | int x = -1; Cost d = numeric_limits::max(); 36 | for(int i = 0; i < n; i++) { 37 | if(!vis[i] && dist[i] < d) { 38 | x = i; 39 | d = dist[x]; 40 | } 41 | } 42 | if(x == -1) break; 43 | vis[x] = true; 44 | for(int i : g[x]) { 45 | Cost d2 = d + e[i].cost + pot[x] - pot[e[i].v]; 46 | if(!vis[e[i].v] && e[i].flow < e[i].cap && d2 < dist[e[i].v]) { 47 | dist[e[i].v] = d2; 48 | f[e[i].v] = min(f[x], e[i].cap - e[i].flow); 49 | par[e[i].v] = i; 50 | } 51 | } 52 | } 53 | }else { 54 | priority_queue, vector>, greater<>> Q; 55 | Q.push({0, s}); 56 | while(!Q.empty()) { 57 | Cost d; int x; 58 | tie(d, x) = Q.top(); Q.pop(); 59 | if(vis[x]) continue; 60 | vis[x] = true; 61 | for(int i : g[x]) { 62 | Cost d2 = d + e[i].cost + pot[x] - pot[e[i].v]; 63 | if(!vis[e[i].v] && e[i].flow < e[i].cap && d2 < dist[e[i].v]) { 64 | dist[e[i].v] = d2; 65 | f[e[i].v] = min(f[x], e[i].cap - e[i].flow); 66 | par[e[i].v] = i; 67 | Q.push({d2, e[i].v}); 68 | } 69 | } 70 | } 71 | } 72 | if(!vis[t]) break; 73 | for(int i = 0; i < n; i++) { 74 | dist[i] += pot[i] - pot[s]; 75 | } 76 | cost += dist[t] * f[t]; 77 | flow += f[t]; 78 | int x = t; 79 | while(x != s) { 80 | e[par[x]].flow += f[t]; 81 | e[par[x] ^ 1].flow -= f[t]; 82 | x = e[par[x] ^ 1].v; 83 | } 84 | dist.swap(pot); 85 | } 86 | return {flow, cost}; 87 | } 88 | }; -------------------------------------------------------------------------------- /source/graphs/scc.h: -------------------------------------------------------------------------------- 1 | 2 | struct scc { 3 | int n; 4 | vector> g, gr; 5 | vector st, comp; 6 | vector vis; 7 | scc(int n) : n(n), g(n), gr(n), vis(n), comp(n, -1) {} 8 | void add_edge(int u, int v) { 9 | g[u].push_back(v); 10 | gr[v].push_back(u); 11 | } 12 | void dfs(int x) { 13 | vis[x] = true; 14 | for(int y : g[x]) { 15 | if(!vis[y]) { 16 | dfs(y); 17 | } 18 | } 19 | st.push_back(x); 20 | } 21 | void dfs2(int x, int c) { 22 | comp[x] = c; 23 | for(int y : gr[x]) { 24 | if(comp[y] == -1) { 25 | dfs2(y, c); 26 | } 27 | } 28 | } 29 | void solve() { 30 | for(int i = 0; i < n; i++) { 31 | if(!vis[i]) { 32 | dfs(i); 33 | } 34 | } 35 | while(!st.empty()) { 36 | int x = st.back(); st.pop_back(); 37 | if(comp[x] == -1) { 38 | dfs2(x, x); 39 | } 40 | } 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /source/strings/suffix_array.h: -------------------------------------------------------------------------------- 1 | 2 | struct suffix_array { 3 | int n; 4 | string s; 5 | vector p, rank, lcp; 6 | suffix_array(string s) : s(s) { 7 | const int A = 256; 8 | s.push_back('$'); 9 | n = s.length(); 10 | int cl = 1; 11 | vector c(n), pn(n), cn(n), cnt(max(A, n), 0); 12 | p.assign(n, 0); 13 | for(int i = 0; i < n; i++) { 14 | cnt[s[i]]++; 15 | } 16 | for(int i = 1; i < A; i++) { 17 | cnt[i] += cnt[i - 1]; 18 | } 19 | for(int i = 0; i < n; i++) { 20 | p[--cnt[s[i]]] = i; 21 | } 22 | c[p[0]] = 0; 23 | for(int i = 1; i < n; i++) { 24 | if(s[p[i]] != s[p[i - 1]]) { 25 | cl++; 26 | } 27 | c[p[i]] = cl - 1; 28 | } 29 | for(int h = 0; (1 << h) < n; h++) { 30 | for(int i = 0; i < n; i++) { 31 | pn[i] = p[i] - (1 << h); 32 | if(pn[i] < 0) { 33 | pn[i] += n; 34 | } 35 | } 36 | fill(cnt.begin(), cnt.begin() + cl, 0); 37 | for(int i = 0; i < n; i++) { 38 | cnt[c[pn[i]]]++; 39 | } 40 | for(int i = 1; i < cl; i++) { 41 | cnt[i] += cnt[i - 1]; 42 | } 43 | for(int i = n - 1; i >= 0; i--) { 44 | p[--cnt[c[pn[i]]]] = pn[i]; 45 | } 46 | cn[p[0]] = 0; 47 | cl = 1; 48 | for(int i = 1; i < n; i++) { 49 | pair cur = {c[p[i]], c[(p[i] + (1 << h)) % n]}; 50 | pair prv = {c[p[i - 1]], c[(p[i - 1] + (1 << h)) % n]}; 51 | if(cur != prv) { 52 | cl++; 53 | } 54 | cn[p[i]] = cl - 1; 55 | } 56 | c.swap(cn); 57 | } 58 | rank.assign(n, 0); 59 | for(int i = 0; i < n; i++) { 60 | rank[p[i]] = i; 61 | } 62 | int k = 0; 63 | lcp.assign(n - 1, 0); 64 | for(int i = 0; i < n; i++) { 65 | if(rank[i] == n - 1) { 66 | k = 0; 67 | continue; 68 | } 69 | int j = p[rank[i] + 1]; 70 | while(i + k < n && j + k < n && s[i + k] == s[j + k]) { 71 | k++; 72 | } 73 | lcp[rank[i]] = k; 74 | if(k > 0) { 75 | k--; 76 | } 77 | } 78 | } 79 | }; 80 | -------------------------------------------------------------------------------- /source/template.cpp: -------------------------------------------------------------------------------- 1 | // Source: https://github.com/rileyborgard/Algorithms/blob/main/source/template.cpp 2 | #include 3 | 4 | #ifdef LOCAL 5 | #include 6 | #else 7 | #define dbg(...) 8 | #define debug(...) 9 | #define log(...) 10 | #define error(...) 11 | template 12 | char _dlim = ' '; 13 | template 14 | char _dlim> = '\n'; 15 | template 16 | std::ostream& operator<<(std::ostream &os, const std::vector &ve) { 17 | int n = ve.size(); 18 | for (int i = 0; i < n; i++) { 19 | os << ve[i]; 20 | if (i < n - 1) os << _dlim; 21 | } 22 | return os; 23 | } 24 | #endif 25 | 26 | #define ll long long 27 | #define sz(x) ((int) (x).size()) 28 | #define all(x) (x).begin(), (x).end() 29 | #define vi vector 30 | #define pii pair 31 | #define rep(i, a, b) for(int i = (a); i < (b); i++) 32 | using namespace std; 33 | template 34 | using minpq = priority_queue, greater>; 35 | 36 | template 37 | void print(T &&head, V &&... tail) { 38 | cout << head << ' '; 39 | if constexpr (sizeof...(tail)) { 40 | print(tail...); 41 | } 42 | } 43 | void print() {} 44 | #define println(...) {print(__VA_ARGS__); cout << '\n';} 45 | 46 | void pre() { 47 | 48 | } 49 | 50 | struct TestCase { 51 | 52 | TestCase() { 53 | 54 | } 55 | 56 | void solve() { 57 | 58 | } 59 | }; 60 | 61 | int main(int argc, char** argv) { 62 | ios::sync_with_stdio(false); 63 | cin.tie(0); 64 | pre(); 65 | int te = 1; 66 | // cin >> te; 67 | int single = -1; 68 | dbg({ if (argc >= 2) single = atoi(argv[1]); }) 69 | rep(test, 1, te + 1) { 70 | debug(test); 71 | TestCase tc; 72 | if (single == -1 || test == single) tc.solve(); 73 | } 74 | } -------------------------------------------------------------------------------- /source/template_interactive.cpp: -------------------------------------------------------------------------------- 1 | // Source: https://github.com/rileyborgard/Algorithms/blob/main/source/template.cpp 2 | #include 3 | 4 | #ifdef LOCAL 5 | #include 6 | #else 7 | #define dbg(...) 8 | #define debug(...) 9 | #define log(...) 10 | #define error(...) 11 | template 12 | char _dlim = ' '; 13 | template 14 | char _dlim> = '\n'; 15 | template 16 | std::ostream& operator<<(std::ostream &os, const std::vector &ve) { 17 | int n = ve.size(); 18 | for (int i = 0; i < n; i++) { 19 | os << ve[i]; 20 | if (i < n - 1) os << _dlim; 21 | } 22 | return os; 23 | } 24 | #endif 25 | 26 | #define ll long long 27 | #define sz(x) ((int) (x).size()) 28 | #define all(x) (x).begin(), (x).end() 29 | #define vi vector 30 | #define pii pair 31 | #define rep(i, a, b) for(int i = (a); i < (b); i++) 32 | using namespace std; 33 | template 34 | using minpq = priority_queue, greater>; 35 | 36 | template 37 | void print(T &&head, V &&... tail) { 38 | cout << head << ' '; 39 | if constexpr (sizeof...(tail)) { 40 | print(tail...); 41 | } 42 | } 43 | void print() {} 44 | #define println(...) {print(__VA_ARGS__); cout << '\n';} 45 | 46 | void pre() { 47 | 48 | } 49 | 50 | struct Interactor { 51 | Interactor() {} 52 | virtual ~Interactor() {} 53 | virtual void ask(int x) = 0; 54 | virtual void answer(int x) = 0; 55 | }; 56 | 57 | struct LocalInteractor: public Interactor { 58 | LocalInteractor() : Interactor() { 59 | // Read input 60 | } 61 | void ask(int x) override { 62 | 63 | } 64 | void answer(int x) override { 65 | 66 | } 67 | }; 68 | 69 | struct ReleaseInteractor: public Interactor { 70 | ReleaseInteractor() : Interactor() {} 71 | void ask(int x) override { 72 | 73 | } 74 | void answer(int x) override { 75 | 76 | } 77 | }; 78 | 79 | struct TestCase { 80 | unique_ptr inter; 81 | TestCase() { 82 | #ifdef LOCAL 83 | inter = make_unique(); 84 | #else 85 | inter = make_unique(); 86 | #endif 87 | } 88 | 89 | void solve() { 90 | 91 | } 92 | }; 93 | 94 | int main(int argc, char** argv) { 95 | ios::sync_with_stdio(false); 96 | cin.tie(0); 97 | pre(); 98 | int te = 1; 99 | // cin >> te; 100 | int single = -1; 101 | dbg({ if (argc >= 2) single = atoi(argv[1]); }) 102 | rep(test, 1, te + 1) { 103 | debug(test); 104 | TestCase tc; 105 | if (single == -1 || test == single) tc.solve(); 106 | } 107 | } --------------------------------------------------------------------------------