├── .gitignore ├── DSU.cpp ├── Dijkstra.cpp ├── FFT.cpp ├── FenwickTree.cpp ├── KMP.cpp ├── MatrixExpo.cpp ├── NumberTheory.cpp ├── README.md ├── SegmentTree.cpp ├── SegmentTreeLazyPropagation.cpp ├── SparseTable.cpp ├── SqrtDecomposition.cpp ├── Trie.cpp └── template ├── debug.hpp └── template.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | test.cpp 2 | .vscode 3 | .cph 4 | *.bin 5 | .DS_Store 6 | *.dSYM 7 | -------------------------------------------------------------------------------- /DSU.cpp: -------------------------------------------------------------------------------- 1 | class DSU { 2 | public: 3 | int n; 4 | vector par; 5 | vector sz; 6 | int cnt; 7 | DSU(){} 8 | DSU(int N) { 9 | n = cnt = N; 10 | par.resize(n); sz.resize(n); 11 | while (N--) { 12 | par[N] = N; 13 | sz[N] = 1; 14 | } 15 | } 16 | int find(int p) { 17 | return par[p] == p? p: par[p] = find(par[p]); 18 | } 19 | bool connected(int p, int q) { 20 | return find(p) == find(q); 21 | } 22 | int size(int p) { 23 | return sz[find(p)]; 24 | } 25 | bool join(int p, int q) { 26 | int root1 = find(p); 27 | int root2 = find(q); 28 | if (root1 == root2) return 0; 29 | if (sz[root1] < sz[root2]) swap(root1, root2); 30 | par[root2] = root1; 31 | sz[root1] += sz[root2]; 32 | cnt--; 33 | return 1; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /Dijkstra.cpp: -------------------------------------------------------------------------------- 1 | vector >> g; 2 | vector dist; 3 | vector previous; 4 | 5 | void dijkstra(int s) { 6 | int n = g.size(); 7 | dist.assign(n, 1e9); 8 | previous.assign(n, -1); 9 | dist[s] = 0; 10 | set> q; 11 | q.insert({0, s}); 12 | while (!q.empty()) { 13 | int v = q.begin()->second; 14 | q.erase(q.begin()); 15 | 16 | for (auto edge : g[v]) { 17 | int to = edge.first; 18 | int len = edge.second; 19 | 20 | if (dist[v] + len < dist[to]) { 21 | q.erase({dist[to], to}); 22 | dist[to] = dist[v] + len; 23 | previous[to] = v; 24 | q.insert({dist[to], to}); 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /FFT.cpp: -------------------------------------------------------------------------------- 1 | // fft template from kactl library 2 | #define rep(i, a, b) for(int i = a; i < (b); ++i) 3 | #define ALL(x) begin(x), end(x) 4 | #define SZ(x) (int)(x).size() 5 | 6 | typedef complex C; 7 | typedef vector vd; 8 | void fft(vector& a) { 9 | int n = SZ(a), L = 31 - __builtin_clz(n); 10 | static vector> R(2, 1); 11 | static vector rt(2, 1); // (^ 10% faster if double) 12 | for (static int k = 2; k < n; k *= 2) { 13 | R.resize(n); rt.resize(n); 14 | auto x = polar(1.0L, acos(-1.0L) / k); 15 | rep(i,k,2*k) rt[i] = R[i] = i&1 ? R[i/2] * x : R[i/2]; 16 | } 17 | vector rev(n); 18 | rep(i,0,n) rev[i] = (rev[i / 2] | (i & 1) << L) / 2; 19 | rep(i,0,n) if (i < rev[i]) swap(a[i], a[rev[i]]); 20 | for (int k = 1; k < n; k *= 2) 21 | for (int i = 0; i < n; i += 2 * k) rep(j,0,k) { 22 | // C z = rt[j+k] * a[i+j+k]; // (25% faster if hand-rolled) /// include-line 23 | auto x = (double *)&rt[j+k], y = (double *)&a[i+j+k]; /// exclude-line 24 | C z(x[0]*y[0] - x[1]*y[1], x[0]*y[1] + x[1]*y[0]); /// exclude-line 25 | a[i + j + k] = a[i + j] - z; 26 | a[i + j] += z; 27 | } 28 | } 29 | vd conv(const vd& a, const vd& b) { 30 | if (a.empty() || b.empty()) return {}; 31 | vd res(SZ(a) + SZ(b) - 1); 32 | int L = 32 - __builtin_clz(SZ(res)), n = 1 << L; 33 | vector in(n), out(n); 34 | copy(ALL(a), begin(in)); 35 | rep(i,0,SZ(b)) in[i].imag(b[i]); 36 | fft(in); 37 | for (C& x : in) x *= x; 38 | rep(i,0,n) out[i] = in[-i & (n - 1)] - conj(in[i]); 39 | fft(out); 40 | rep(i,0,SZ(res)) res[i] = imag(out[i]) / (4 * n); 41 | return res; 42 | } -------------------------------------------------------------------------------- /FenwickTree.cpp: -------------------------------------------------------------------------------- 1 | class FenwickTree { 2 | const int IDENTITY = 0; 3 | int fn(int a, int b) { return a+b; } 4 | int invFn(int a, int b) { return a-b; } 5 | int diff(int i, int x) { return invFn(x, a[i]); } 6 | vector bit, a; 7 | public: 8 | FenwickTree(int n): bit(n, IDENTITY), a(n, IDENTITY) {} 9 | FenwickTree(vector &a): bit(SZ(a), IDENTITY), a(a) { 10 | for (int i = 0; i < SZ(a); i++) { 11 | bit[i] = fn(bit[i], a[i]); 12 | int r = i | (i+1); 13 | if (r < SZ(a)) bit[r] = fn(bit[r], bit[i]); 14 | } 15 | } 16 | void update(int i, int x) { 17 | int delta = diff(i,x); 18 | a[i] = x; 19 | for (int j = i; j < SZ(a); j |= (j+1)) { 20 | bit[j] = fn(bit[j], delta); 21 | } 22 | } 23 | int query(int r) { 24 | int res = IDENTITY; 25 | for (;r >= 0; r = (r & (r+1)) - 1) { 26 | res = fn(res, bit[r]); 27 | } 28 | return res; 29 | } 30 | int query(int l, int r) { 31 | return l == r ? a[l]: l > 0 ? invFn(query(r), query(l-1)): query(r); 32 | } 33 | }; -------------------------------------------------------------------------------- /KMP.cpp: -------------------------------------------------------------------------------- 1 | // returns the longest proper prefix array of pattern p 2 | // where lps[i]=longest proper prefix which is also suffix of p[0...i] 3 | vector build_lps(string p) { 4 | int sz = p.size(); 5 | vector lps; 6 | lps.assign(sz + 1, 0); 7 | int j = 0; 8 | lps[0] = 0; 9 | for(int i = 1; i < sz; i++) { 10 | while(j >= 0 && p[i] != p[j]) { 11 | if(j >= 1) j = lps[j - 1]; 12 | else j = -1; 13 | } 14 | j++; 15 | lps[i] = j; 16 | } 17 | return lps; 18 | } 19 | // returns matches in vector ans in 0-indexed 20 | vector kmp(vector lps, string s, string p) { 21 | vector ans; 22 | int psz = p.size(), sz = s.size(); 23 | int j = 0; 24 | for(int i = 0; i < sz; i++) { 25 | while(j >= 0 && p[j] != s[i]) 26 | if(j >= 1) j = lps[j - 1]; 27 | else j = -1; 28 | j++; 29 | if(j == psz) { 30 | j = lps[j - 1]; 31 | // pattern found in string s at position i-psz+1 32 | ans.push_back(i - psz + 1); 33 | } 34 | // after each loop we have j=longest common suffix of s[0..i] which is also prefix of p 35 | } 36 | return ans; 37 | } 38 | 39 | vector kmp(string str, string pattern) { 40 | return kmp(build_lps(pattern), str, pattern); 41 | } 42 | -------------------------------------------------------------------------------- /MatrixExpo.cpp: -------------------------------------------------------------------------------- 1 | const int MOD = (int)(1e9+7); 2 | 3 | class Matrix{ 4 | int n,m; 5 | vector > a; 6 | Matrix(int n, int m) { 7 | this->n = n; 8 | this->m = m; 9 | a.resize(n,vector (m)); 10 | } 11 | 12 | Matrix operator*(const Matrix& other) { 13 | assert(m == other.n); 14 | Matrix product(n,other.m); 15 | for(int i=0;i & operator[] (int i) { 27 | return a[i]; 28 | } 29 | }; 30 | 31 | Matrix getIdentity(int n) { 32 | Matrix ans(n,n); 33 | for(int i=0;i>= 1; 46 | } 47 | return res; 48 | } -------------------------------------------------------------------------------- /NumberTheory.cpp: -------------------------------------------------------------------------------- 1 | // Modular Arithmetic 2 | const int MOD = (1e9 + 7); 3 | 4 | int power(int a, int b, int c=MOD) { 5 | int res = 1; 6 | a %= c; 7 | while (b) { 8 | if (b&1) res = (res * a) % c; 9 | a = (a * a) % c; 10 | b >>= 1; 11 | } 12 | return res; 13 | } 14 | int inv(int a) { return power(a, MOD-2); } 15 | int addMod(int a, int b) { return ((a%MOD + b%MOD) % MOD + MOD) % MOD; } 16 | int subMod(int a, int b) { return addMod(a, -b); } 17 | int multMod(int a, int b) { return ((a%MOD * b%MOD) % MOD + MOD) % MOD; } 18 | int divMod(int a, int b) { return multMod(a, inv(b)); } 19 | 20 | // Sieve 21 | bitset<(int)1e6> SIEVE; 22 | void preSieve() { 23 | SIEVE[0]=SIEVE[1]=1; 24 | for (int i = 2; i*i < 1e6; i++) { 25 | if (!SIEVE[i]) { 26 | for (int j=i*i; j < 1e6; j+=i) { 27 | SIEVE[j]=1; 28 | } 29 | } 30 | } 31 | } 32 | 33 | // Prime factorization 34 | vector v(1e7+1); // v[i] = smallest prime factor of i 35 | void prePrimeFact() { 36 | for (int i = 0; i <= 1e7; i++) v[i] = i; 37 | for (int i = 2; i <= 1e7; i++) { 38 | if (v[i] != i) continue ; 39 | for (int j = i*i; j <= 1e7; j += i) { 40 | if (v[j]==j) v[j] = i; 41 | } 42 | } 43 | } 44 | vector primeFact(int n) { // with precalc - O(log) 45 | vector fct; 46 | while (n != 1) { 47 | int i = v[n]; 48 | while (n % i == 0) 49 | n /= i; 50 | fct.push_back(i); 51 | } 52 | return fct; 53 | } 54 | vector prime_fact(int n) { // without precalc - O(sqrt) 55 | vector ret; 56 | for (int i = 2; i*i <= n; i++) { 57 | if (n%i == 0) { 58 | ret.push_back(i); 59 | while (n%i == 0) 60 | n /= i; 61 | } 62 | } 63 | if (n > 1) ret.push_back(n); 64 | return ret; 65 | } 66 | 67 | // Factorial and Binomial Coefficient (n choose k) 68 | const int MAXN = 2e5 + 5; 69 | int fact[MAXN], ifact[MAXN]; 70 | void preFact() { 71 | fact[0] = ifact[0] = 1; 72 | for (int i = 1; i < MAXN; i++) { 73 | fact[i] = (fact[i-1] * i) % MOD; 74 | ifact[i] = (ifact[i-1] * inv(i)) % MOD; 75 | } 76 | } 77 | int nCk(int n, int k) { // (n choose k) 78 | return k > n? 0: (fact[n] * ((ifact[n-k] * ifact[k]) % MOD)) % MOD; 79 | } 80 | 81 | // Euler's totient function 82 | // a^phi(m) = 1 [modulo m] if a and m are coprimes 83 | int phi(int x) { 84 | int res = x; 85 | for (int i = 2; i*i <= x; i++) { 86 | if (x%i == 0) { 87 | while (x%i == 0) x /= i; 88 | res -= res / i; 89 | } 90 | } 91 | if (x > 1) res -= res / x; 92 | return res; 93 | } 94 | 95 | // phi preprocessing from 1 to n 96 | const int MAXN = 1e6 + 5; 97 | int PHI[MAXN]; 98 | void prePhi() { 99 | for (int i=0; i < MAXN; i++) PHI[i] = i; 100 | for (int i = 2; i < MAXN; i++) { 101 | if (PHI[i] == i) { 102 | for (int j = i; j < MAXN; j += i) { 103 | PHI[j] -= PHI[j] / i; 104 | } 105 | } 106 | } 107 | } 108 | 109 | int inv(int a, int m) { 110 | return power(a, PHI[m]-1, m); // or phi(m)-1 depends if m is big or no ! 111 | } 112 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Practicing 2 | 3 | * [CSES problemset](https://cses.fi/problemset/) 4 | * [Leetcode](https://leetcode.com/problemset/) 5 | * [Codeforces](https://codeforces.com/problemset) 6 | 7 | ### Youtube 8 | 9 | * [3blue1brown](https://www.youtube.com/c/3blue1brown/) 10 | * [NeatlyStructured](NeatlyStructured) 11 | * [Colin Galen](https://www.youtube.com/c/ColinGalen) 12 | * [WilliamFiset](https://www.youtube.com/c/WilliamFiset-videos) 13 | * [Back To Back SWE](https://www.youtube.com/channel/UCmJz2DV1a3yfgrR7GqRtUUA) 14 | * [Reducible](https://www.youtube.com/c/Reducible) 15 | 16 | ### Articles - Books 17 | 18 | * [cp-algorithms](https://cp-algorithms.com/) 19 | * [Competitive Programmer's Handbook](https://cses.fi/book/index.php) 20 | 21 | ### Tools 22 | 23 | * [code-library](https://github.com/ShahjalalShohag/code-library) 24 | * [kactl](https://github.com/kth-competitive-programming/kactl) 25 | * [WolframAlpha](https://www.wolframalpha.com/) 26 | * [Encyclopedia of sequences](https://oeis.org/) 27 | -------------------------------------------------------------------------------- /SegmentTree.cpp: -------------------------------------------------------------------------------- 1 | // from kactl 2 | struct SegTree { 3 | typedef int T; 4 | static const T identity = 0; 5 | T fn(T a, T b) { return a + b; } // (any associative fn) 6 | vector s; int n; 7 | SegTree(int n = 0, T def = identity) : s(4*n, def), n(n) {} 8 | SegTree(vector &a) : s(4*a.size()), n(a.size()) { 9 | for (int i = 0; i < n; i++) update(i, a[i]); 10 | } 11 | void update(int pos, T val) { 12 | for (s[pos += n] = val; pos /= 2;) 13 | s[pos] = fn(s[pos * 2], s[pos * 2 + 1]); 14 | } 15 | T query(int b, int e) { // query [b, e] 16 | T ra = identity, rb = identity; e++; 17 | for (b += n, e += n; b < e; b /= 2, e /= 2) { 18 | if (b % 2) ra = fn(ra, s[b++]); 19 | if (e % 2) rb = fn(s[--e], rb); 20 | } 21 | return fn(ra, rb); 22 | } 23 | }; 24 | 25 | // from https://github.com/jalalium/cpTemplates 26 | class SegTree2d { 27 | int lenx; 28 | int leny; 29 | vector> all; 30 | vector> seg; 31 | static const int identity = 0; 32 | int fn(int a, int b) {return a + b;} 33 | public: 34 | SegTree2d(){} 35 | SegTree2d(vector> inp) { 36 | lenx = inp.size(); 37 | leny = inp[0].size(); 38 | all = inp; 39 | seg.resize(4 *lenx); 40 | for (int i = 0; i < 4*lenx; i++) 41 | seg[i].resize(4*leny); 42 | buildx(1,1,0,lenx-1,0,leny-1); 43 | } 44 | // rows range: [lx , rx] 45 | // columns range: [ly , ry] 46 | int query(int lx,int rx,int ly,int ry) { 47 | return queryx(1,0,lenx-1,lx,rx,ly,ry); 48 | } 49 | // Update (x, y) 50 | void update(int x,int y, int val) { 51 | updatex(1,0,lenx-1,x,y,val); 52 | } 53 | int query(pair a, pair b) { 54 | return query(a.first, b.first, a.second, b.second); 55 | } 56 | private: 57 | void buildy(int idx, int idy, int lx, int rx, int ly, int ry) 58 | { 59 | if (ly==ry) 60 | { 61 | if (lx == rx) 62 | seg[idx][idy]= all[lx][ly]; 63 | else 64 | seg[idx][idy] = fn(seg[2*idx][idy] , seg[2*idx+1][idy]); 65 | } 66 | else 67 | { 68 | int midy=(ly+ry)/2; 69 | buildy(idx,2*idy,lx,rx,ly,midy); 70 | buildy(idx,2*idy+1,lx,rx,midy+1,ry); 71 | seg[idx][idy] = fn(seg[idx][2*idy], seg[idx][2*idy+1]); 72 | } 73 | } 74 | void buildx(int idx, int idy, int lx, int rx, int ly, int ry) 75 | { 76 | if (lx != rx) 77 | { 78 | int midx = (lx+rx)/2; 79 | buildx(2*idx,idy,lx,midx,ly,ry); 80 | buildx(2*idx+1,idy,midx+1,rx,ly,ry); 81 | } 82 | buildy(idx,idy,lx,rx,ly,ry); 83 | } 84 | int queryy(int idx, int idy, int tly,int tryy, int ly,int ry) 85 | { 86 | if (tly > ry || tryy < ly) 87 | return identity; 88 | if (tly >= ly && tryy <= ry) 89 | return seg[idx][idy]; 90 | int tmy = (tly+tryy)/2; 91 | return fn(queryy(idx,2*idy,tly,tmy,ly,ry), queryy(idx,2*idy+1,tmy+1,tryy,ly,ry)); 92 | } 93 | int queryx(int idx, int tlx,int trx, int lx,int rx,int ly,int ry) 94 | { 95 | if (tlx > rx || trx= lx && trx <= rx) 98 | return queryy(idx,1,0,leny-1,ly,ry); 99 | int tmx=(tlx+trx)/2; 100 | return fn(queryx(2*idx,tlx,tmx,lx,rx,ly,ry), queryx(2*idx+1,tmx+1,trx,lx,rx,ly,ry)); 101 | } 102 | void updatey(int idx, int tlx, int trx, int idy, int tly, int tryy, int y, int val) 103 | { 104 | if (tly == tryy) 105 | { 106 | if (tlx == trx) 107 | seg[idx][idy]=val; 108 | else 109 | seg[idx][idy] = fn(seg[2*idx][idy], seg[2*idx+1][idy]); 110 | } 111 | else 112 | { 113 | int tmy=(tly+tryy)/2; 114 | if (y <= tmy) 115 | updatey(idx,tlx,trx,2*idy,tly,tmy,y,val); 116 | else 117 | updatey(idx,tlx,trx,2*idy+1,tmy+1,tryy,y,val); 118 | seg[idx][idy] = fn(seg[idx][2*idy], seg[idx][2*idy+1]); 119 | } 120 | } 121 | void updatex(int idx, int tlx, int trx, int x, int y, int val) 122 | { 123 | if (tlx != trx) 124 | { 125 | int tmx = (tlx+trx)/2; 126 | if (x <= tmx) 127 | updatex(2*idx,tlx,tmx,x,y,val); 128 | else 129 | updatex(2*idx+1,tmx+1,trx,x,y,val); 130 | } 131 | updatey(idx, tlx, trx,1,0,leny-1,y, val); 132 | } 133 | }; 134 | 135 | -------------------------------------------------------------------------------- /SegmentTreeLazyPropagation.cpp: -------------------------------------------------------------------------------- 1 | struct LazySegTree { 2 | vector all; 3 | int n; 4 | vector s; 5 | vector lazy; 6 | int identity = 0; 7 | 8 | int fn(int a, int b){ 9 | return a + b; 10 | } 11 | LazySegTree(int n) { 12 | this->n = n; 13 | s.assign(4 * n, identity); 14 | lazy.assign(4 * n, identity); 15 | all.assign(n, identity); 16 | } 17 | LazySegTree(vector &a){ 18 | n = a.size(); 19 | all = a; 20 | s.resize(4 * n); 21 | lazy.resize(4 * n); 22 | build(1, 0, n - 1); 23 | } 24 | void build(int node, int start, int end){ 25 | if (start == end){ 26 | s[node] = all[start]; 27 | return ; 28 | } 29 | int mid = (start + end) / 2; 30 | build(2 * node, start, mid); 31 | build(2 * node + 1, mid + 1, end); 32 | s[node] = fn(s[2*node], s[2*node + 1]); 33 | } 34 | 35 | void push_down(int node, int start, int end) { 36 | s[node] += lazy[node] * (end - start + 1); 37 | if (start != end){ 38 | lazy[2 * node] += lazy[node]; 39 | lazy[2 * node + 1] += lazy[node]; 40 | } 41 | lazy[node] = 0; 42 | } 43 | 44 | void update(int node, int start, int end, int l, int r, int val){ 45 | push_down(node, start, end); 46 | if (start > r || end < l) return ; 47 | if (start >= l && end <= r){ 48 | lazy[node] += val; 49 | push_down(node, start, end); 50 | return ; 51 | } 52 | int mid = (start + end) / 2; 53 | update(2 * node, start, mid, l, r, val); 54 | update(2 * node + 1, mid + 1, end, l, r, val); 55 | s[node] = fn(s[2 * node], s[2 * node + 1]); 56 | } 57 | void update(int l, int r, int val){ 58 | update(1, 0, n - 1, l, r, val); 59 | } 60 | 61 | int query(int node, int start, int end, const int l, const int r){ 62 | push_down(node, start, end); 63 | if (start > r || end < l) return identity; 64 | if (start >= l && end <= r) return s[node]; 65 | int mid = (start + end) / 2; 66 | int left = query(2 * node, start, mid, l, r); 67 | int right = query(2 * node + 1, mid + 1, end, l, r); 68 | return fn(left, right); 69 | } 70 | int query(int l, int r){ 71 | return query(1, 0, n - 1, l, r); 72 | } 73 | }; 74 | -------------------------------------------------------------------------------- /SparseTable.cpp: -------------------------------------------------------------------------------- 1 | // from kactl library 2 | #define rep(i,a,b) for (int i = (a); i < (b); i++) 3 | template 4 | struct SparseTable { 5 | T fn(T a, T b) {return max(a, b); } 6 | vector> jmp; 7 | SparseTable(const vector& V) : jmp(1, V) { 8 | for (int pw = 1, k = 1; pw * 2 <= SZ(V); pw *= 2, ++k) { 9 | jmp.emplace_back(SZ(V) - pw * 2 + 1); 10 | rep(j,0,SZ(jmp[k])) 11 | jmp[k][j] = fn(jmp[k - 1][j], jmp[k - 1][j + pw]); 12 | } 13 | } 14 | T query(int a, int b) { b++; // [a,b] 15 | assert(a < b); // or return inf if a == b 16 | int dep = 31 - __builtin_clz(b - a); 17 | return fn(jmp[dep][a], jmp[dep][b - (1 << dep)]); 18 | } 19 | }; 20 | 21 | // with template function 22 | template 23 | struct SparseTable { 24 | vector> jmp; 25 | SparseTable(const vector& V) : jmp(1, V) { 26 | for (int pw = 1, k = 1; pw * 2 <= SZ(V); pw *= 2, ++k) { 27 | jmp.emplace_back(SZ(V) - pw * 2 + 1); 28 | rep(j,0,SZ(jmp[k])) 29 | jmp[k][j] = fn(jmp[k - 1][j], jmp[k - 1][j + pw]); 30 | } 31 | } 32 | T query(int a, int b) { b++; // [a,b] 33 | assert(a < b); // or return inf if a == b 34 | int dep = 31 - __builtin_clz(b - a); 35 | return fn(jmp[dep][a], jmp[dep][b - (1 << dep)]); 36 | } 37 | }; -------------------------------------------------------------------------------- /SqrtDecomposition.cpp: -------------------------------------------------------------------------------- 1 | int N = 1e5; 2 | int BLOCK_SZ = sqrt(N); 3 | 4 | struct Query { 5 | int l, r, idx; 6 | bool operator<(Query other) const { 7 | return make_pair(l / BLOCK_SZ, r) < 8 | make_pair(other.l / BLOCK_SZ, other.r); 9 | } 10 | }; 11 | 12 | vector solve(vector queries) { 13 | vector answers(queries.size()); 14 | sort(queries.begin(), queries.end()); 15 | 16 | int currL = 0; 17 | int currR = -1; 18 | int currAns = 0; 19 | for (Query q : queries) { 20 | int L = q.l, R = q.r, idx = q.idx; 21 | while (currL > L) { 22 | currL--; 23 | // currAns += add(currL); 24 | } 25 | while (currR < R) { 26 | currR++; 27 | // currAns += add(currR); 28 | } 29 | while (currL < L) { 30 | // currAns -= remove(currL); 31 | currL++; 32 | } 33 | while (currR > R) { 34 | // currAns -= remove(currR); 35 | currR--; 36 | } 37 | answers[q.idx] = currAns; 38 | } 39 | return answers; 40 | } -------------------------------------------------------------------------------- /Trie.cpp: -------------------------------------------------------------------------------- 1 | // source: https://gist.github.com/hrsvrdhn/1ae71c25ef1c620c022a544d52df8928 2 | struct Trie 3 | { 4 | map children; 5 | int prefixes; 6 | bool endofword; 7 | Trie() { 8 | prefixes=0; 9 | endofword=false; 10 | } 11 | void insert(string word) 12 | { 13 | Trie *current=this; 14 | for(int i=0;ichildren[ch]; 18 | if(!node) 19 | { 20 | node=new Trie(); 21 | current->children[word[i]]=node; 22 | } 23 | current=node; 24 | current->prefixes++; 25 | } 26 | current->endofword=true; 27 | } 28 | bool search(string word) 29 | { 30 | Trie *current=this; 31 | for(int i=0;ichildren[ch]; 35 | if(!node) 36 | return false; 37 | current=node; 38 | } 39 | return current->endofword; 40 | } 41 | int countPrefix(string word) 42 | { 43 | Trie *current=this; 44 | for(int i=0;ichildren[ch]; 48 | if(!node) 49 | { 50 | return 0; 51 | } 52 | current=node; 53 | } 54 | return current->prefixes; 55 | } 56 | }; 57 | -------------------------------------------------------------------------------- /template/debug.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | using namespace std; 4 | 5 | void __print(int x) {cerr << x;} 6 | void __print(long x) {cerr << x;} 7 | void __print(unsigned x) {cerr << x;} 8 | void __print(unsigned long x) {cerr << x;} 9 | void __print(unsigned long long x) {cerr << x;} 10 | void __print(float x) {cerr << x;} 11 | void __print(double x) {cerr << x;} 12 | void __print(char x) {cerr << '\'' << x << '\'';} 13 | void __print(const char *x) {cerr << '\"' << x << '\"';} 14 | void __print(const string &x) {cerr << '\"' << x << '\"';} 15 | void __print(bool x) {cerr << (x ? "true" : "false");} 16 | 17 | template 18 | void __print(const pair &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';} 19 | template 20 | void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";} 21 | void _print() {cerr << "]\n";} 22 | template 23 | void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);} 24 | 25 | #define debug(x...) cerr << "[" << #x << "] = ["; _print(x) -------------------------------------------------------------------------------- /template/template.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | using namespace __gnu_pbds; 7 | template using OrderedSet = tree, rb_tree_tag,tree_order_statistics_node_update>; 8 | template using OrderedMultiSet = tree, rb_tree_tag,tree_order_statistics_node_update>; 9 | #define int long long 10 | #define double long double 11 | #define endl '\n' 12 | #define ALL(a) a.begin(), a.end() 13 | #define RALL(a) a.rbegin(), a.rend() 14 | #define YESORNO(x) cout << (x? "YES\n": "NO\n") 15 | #define SZ(x) (int)(x.size()) 16 | template bool ckmin(T& a, const T b) { return b < a ? a = b, 1 : 0; } 17 | template bool ckmax(T& a, const T b) { return a < b ? a = b, 1 : 0; } 18 | 19 | #ifndef ONLINE_JUDGE 20 | #include "debug.hpp" 21 | #else 22 | #define debug(x...) 23 | #endif 24 | 25 | void solve(int testCase) { 26 | 27 | } 28 | 29 | int32_t main() { 30 | ios::sync_with_stdio(false); 31 | cin.tie(0); 32 | 33 | int t; cin >> t; 34 | while (t--) { 35 | solve(t); 36 | } 37 | } --------------------------------------------------------------------------------