├── 2D Segment Tree.cpp ├── 2SAT.cpp ├── AhoCorasick.cpp ├── ArticulationPointAndBridge.cpp ├── Barleykamp-Massey + Cayley Hamlnton.cpp ├── Binary Indexed Tree.cpp ├── BridgeTree.cpp ├── Cactus.cpp ├── Centroid Decompostion.cpp ├── Centroid Tree.cpp ├── Closest Pair of Points O(n lg^2 n).cpp ├── ConvexHull.cpp ├── ConvexHullTrick (Dynamic Online).cpp ├── ConvexHullTrick.cpp ├── DSU.cpp ├── Dinic.cpp ├── Discrete Log.cpp ├── Dominator Tree.cpp ├── EdmondKarp.cpp ├── FFT Applications.cpp ├── Fast Fourier Transform.cpp ├── Fast Input.cpp ├── Fast Walsh Hadamard Trandform.cpp ├── Gaussian Elimination.cpp ├── HLD.cpp ├── Hash.cpp ├── Hopcroft Karp.cpp ├── INF Knight.cpp ├── KMP.cpp ├── LCA.cpp ├── Lazy Array.cpp ├── LongestPathInDAG.cpp ├── MO'a algo with Updates.cpp ├── MO's Algo.cpp ├── Manacher.cpp ├── Manhattan MST.cpp ├── MatrixExpo.cpp ├── Max BPM.cpp ├── Max XOR Subset.cpp ├── Mex using Trie O(log Max).cpp ├── Millar-Rabin Primality Test.cpp ├── MinCostMaxFlow.cpp ├── Minimum Expression.cpp ├── Misc Geometry.cpp ├── Number Theoretic Transform.cpp ├── Number Theory for Copy Paste.cpp ├── PalindromicTree.cpp ├── Persistent Segment Tree.cpp ├── Persistent Trie.cpp ├── PolardRho.cpp ├── README.md ├── Segment Tree (Lazy Prop).cpp ├── Segment Tree.cpp ├── Simpson.cpp ├── Stoer-Wagner.cpp ├── Strongly Connected Components.cpp ├── Suffix Array.cpp ├── Suffix Automata.cpp ├── Treap (Basic Operations).cpp ├── Treap (Implict).cpp ├── Z-Algorithm.cpp ├── maxHistrogram.cpp ├── nCr mod M.cpp ├── nextGreaterElement.cpp └── slidingRMQ.cpp /2D Segment Tree.cpp: -------------------------------------------------------------------------------- 1 | /*///////////////////////////// 2 | 2D Segment Tree 3 | Needs O(16nm) memory!!! 4 | Be carefull writing lx, rx, ly, ry! 5 | //////////////////////////////*/ 6 | 7 | const int maxn = 2001; 8 | int tree[4*maxn][4*maxn], n, m, arr[maxn][maxn]; 9 | void buildY(int ndx, int lx, int rx, int ndy, int ly, int ry) { 10 | if(ly == ry) { 11 | if(lx == rx) tree[ndx][ndy] = arr[lx][ly]; 12 | else tree[ndx][ndy] = tree[ndx*2][ndy] + tree[ndx*2+1][ndy]; 13 | return; 14 | } int mid = ly + ry >> 1; 15 | buildY(ndx, lx, rx, ndy*2, ly, mid); 16 | buildY(ndx, lx, rx, ndy*2+1, mid+1, ry); 17 | tree[ndx][ndy] = tree[ndx][ndy*2] + tree[ndx][ndy*2+1]; 18 | } 19 | void buildX(int ndx, int lx, int rx) { 20 | if(lx != rx) { 21 | int mid = lx + rx >> 1; 22 | buildX(ndx*2, lx, mid); 23 | buildX(ndx*2+1, mid+1, rx); 24 | } buildY(ndx, lx, rx, 1, 0, m-1); 25 | } 26 | void updateY(int ndx, int lx, int rx, int ndy, int ly, int ry, int y, int val) { 27 | if(ly == ry) { 28 | if(lx == rx) tree[ndx][ndy] = val; 29 | else tree[ndx][ndy] = tree[ndx*2][ndy] + tree[ndx*2+1][ndy]; 30 | return; 31 | } int mid = ly + ry >> 1; 32 | if(y <= mid) updateY(ndx, lx, rx, ndy*2, ly, mid, y, val); 33 | else updateY(ndx, lx, rx, ndy*2+1, mid+1, ry, y, val); 34 | tree[ndx][ndy] = tree[ndx][ndy*2] + tree[ndx][ndy*2+1]; 35 | } 36 | void updateX(int ndx, int lx, int rx, int x, int y, int val) { 37 | if(lx != rx) { 38 | int mid = lx + rx >> 1; 39 | if(x <= mid) updateX(ndx*2, lx, mid, x, y, val); 40 | else updateX(ndx*2+1, mid+1, rx, x,y, val); 41 | } updateY(ndx, lx, rx, 1, 0, m-1, y,val); 42 | } 43 | 44 | int queryY(int ndx, int ndy, int ly, int ry, int y1, int y2) { 45 | if(ry < y1 || ly > y2) return 0; 46 | if(y1 <= ly && ry <= y2) 47 | return tree[ndx][ndy]; 48 | int mid = ly + ry >> 1; 49 | return queryY(ndx, ndy*2, ly, mid, y1, y2) + 50 | queryY(ndx, ndy*2+1, mid+1, ry, y1, y2); 51 | } 52 | int queryX(int ndx, int lx, int rx, int x1, int y1, int x2, int y2) { 53 | if(rx < x1 || lx > x2) return 0; 54 | if(x1 <= lx && rx <= x2) { 55 | return queryY(ndx, 1, 0, m-1, y1, y2); 56 | } int mid = lx + rx >> 1; 57 | return queryX(ndx*2, lx, mid, x1,y1,x2,y2) + 58 | queryX(ndx*2+1, mid+1, rx, x1,y1,x2,y2); 59 | } 60 | -------------------------------------------------------------------------------- /2SAT.cpp: -------------------------------------------------------------------------------- 1 | const int N = 1e5 + 5; 2 | 3 | vector g[2 * N], gt[2 * N]; 4 | int n; // number of variables 5 | int vis[2 * N], comp[2 * N], a[2 * N]; 6 | vector ord; 7 | 8 | #define Not(x) ((x)^1) 9 | #define var(x) (2 * (x)) 10 | #define zero(x) (2 * (x)) 11 | #define one(x) (2 * (x) + 1) 12 | 13 | void addImp(int u, int v) { 14 | g[u].push_back(v); 15 | gt[v].push_back(u); 16 | } 17 | 18 | void forceTrue(int x) { 19 | addImp(Not(x), x); 20 | } 21 | 22 | void addOr(int x, int y) { 23 | addImp(Not(x), y); 24 | addImp(Not(y), x); 25 | } 26 | 27 | void addXor(int x, int y) { 28 | addOr(x, y); 29 | addOr(Not(x), Not(y)); 30 | } 31 | 32 | void dfs(int u) { 33 | vis[u] = 1; 34 | for(int v : g[u]) if(!vis[v]) dfs(v); 35 | ord.push_back(u); 36 | } 37 | 38 | void color(int u, int c) { 39 | comp[u] = c; 40 | for(int v : gt[u]) if(!comp[v]) color(v, c); 41 | } 42 | 43 | bool solve() { 44 | int V = 2 * n; 45 | for(int i = 0; i < V; ++i) { 46 | if(!vis[i]) dfs(i); 47 | } 48 | for(int i = 0, j = 0; i < V; ++i) { 49 | int v = ord[V - i - 1]; 50 | if(!comp[v]) color(v, ++j); 51 | } 52 | for(int i = 0; i < V; ++i) { 53 | if(comp[i] == comp[Not(i)]) return 0; 54 | a[i] = comp[i] > comp[Not(i)]; 55 | } 56 | // solution in a[var(i)]. 57 | return 1; 58 | } -------------------------------------------------------------------------------- /AhoCorasick.cpp: -------------------------------------------------------------------------------- 1 | soconst int N = 1e6 + 10; 2 | int trie[N][26], link[N], idx, tot[N]; 3 | char p[N], s[N]; 4 | 5 | void insert() { 6 | int u = 0, len = strlen(p); 7 | for(int i = 0; i < len; i++) { 8 | int &v = trie[u][p[i] - 'a']; 9 | u = v = v ? v : ++idx; 10 | } tot[u]++; 11 | } 12 | void bfs() { 13 | queue q; 14 | for(q.push(0); !q.empty(); ) { 15 | int u = q.front(); q.pop(); 16 | for(int c = 0; c < 26; c++) { 17 | int &v = trie[u][c]; 18 | if(!v) v = trie[link[u]][c]; 19 | else { 20 | link[v] = u ? trie[link[u]][c] : 0; 21 | tot[v] += tot[link[v]]; 22 | q.push(v); 23 | } 24 | } 25 | } 26 | } 27 | int match() { 28 | int u = 0, len = strlen(s); 29 | int ret = 0; 30 | for(int i = 0; i < len; i++) { 31 | u = trie[u][s[i] - 'a']; 32 | ret += tot[u]; 33 | } return ret; 34 | } -------------------------------------------------------------------------------- /ArticulationPointAndBridge.cpp: -------------------------------------------------------------------------------- 1 | const int maxn = 1e5 + 10; 2 | vector adj[maxn]; 3 | int vis[maxn], low[maxn], cut[maxn], now = 0; 4 | 5 | void dfs(int u, int par) { 6 | low[u] = vis[u] = ++now; int ch = 0; 7 | for(int v : adj[u]) if(v - par) { 8 | if(vis[v]) low[u] = min(low[u], vis[v]); 9 | else { ch++; 10 | dfs(v, u); 11 | low[u] = min(low[u], low[v]); 12 | if(par + 1 && low[v] >= vis[u]) 13 | cut[u] = 1; 14 | if(low[v] > vis[u]) { 15 | printf("Bridge %d -- %d\n", u, v); 16 | } 17 | } 18 | } if(par == -1 && ch > 1) cut[u] = 1; 19 | } 20 | 21 | void ArticulationPointAndBridge() { 22 | memset(vis, 0, sizeof vis); 23 | memset(low, 0, sizeof low); 24 | memset(cut, 0, sizeof cut); 25 | now = 0; 26 | for(int i = 0; i < n; i++) { 27 | if(!vis[i]) dfs(i, -1); 28 | } 29 | } -------------------------------------------------------------------------------- /Barleykamp-Massey + Cayley Hamlnton.cpp: -------------------------------------------------------------------------------- 1 | vector BerlekampMassey(vector s) { 2 | int n = s.size(), L = 0, m = 0; 3 | vector C(n), B(n), T; 4 | C[0] = B[0] = 1; 5 | ll b = 1; 6 | for(int i = 0; i < n; ++i) { 7 | ++m; 8 | ll d = s[i] % mod; 9 | for(int j = 1; j <= L; ++j) 10 | d = (d + C[j] * s[i - j]) % mod; 11 | if (!d) continue; 12 | T = C; ll coef = d * Pow(b, mod-2) % mod; 13 | for(int j = m; j < n; ++j) 14 | C[j] = (C[j] - coef * B[j - m]) % mod; 15 | if (2 * L > i) continue; 16 | L = i + 1 - L; B = T; b = d; m = 0; 17 | } 18 | 19 | C.resize(L + 1); C.erase(C.begin()); 20 | for (ll &x : C) x = (mod - x) % mod; 21 | return C; 22 | } 23 | 24 | ll linearRec(vector S, vector tr, ll k) { 25 | int n = S.size(); 26 | 27 | auto combine = [&](vector a, vector b) { 28 | vector res(n * 2 + 1); 29 | for(int i = 0; i <= n; ++i) for(int j = 0; j <= n; ++j) 30 | res[i + j] = (res[i + j] + a[i] * b[j]) % mod; 31 | for(int i = 2 * n; i > n; --i) for(int j = 0; j < n; ++j) 32 | res[i-1-j]=(res[i-1-j] + res[i] * tr[j]) % mod; 33 | res.resize(n + 1); 34 | return res; 35 | }; 36 | 37 | vector pol(n + 1), e(pol); 38 | pol[0] = e[1] = 1; 39 | 40 | for (++k; k; k /= 2) { 41 | if (k % 2) pol = combine(pol, e); 42 | e = combine(e, e); 43 | } 44 | 45 | ll res = 0; 46 | for(int i = 0; i < n; ++i) 47 | res = (res + pol[i + 1] * S[i]) % mod; 48 | return res; 49 | } -------------------------------------------------------------------------------- /Binary Indexed Tree.cpp: -------------------------------------------------------------------------------- 1 | 2 | struct BIT { 3 | vector A, M; int sz; 4 | void init(int n) { 5 | A = M = vector(n + 5, 0); 6 | sz = n; 7 | } 8 | void upd(int x, ll m, ll a) { 9 | for(; x <= sz; x += x & -x) 10 | M[x] += m, A[x] += a; 11 | } 12 | void update(int l, int r, ll v) { 13 | upd(l, v, -(l - 1) * v); 14 | upd(r, -v, r * v); 15 | } 16 | ll query(int idx) { 17 | ll mul = 0, add = 0; 18 | for(int x = idx; x > 0; x -= x & -x) 19 | mul += M[x], add += A[x]; 20 | return mul * idx + add; 21 | } 22 | ll query(int l, int r) { 23 | return query(r) - query(l - 1); 24 | } 25 | } t; -------------------------------------------------------------------------------- /BridgeTree.cpp: -------------------------------------------------------------------------------- 1 | const int N = 2e5 + 5; 2 | vector adj[N]; 3 | int n, m, vis[N], low[N], tym, idx; 4 | stack st; 5 | vector> comps; 6 | 7 | void generate_comp(int v = -1) { 8 | vector comp; 9 | while (st.size()) { 10 | int w = st.top(); 11 | comp.push_back(w); 12 | // comp[w] = idx; 13 | st.pop(); 14 | if(w == v) break; 15 | } 16 | comps.push_back(comp); 17 | } 18 | 19 | void dfs(int u, int p) { 20 | low[u] = vis[u] = ++tym; 21 | st.push(u); 22 | for (int v : adj[u]) { 23 | if (vis[v]) { 24 | if (v != p) low[u] = min(low[u], vis[v]); 25 | else p = 0; 26 | } else { 27 | dfs(v, u); 28 | low[u] = min(low[u], low[v]); 29 | if (low[v] > vis[u]) generate_comp(v); 30 | } 31 | } 32 | } 33 | 34 | int main() { 35 | scanf("%d %d", &n, &m); 36 | while (m--) { 37 | int u, v; 38 | scanf("%d %d", &u, &v); 39 | adj[u].push_back(v); 40 | adj[v].push_back(u); 41 | } 42 | 43 | for (int i = 1; i <= n; ++i) { 44 | if (vis[i]) continue; 45 | dfs(i, 0); 46 | // roots.push_back(idx); 47 | generate_comp(); 48 | } 49 | 50 | return 0; 51 | } -------------------------------------------------------------------------------- /Cactus.cpp: -------------------------------------------------------------------------------- 1 | // Vertex Cactus 2 | 3 | const int N = 2e5 + 5; 4 | vector adj[N]; 5 | int n, m, l[N], r[N], vis[N], cycId[N], cyc; // cyc = n 6 | 7 | stack st; 8 | void dfs(int u, int p) { 9 | vis[u] = 1; 10 | st.push(u); 11 | 12 | for (int i : adj[u]) { 13 | int v = u ^ l[i] ^ r[i]; 14 | if (v == p) continue; 15 | if (vis[v]) { 16 | if (!cycId[v]) { 17 | cycId[v] = ++cyc; 18 | while (st.top() != v) { 19 | cycId[st.top()] = cyc; 20 | st.pop(); 21 | } 22 | st.pop(); 23 | } 24 | } else { 25 | dfs(v, u); 26 | } 27 | } 28 | 29 | if (!cycId[u]) cycId[u] = u; 30 | if(st.size() && st.top() == u) st.pop(); 31 | } 32 | 33 | -------------------------------------------------------------------------------- /Centroid Decompostion.cpp: -------------------------------------------------------------------------------- 1 | // Sample implementation of Centroid Decomposition. 2 | // This solves the problem "count number of k length paths in tree" 3 | // TODO: Do book-keeping in solve() instead of unordered_map 4 | 5 | const int maxn = 1e5 + 10; 6 | int n, k, vis[maxn], sub[maxn]; 7 | vector adj[maxn]; 8 | 9 | void calc(int u, int par) { sub[u] = 1; 10 | for(int v : adj[u]) if(!vis[v] && v - par) 11 | calc(v, u), sub[u] += sub[v]; 12 | } 13 | int centroid(int u, int par, int r) { 14 | for(int v : adj[u]) if(!vis[v] && v - par) 15 | if(sub[v] > r) return centroid(v, u, r); 16 | return u; 17 | } 18 | 19 | int dist[maxn]; ll ans; 20 | int in[maxn], out[maxn], vert[maxn], tym = 0; 21 | 22 | void dfs(int u, int par = -1, int d = 0) { 23 | dist[u] = d; 24 | in[u] = tym; 25 | vert[tym++] = u; 26 | for(int v : adj[u]) if(v - par && !vis[v]) 27 | dfs(v, u, d + 1); 28 | out[u] = tym - 1; 29 | } 30 | 31 | void solve(int u) { 32 | tym = 0; dfs(u); 33 | unordered_map cnt; cnt[0] = 1; 34 | for(int v : adj[u]) if(!vis[v]) { 35 | for(int t = in[v]; t <= out[v]; ++t) 36 | if(dist[vert[t]] <= k) 37 | ans += cnt[k - dist[vert[t]]]; 38 | for(int t = in[v]; t <= out[v]; ++t) 39 | ++cnt[dist[vert[t]]]; 40 | } 41 | } 42 | 43 | void decomp(int u, int par = -1) { 44 | calc(u, par); 45 | int c = centroid(u, par, sub[u] / 2); 46 | solve(c); vis[c] = 1; 47 | for(int v : adj[c]) if(!vis[v]) decomp(v, c); 48 | } 49 | -------------------------------------------------------------------------------- /Centroid Tree.cpp: -------------------------------------------------------------------------------- 1 | ///////////////////// 2 | // p[u] = parent of u in centroid tree 3 | // d[x][u] = distance from u to a parent of u at level x of centroid tree 4 | // if u is in subtree of centroid c, then d[lvl[c]][u] = dist(c, l) 5 | ///////////////////// 6 | const int maxn = 1e5 + 10; 7 | vector adj[maxn]; 8 | int lvl[maxn], sub[maxn], p[maxn], vis[maxn], d[18][maxn], ans[maxn]; 9 | 10 | void calc(int u, int par) { sub[u] = 1; 11 | for(int v : adj[u]) if(v - par && !vis[v]) 12 | calc(v, u), sub[u] += sub[v]; 13 | } 14 | int centroid(int u, int par, int r) { 15 | for(int v : adj[u]) if(v - par && !vis[v]) 16 | if(sub[v] > r) return centroid(v, u, r); 17 | return u; 18 | } 19 | void dfs(int l, int u, int par) { 20 | if(par + 1) d[l][u] = d[l][par] + 1; 21 | for(int v : adj[u]) if(v - par && !vis[v]) 22 | dfs(l, v, u); 23 | } 24 | void decompose(int u, int par) { 25 | calc(u, -1); 26 | int c = centroid(u, -1, sub[u] >> 1); 27 | vis[c] = 1, p[c] = par; 28 | if(par + 1) lvl[c] = lvl[par] + 1; 29 | dfs(lvl[c], c, -1); 30 | for(int v : adj[c]) if(v - par && !vis[v]) 31 | decompose(v, c); 32 | } 33 | 34 | void update(int u) { 35 | for(int v = u; v + 1; v = p[v]) 36 | ans[v] = min(ans[v], d[lvl[v]][u]); 37 | } 38 | int query(int u) { 39 | int ret = 1e9; 40 | for(int v = u; v + 1; v = p[v]) 41 | ret = min(ret, ans[v] + d[lvl[v]][u]); 42 | return ret; 43 | } -------------------------------------------------------------------------------- /Closest Pair of Points O(n lg^2 n).cpp: -------------------------------------------------------------------------------- 1 | // O(n lg^2 n) 2 | typedef long long ll; 3 | #define sq(a) ((a)*(a)) 4 | struct point { 5 | ll x, y; 6 | bool operator < (const point &p) const { 7 | return x == p.x ? y < p.y : x < p.x; 8 | } 9 | }; 10 | ll dist(point &p, point &q) { return sq(p.x - q.x) + sq(p.y - q.y); } 11 | vector p; 12 | ll solve(int l, int r) { 13 | if(r - l <= 3) { 14 | ll ret = 1e18; 15 | for(int i = l; i <= r; i++) 16 | for(int j = i + 1; j <= r; j++) 17 | ret = min(ret, dist(p[i], p[j])); 18 | return ret; 19 | } 20 | int mid = l + r >> 1; 21 | ll d = min(solve(l, mid), solve(mid+1, r)); 22 | 23 | vector t; 24 | for(int i = l; i <= r; i++) 25 | if(sq(p[mid].x - p[i].x) <= d) 26 | t.push_back({p[i].y, p[i].x}); 27 | 28 | sort(t.begin(), t.end()); 29 | for(int i = 0; i < t.size(); i++) { 30 | for(int j = i+1; j < t.size() && j <= i + 15; j++) 31 | d = min(d, dist(t[i], t[j])); 32 | } return d; 33 | } 34 | ll closestPair() { 35 | sort(p.begin(), p.end()); 36 | return solve(0, p.size()-1); 37 | } -------------------------------------------------------------------------------- /ConvexHull.cpp: -------------------------------------------------------------------------------- 1 | typedef long long ll; 2 | struct point{ 3 | int x, y; 4 | bool operator < (const point &p) const { 5 | return x == p.x ? y < p.y : x < p.x; 6 | } 7 | }; 8 | ll cross (point a, point b, point c) { 9 | return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x); 10 | } 11 | vector ConvexHull(vector&p, int n) { 12 | int sz = 0; 13 | vector hull(n + n); 14 | sort(p.begin(), p.end()); 15 | for(int i = 0; i < n; ++i) { 16 | while (sz > 1 and cross(hull[sz - 2], hull[sz - 1], p[i]) <= 0) --sz; 17 | hull[sz++] = p[i]; 18 | } 19 | for(int i = n - 2, j = sz + 1; i >= 0; --i) { 20 | while (sz >= j and cross(hull[sz - 2], hull[sz - 1], p[i]) <= 0) --sz; 21 | hull[sz++] = p[i]; 22 | } 23 | hull.resize(sz - 1); 24 | return hull; 25 | } -------------------------------------------------------------------------------- /ConvexHullTrick (Dynamic Online).cpp: -------------------------------------------------------------------------------- 1 | 2 | // Keeps upper hull for maximums. 3 | // add lines with -m and -b and return -ans to 4 | // make this code working for minimums. 5 | // (Self Written) 6 | 7 | typedef long double ld; 8 | const ld inf = 1e18; 9 | 10 | struct chtDynamic { 11 | struct line { 12 | ll m, b; ld x; 13 | ll val; bool isQuery; 14 | line(ll _m = 0, ll _b = 0) : 15 | m(_m), b(_b), val(0), x(-inf), isQuery(false) {} 16 | 17 | ll eval(ll x) const { return m * x + b; } 18 | bool parallel(const line &l) const { return m == l.m; } 19 | ld intersect(const line &l) const { 20 | return parallel(l) ? inf : 1.0 * (l.b - b) / (m - l.m); 21 | } 22 | bool operator < (const line &l) const { 23 | if(l.isQuery) return x < l.val; 24 | else return m < l.m; 25 | } 26 | }; 27 | 28 | set hull; 29 | typedef set :: iterator iter; 30 | 31 | bool cPrev(iter it) { return it != hull.begin(); } 32 | bool cNext(iter it) { return it != hull.end() && next(it) != hull.end(); } 33 | 34 | bool bad(const line &l1, const line &l2, const line &l3) { 35 | return l1.intersect(l3) <= l1.intersect(l2); 36 | } 37 | bool bad(iter it) { 38 | return cPrev(it) && cNext(it) && bad(*prev(it), *it, *next(it)); 39 | } 40 | 41 | iter update(iter it) { 42 | if(!cPrev(it)) return it; 43 | ld x = it -> intersect(*prev(it)); 44 | line tmp(*it); tmp.x = x; 45 | it = hull.erase(it); 46 | return hull.insert(it, tmp); 47 | } 48 | 49 | void addLine(ll m, ll b) { 50 | line l(m, b); 51 | iter it = hull.lower_bound(l); 52 | if(it != hull.end() && l.parallel(*it)) { 53 | if(it -> b < b) it = hull.erase(it); 54 | else return; 55 | } 56 | 57 | it = hull.insert(it, l); 58 | if(bad(it)) return (void) hull.erase(it); 59 | 60 | while(cPrev(it) && bad(prev(it))) hull.erase(prev(it)); 61 | while(cNext(it) && bad(next(it))) hull.erase(next(it)); 62 | 63 | it = update(it); 64 | if(cPrev(it)) update(prev(it)); 65 | if(cNext(it)) update(next(it)); 66 | } 67 | 68 | ll query(ll x) const { 69 | if(hull.empty()) return -inf; 70 | line q; q.val = x, q.isQuery = 1; 71 | iter it = --hull.lower_bound(q); 72 | return it -> eval(x); 73 | } 74 | } ds; 75 | 76 | 77 | // Short code and faster 78 | // Keeps upper hull for maximums. 79 | // add lines with -m and -b and return -ans to 80 | // make this code working for minimums. 81 | // source: http://codeforces.com/blog/entry/11155?#comment-162462 82 | 83 | const ll is_query = -(1LL<<62); 84 | struct Line { 85 | ll m, b; 86 | mutable function succ; 87 | bool operator<(const Line& rhs) const { 88 | if (rhs.b != is_query) return m < rhs.m; 89 | const Line* s = succ(); 90 | if (!s) return 0; 91 | ll x = rhs.m; 92 | return b - s->b < (s->m - m) * x; 93 | } 94 | }; 95 | struct HullDynamic : public multiset { 96 | bool bad(iterator y) { 97 | auto z = next(y); 98 | if (y == begin()) { 99 | if (z == end()) return 0; 100 | return y->m == z->m && y->b <= z->b; 101 | } 102 | auto x = prev(y); 103 | if (z == end()) return y->m == x->m && y->b <= x->b; 104 | return 1.0 * (x->b - y->b)*(z->m - y->m) >= 1.0 * (y->b - z->b)*(y->m - x->m); 105 | } 106 | void insert_line(ll m, ll b) { 107 | auto y = insert({ m, b }); 108 | y->succ = [=] { return next(y) == end() ? 0 : &*next(y); }; 109 | if (bad(y)) { erase(y); return; } 110 | while (next(y) != end() && bad(next(y))) erase(next(y)); 111 | while (y != begin() && bad(prev(y))) erase(prev(y)); 112 | } 113 | ll eval(ll x) { 114 | auto l = *lower_bound((Line) { x, is_query }); 115 | return l.m * x + l.b; 116 | } 117 | }; 118 | 119 | -------------------------------------------------------------------------------- /ConvexHullTrick.cpp: -------------------------------------------------------------------------------- 1 | /*------Non-Dynamic Convex Hull Trick--------*\ 2 | Requirements: 3 | If m[] is decreasing: 4 | If we want minimums then bad(s-3, s-2, s-1), x[] increasing 5 | If we want maximums then bad(s-1, s-2, s-3), x[] decreasing 6 | 7 | If m[] is increasing: 8 | If we want maximums then bad(s-3, s-2, s-1), x[] increasing 9 | If we want minimums then bad(s-1, s-2, s-3), x[] decreasing 10 | 11 | If x isn't monotonic, then do Ternary Search or keep intersections and do binary search 12 | /*-------------------------------------------*/ 13 | struct CHT{ 14 | vector m, b; 15 | int ptr = 0; 16 | bool bad(int l1, int l2, int l3) { // returns intersect(l1, l3) <= intersect(l1, l2) 17 | return 1.0 * (b[l3] - b[l1]) * (m[l1] - m[l2]) <= 1.0 * (b[l2] - b[l1]) * (m[l1] - m[l3]); 18 | } 19 | 20 | void add(ll _m, ll _b) { 21 | m.push_back(_m); 22 | b.push_back(_b); 23 | int s = m.size(); 24 | while(s >= 3 && bad(s-3, s-2, s-1)) { 25 | s--; 26 | m.erase(m.end()-2); 27 | b.erase(b.end()-2); 28 | } 29 | } 30 | ll f(int i, ll x) { return m[i]*x + b[i]; } 31 | 32 | ll query(ll x) { 33 | if(ptr >= m.size()) ptr = m.size()-1; 34 | while(ptr < m.size()-1 && 35 | f(ptr+1, x) < f(ptr, x)) ptr++; 36 | return f(ptr, x); 37 | } 38 | }; 39 | 40 | -------------------------------------------------------------------------------- /DSU.cpp: -------------------------------------------------------------------------------- 1 | struct dsu { 2 | vector p; // p[u] = u is root ? -size : parent; 3 | 4 | dsu(int n) : p(n + 1, -1) {} 5 | 6 | int Union(int u, int v) { 7 | u = Find(u), v = Find(v); 8 | if (u == v) return u; 9 | if (-p[u] < -p[v]) swap(u, v); 10 | p[u] += p[v]; 11 | p[v] = u; 12 | return u; 13 | } 14 | 15 | int Find(int u) { return p[u] < 0 ? u : p[u] = Find(p[u]); } 16 | 17 | bool IsSame(int u, int v) { return Find(u) == Find(v); } 18 | 19 | int Size(int u) { return -p[Find(u)]; } 20 | }; 21 | -------------------------------------------------------------------------------- /Dinic.cpp: -------------------------------------------------------------------------------- 1 | template 2 | class MaxFlow { 3 | public: 4 | struct Edge { 5 | int u, v; 6 | T cap, flow; 7 | Edge(int u, int v, T cap, T flow) : u(u), v(v), cap(cap), flow(flow) {} 8 | }; 9 | vector adj[N]; 10 | vector E; 11 | int n, s, t, ptr[N], dist[N], Q[N]; 12 | 13 | inline void init(int _n, int _s, int _t) { 14 | n = _n, s = _s, t = _t; 15 | E.clear(); 16 | for (int i = 0; i < n; ++i) { 17 | adj[i].clear(); 18 | } 19 | } 20 | inline void addEdge(int u, int v, T cap, bool directed = true) { 21 | adj[u].push_back(E.size()); 22 | E.emplace_back(u, v, cap, 0); 23 | adj[v].push_back(E.size()); 24 | E.emplace_back(v, u, directed ? 0 : cap, 0); 25 | } 26 | inline bool bfs() { 27 | memset(dist, -1, sizeof(dist[0]) * n); 28 | int f = 0, l = 0; 29 | dist[s] = 0, Q[l++] = s; 30 | while (f < l && dist[t] == -1) { 31 | int u = Q[f++]; 32 | for (int i : adj[u]) { 33 | if (dist[E[i].v] == -1 && E[i].flow < E[i].cap) 34 | Q[l++] = E[i].v, dist[E[i].v] = dist[u] + 1; 35 | } 36 | } 37 | return dist[t] != -1; 38 | } 39 | T dfs(int u, T pf) { 40 | if (u == t || !pf) return pf; 41 | while (ptr[u] < adj[u].size()) { 42 | int i = adj[u][ptr[u]]; 43 | if (dist[E[i].v] == dist[u] + 1) { 44 | if (T x = dfs(E[i].v, min(pf, E[i].cap - E[i].flow))) { 45 | E[i].flow += x, E[i ^ 1].flow -= x; 46 | return x; 47 | } 48 | } 49 | ++ptr[u]; 50 | } 51 | return 0; 52 | } 53 | T flow() { 54 | T res = 0; 55 | while (bfs()) { 56 | memset(ptr, 0, n * sizeof(ptr[0])); 57 | while (T f = dfs(s, numeric_limits::max())) res += f; 58 | } 59 | return res; 60 | } 61 | }; 62 | 63 | -------------------------------------------------------------------------------- /Discrete Log.cpp: -------------------------------------------------------------------------------- 1 | // Finds minimum x such that a^x = b (mod m) 2 | ll shanks(ll a, ll b, ll m) { 3 | a %= m, b %= m; ll n = sqrt(m) + 1; 4 | unordered_map mp; 5 | ll an = 1, base = 1, ans = -1; 6 | for(int i = 0; i < n; i++) an = (an * a) % m; 7 | for(int i = 1; i <= n; i++) { 8 | base = (base * an) % m; 9 | if(!mp.count(base)) 10 | mp[base] = i; 11 | } base = b; 12 | for(int j = 0; j <= n; j++) { 13 | if(mp.count(base)) { 14 | ll ret = mp[base] * n - j; 15 | if(ans == -1 || (ret < m && ans > ret)) ans = ret; 16 | } base = (base * a) % m; 17 | } return ans; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /Dominator Tree.cpp: -------------------------------------------------------------------------------- 1 | /* /////////////////////// 2 | * adj[u] contains child of u in dominator tree 3 | * par[u] contains parent of u in DAG 4 | * dom[u] = immediate dominator of u 5 | *///////////////////////// 6 | vector adj[maxn], par[maxn], topo; 7 | int dom[maxn], L[maxn], p[maxn][22], vis[maxn]; 8 | 9 | void addEdge(int u, int v) { // Construct your DAG using this fucntion. 10 | adj[u].push_back(v); 11 | par[v].push_back(u); 12 | } 13 | void dfs(int u) { // topo sort 14 | if(vis[u]) return; vis[u] = 1; 15 | for(int v : adj[u]) if(!vis[v]) dfs(v); 16 | topo.push_back(u); 17 | } 18 | void addToTree(int par, int u) { // Adds edge (par, u) to dominator tree. 19 | dom[u] = par; p[u][0] = par; 20 | L[u] = L[par] + 1; 21 | for(int i = 1; i <= 20; ++i) 22 | if(p[u][i - 1] + 1) 23 | p[u][i] = p[p[u][i-1]][i-1]; 24 | } 25 | int lca(int u, int v) { 26 | if(L[u] < L[v]) swap(u, v); 27 | for(int i = 20; i >= 0; --i) 28 | if(p[u][i] + 1 && L[p[u][i]] >= L[v]) 29 | u = p[u][i]; 30 | if(u == v) return u; 31 | for(int i = 20; i >= 0; --i) 32 | if(p[u][i] - p[v][i]) 33 | u = p[u][i], v = p[v][i]; 34 | return p[v][0]; 35 | } 36 | void DominatorTree(int root) { 37 | dfs(root); 38 | memset(p, -1, sizeof p); 39 | memset(dom, -1, sizeof dom); 40 | for(int i = (int) topo.size() - 2; i >= 0; --i) { 41 | int u = topo[i], d = -1; 42 | for(int v : par[u]) d = d == -1 ? v : lca(v, d); 43 | addToTree(d, u); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /EdmondKarp.cpp: -------------------------------------------------------------------------------- 1 | 2 | const int maxn = 111; 3 | struct Edmonds { // O(VE^2) 4 | struct edge { int u, v, cap, flow; }; 5 | vector E; 6 | vector adj[maxn]; 7 | int vis[maxn], par[maxn], Min[maxn]; 8 | 9 | void clear() { 10 | E.clear(); 11 | for(int i = 0; i < maxn; i++) 12 | adj[i].clear(); 13 | } 14 | 15 | void addEdge(int u, int v, int w) { 16 | E.push_back({u, v, w, 0}); 17 | adj[u].push_back(E.size() - 1); 18 | E.push_back({v, u, 0, 0}); 19 | adj[v].push_back(E.size() - 1); 20 | } 21 | int get(int s, int t) { 22 | int flow = 0; 23 | while(1) { 24 | memset(vis, 0, sizeof vis); 25 | memset(Min, 0, sizeof Min); 26 | queue q; q.push(s); 27 | Min[s] = 1e9, vis[s] = 1; 28 | while(!q.empty()) { 29 | int u = q.front(); q.pop(); 30 | if(u == t) break; 31 | for(int idx : adj[u]) { 32 | edge e = E[idx]; int v = e.v; 33 | if(!vis[v] && e.cap > e.flow) { 34 | Min[v] = min(Min[u], e.cap - e.flow); 35 | par[v] = idx; 36 | q.push(v); 37 | vis[v] = 1; 38 | } 39 | } 40 | } if(Min[t] == 0) break; 41 | for(int u = t; u != s; u = E[par[u]].u) { 42 | E[par[u]].flow += Min[t]; 43 | E[par[u] + 1].flow -= Min[t]; 44 | } flow += Min[t]; 45 | } return flow; 46 | } 47 | } mf; -------------------------------------------------------------------------------- /FFT Applications.cpp: -------------------------------------------------------------------------------- 1 | /********************************* 2 | * polyinv(a, b, n) calculates b: b(z)a(z) = 1 (mod z^n) 3 | * polysqrt(a, b, n) calculates b: b(z)^2 = a(z) (mod z^n) 4 | * make sure ta[], tb[] has 2n spaces to be used. 5 | * in polysqrt(), if a[0] != 1 then discrete sqrt function is needed 6 | **********************************/ 7 | 8 | void mul(int *a, int *b, int *c, int n, int m) { 9 | static int f[N], g[N]; 10 | 11 | int sz = n + m - 1; 12 | while(sz & (sz - 1)) sz = (sz | (sz - 1)) + 1; 13 | memcpy(f, a, n << 2), memcpy(g, b, m << 2); 14 | memset(f + n, 0, sz - n << 2), memset(g + m, 0, sz - n << 2); 15 | 16 | fft(f, sz), fft(g, sz); 17 | for(int i = 0; i < sz; ++i) 18 | f[i] = (ll) f[i] * g[i] % mod; 19 | reverse(f + 1, f + sz); 20 | fft(f, sz); 21 | 22 | int inv_n = Pow(sz, mod - 2); 23 | for(int i = 0; i < sz; ++i) 24 | c[i] = (ll) f[i] * inv_n % mod; 25 | } 26 | 27 | // a[0] != 0, a has degee (deg - 1), first n terms of inverse. 28 | void polyinv(int *a, int *b, int deg, int n) { 29 | static int x[N], y[N]; 30 | b[0] = Pow(a[0], mod - 2); 31 | int sz = 1; 32 | while(sz < n) { 33 | sz <<= 1; 34 | for(int i = 0; i < sz; ++i) x[i] = i < deg ? a[i] : 0; 35 | for(int i = 0; i < sz; ++i) y[i] = 2 * i < sz ? b[i] : 0; 36 | fft(x, sz), fft(y, sz); 37 | for(int i = 0; i < sz; ++i) x[i] = mul(x[i], y[i]); 38 | reverse(x + 1, x + sz), fft(x, sz); 39 | for(int i = sz / 2; i < sz; ++i) x[i - sz / 2] = x[i], x[i] = 0; 40 | fft(x, sz); 41 | for(int i = 0; i < sz; ++i) x[i] = mul(x[i], mod - y[i]); 42 | reverse(x + 1, x + sz), fft(x, sz); 43 | int inv_n2 = Pow(sz, mod - 3); 44 | for(int i = sz / 2; i < sz; ++i) b[i] = mul(x[i - sz / 2], inv_n2); 45 | } 46 | } 47 | 48 | // a[0] = 1, a has degee (deg - 1), first n terms of ln. 49 | void polyln(int *a, int *b, int deg, int n) { 50 | static int c[N], inv[N]; 51 | if(!inv[1]) { 52 | inv[1] = 1; 53 | for(int i = 2; i < N; ++i) // change n as needed. 54 | inv[i] = mul(mod - mod / i, inv[mod % i]); 55 | } 56 | polyinv(a, c, deg, n); 57 | for(int i = 0; i < n; ++i) b[i] = mul(i + 1, i + 1 < deg ? a[i + 1] : 0); 58 | mul(b, c, b, n, n); 59 | for(int i = n - 1; i > 0; --i) b[i] = mul(b[i - 1], inv[i]); 60 | b[0] = 0; 61 | } 62 | 63 | 64 | // a[0] = 0. a has degree (deg - 1). 65 | void polyexp(int *a, int *b, int deg, int n) { 66 | static int x[N], y[N]; 67 | b[0] = 1; 68 | int sz = 1; 69 | while(sz < n) { 70 | sz <<= 1; 71 | for(int i = 0; i < sz; ++i) x[i] = 2 * i < sz ? b[i] : 0; 72 | fft(x, sz), polyln(b, y, sz / 2, sz); 73 | for(int i = sz / 2; i < sz; ++i) { 74 | int t = i < deg ? a[i] : 0; 75 | y[i - sz / 2] = t - y[i] < 0 ? t - y[i] + mod : t - y[i], y[i] = 0; 76 | } 77 | fft(y, sz); 78 | for(int i = 0; i < sz; ++i) x[i] = mul(x[i], y[i]); 79 | reverse(x + 1, x + sz); 80 | fft(x, sz); 81 | int inv_n = Pow(sz, mod - 2); 82 | for(int i = sz / 2; i < sz; ++i) b[i] = mul(x[i - sz / 2], inv_n); 83 | } 84 | } 85 | 86 | 87 | // first n terms of a^k. 88 | void polypow(int *a, int *b, int deg, int k, int n) { 89 | static int c[N]; 90 | memset(b, 0, n << 2); 91 | int m = 0; 92 | while(m < deg && a[m] == 0) ++m; 93 | if((ll) m * k > n) return; 94 | int leading = a[m], inv = Pow(leading, mod - 2), scale = Pow(leading, k); 95 | for(int i = m; i < deg; ++i) a[i] = mul(a[i], inv); 96 | polyln(a + m, c, deg - m, n - m * k); 97 | for(int i = 0; i < n - m * k; ++i) c[i] = mul(c[i], k); 98 | polyexp(c, b + m * k, n - m * k, n - m * k); 99 | for(int i = m * k; i < n; ++i) b[i] = mul(b[i], scale); 100 | } 101 | 102 | 103 | // used in polysqrt. 104 | ll shanks(ll a, ll b, ll m) { 105 | a %= m, b %= m; ll n = sqrt(m) + 1; 106 | unordered_map mp; 107 | ll an = 1, base = 1, ans = -1; 108 | for(int i = 0; i < n; i++) an = (an * a) % m; 109 | for(int i = 1; i <= n; i++) { 110 | base = (base * an) % m; 111 | if(!mp.count(base)) 112 | mp[base] = i; 113 | } base = b; 114 | for(int j = 0; j <= n; j++) { 115 | if(mp.count(base)) { 116 | ll ret = mp[base] * n - j; 117 | if(ans == -1 || (ret < m && ans > ret)) ans = ret; 118 | } base = (base * a) % m; 119 | } return ans; 120 | } 121 | 122 | 123 | // CAUTION: assumes a, b is clear. a[0] = 1. 124 | void polysqrt_monic(int *a, int *b, int deg, int n) { 125 | static int x[N], y[N]; 126 | b[0] = 1; 127 | int sz = 2; 128 | while(sz / 2 < n) { 129 | sz <<= 1; 130 | for(int i = 0; i < sz / 2; ++i) x[i] = i < deg ? a[i] : 0; 131 | polyinv(b, y, sz >> 1, sz >> 1); 132 | fft(x, sz), fft(y, sz); 133 | for(int i = 0; i < sz; ++i) x[i] = mul(x[i], y[i]); 134 | reverse(x + 1, x + sz); 135 | fft(x, sz); 136 | int inv_n = Pow(sz, mod - 2); 137 | for(int i = (sz >> 2); i < (sz >> 1); ++i) 138 | b[i] = mul((mod + 1) / 2, b[i] + mul(x[i], inv_n)); 139 | } 140 | } 141 | 142 | // CAUTION: assumes a, b is clear. 143 | bool polysqrt(int *a, int *b, int deg, int n) { 144 | static int x[N], y[N], z[N]; 145 | memset(b, 0, n << 2); 146 | 147 | int m = 0; 148 | while(m < deg && a[m] == 0) ++m; 149 | if(m == deg) return 1; // b = {0} 150 | if(m & 1) return 0; 151 | 152 | int lg = shanks(mul(g, g), a[m], mod), scale = Pow(a[m], mod - 2); 153 | if(lg == -1) return 0; 154 | for(int i = m; i < deg; ++i) a[i] = mul(a[i], scale); 155 | 156 | polysqrt_monic(a + m, b + m / 2, deg - m, n - m / 2); 157 | scale = Pow(g, lg); 158 | for(int i = m / 2; i < n; ++i) b[i] = mul(b[i], scale); 159 | return 1; 160 | } 161 | 162 | // Raising factorials. 163 | // (x+1)(x+2)...(x+N) 164 | 165 | int f[M], h[M], a[M], b[M]; 166 | int fact[M], inv[M]; 167 | 168 | void build(int n) { 169 | if(n == 1) return void(f[0] = f[1] = 1); 170 | if(n & 1) { 171 | build(n - 1); 172 | for(int i = n; i >= 1; i--) { 173 | f[i] = f[i - 1] + (ll) n * f[i] % mod; 174 | if(f[i] >= mod) f[i] -= mod; 175 | } f[0] = (ll) f[0] * n % mod; 176 | return; 177 | } 178 | n >>= 1; build(n); 179 | int t = n + n + 1, sz = 1; 180 | while(sz < t) sz <<= 1; 181 | prepare(sz); 182 | 183 | for(int i = 0; i <= n; i++) 184 | a[i] = (ll) f[n - i] * fact[n - i] % mod; 185 | for(int i = 0, p = 1; i <= n; i++) { 186 | b[i] = (ll) p * inv[i] % mod; 187 | p = (ll) p * n % mod; 188 | } 189 | for(int i = n + 1; i < sz; i++) a[i] = b[i] = 0; 190 | 191 | ntt(a, sz); ntt(b, sz); 192 | for(int i = 0; i < sz; i++) 193 | h[i] = (ll) a[i] * b[i] % mod; 194 | ntt(h, sz, 1); 195 | reverse(h, h + n + 1); 196 | 197 | for(int i = 0; i <= n; i++) 198 | h[i] = (ll) h[i] * inv[i] % mod; 199 | for(int i = n + 1; i < sz; i++) 200 | f[i] = h[i] = 0; 201 | 202 | ntt(h, sz); ntt(f, sz); 203 | for(int i = 0; i < sz; i++) 204 | f[i] = (ll) f[i] * h[i] % mod; 205 | ntt(f, sz, 1); 206 | } 207 | 208 | // q_i = P(x^i), for i in [0..m-1] 209 | void chirpz(int *p, int *q, int n, int m, int x) { 210 | static int a[N], b[N], c[N]; 211 | int t = n + m, s = max(n, m); 212 | int xinv = Pow(x, mod - 2); 213 | for (int i = 0; i < s; ++i) q[i] = Pow(xinv, (ll)i * (i - 1) / 2 % (mod - 1)); 214 | for (int i = 0; i < n; ++i) a[n - i - 1] = mul(p[i], q[i]); 215 | for (int i = n; i < t; ++i) a[i] = 0; 216 | for (int i = 0; i < t; ++i) b[i] = Pow(x, (ll)i * (i - 1) / 2 % (mod - 1)); 217 | mul(a, b, c, t, t); 218 | for (int i = 0; i < m; ++i) q[i] = mul(q[i], c[n + i - 1]); 219 | } 220 | 221 | // c[k] = sum a[i] * b[i + k] 222 | void dot(int *a, int *b, int *c, int n, int m) { 223 | for(int i = 0; i < n; ++i) c[i] = a[n - 1 - i]; 224 | mul(c, b, c, n, m); 225 | for(int i = 0; i < m; ++i) c[i] = c[n - 1 + i]; 226 | } 227 | -------------------------------------------------------------------------------- /Fast Fourier Transform.cpp: -------------------------------------------------------------------------------- 1 | #pragma GCC optimize("Ofast,unroll-loops,no-stack-protector") 2 | #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") 3 | 4 | typedef long double ld; 5 | ld PI = acos(-1); 6 | 7 | struct base { 8 | ld a, b; 9 | base(ld _a = 0.0, ld _b = 0.0) : a(_a), b(_b) {} 10 | const base operator + (const base &c) const 11 | { return base(a + c.a, b + c.b); } 12 | const base operator - (const base &c) const 13 | { return base(a - c.a, b - c.b); } 14 | const base operator * (const base &c) const 15 | { return base(a * c.a - b * c.b, a * c.b + b * c.a); } 16 | const base conj() const { return base(a, -b); } 17 | }; 18 | 19 | vector rev; 20 | vector w; 21 | 22 | void prepare(int n) { // n is power of 2 23 | int sz = __builtin_ctz(n); 24 | if(rev.size() != n) { 25 | rev.assign(n, 0); 26 | for(int i = 0; i < n; ++i) { 27 | rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (sz - 1)); 28 | } 29 | } 30 | 31 | if(w.size() >= n) return; 32 | if(w.empty()) w = {{0, 0}, {1, 0}}; 33 | 34 | sz = __builtin_ctz(w.size()); 35 | w.resize(n); 36 | 37 | // w[n + i] = w_{2n}^i, n power of 2, i < n 38 | while((1 << sz) < n) { 39 | double ang = 2 * PI / (1 << (sz + 1)); 40 | base wn(cos(ang), sin(ang)); 41 | // For NTT: wn = Pow(g, (mod - 1) >> (sz + 1)); 42 | for(int i = 1 << (sz - 1); i < (1 << sz); ++i) { 43 | w[i << 1] = w[i]; 44 | w[i << 1 | 1] = w[i] * wn; 45 | } ++sz; 46 | } 47 | } 48 | 49 | void fft(base *p, int n) { 50 | prepare(n); 51 | for(int i = 1; i < n - 1; ++i) 52 | if(i < rev[i]) swap(p[i], p[rev[i]]); 53 | for(int h = 1; h < n; h <<= 1) { 54 | for(int s = 0; s < n; s += h << 1) { 55 | for(int i = 0; i < h; ++i) { 56 | base &u = p[s + i], &v = p[s + h + i], 57 | t = v * w[h + i]; 58 | v = u - t; u = u + t; 59 | } 60 | } 61 | } 62 | } 63 | 64 | void mul(int *a, int *b, int *c, int n, int m) { 65 | static base f[N]; 66 | 67 | int sz = n + m - 1; 68 | while(sz & (sz - 1)) sz = (sz | (sz - 1)) + 1; 69 | for(int i = 0; i < sz; ++i) 70 | f[i] = base(i < n ? a[i] : 0, i < m ? b[i] : 0); 71 | fft(f, sz); 72 | for(int i = 0; i <= (sz >> 1); ++i) { 73 | int j = (sz - i) & (sz - 1); 74 | base x = (f[i] * f[i] - (f[j] * f[j]).conj()) * base(0, -0.25); 75 | f[j] = x; f[i] = x.conj(); 76 | } 77 | fft(f, sz); 78 | for(int i = 0; i < sz; ++i) c[i] = f[i].a / sz + 0.5; 79 | } 80 | 81 | inline void mul_mod(int *a, int *b, int *c, int n, int m) { 82 | static base f[N], g[N], u[N], v[N]; 83 | int sz = 1; 84 | while(sz < n + m - 1) sz <<= 1; 85 | for(int i = 0; i < n; i++) f[i] = base(a[i] & 32767, a[i] >> 15); 86 | for(int i = 0; i < m; i++) g[i] = base(b[i] & 32767, b[i] >> 15); 87 | for(int i = n; i < sz; i++) f[i] = base(0, 0); 88 | for(int i = m; i < sz; i++) g[i] = base(0, 0); 89 | 90 | fft(f, sz), fft(g, sz); 91 | for(int i = 0; i < sz; ++i) { 92 | int j = (sz - i) & (sz - 1); 93 | static base da, db, dc, dd; 94 | da = (f[i] + f[j].conj()) * base(0.5, 0); 95 | db = (f[i] - f[j].conj()) * base(0, -0.5); 96 | dc = (g[i] + g[j].conj()) * base(0.5, 0); 97 | dd = (g[i] - g[j].conj()) * base(0, -0.5); 98 | u[j] = da * dc + da * dd * base(0, 1); 99 | v[j] = db * dc + db * dd * base(0, 1); 100 | } 101 | fft(u, sz), fft(v, sz); 102 | for(int i = 0; i < sz; ++i) { 103 | int da = (ll)(u[i].a / sz + 0.5) % mod; 104 | int db = (ll)(u[i].b / sz + 0.5) % mod; 105 | int dc = (ll)(v[i].a / sz + 0.5) % mod; 106 | int dd = (ll)(v[i].b / sz + 0.5) % mod; 107 | c[i] = (da + ((ll)(db + dc) << 15) + ((ll)dd << 30)) % mod; 108 | } 109 | } -------------------------------------------------------------------------------- /Fast Input.cpp: -------------------------------------------------------------------------------- 1 | inline char read() { 2 | static const int IN_LEN = 1000000; 3 | static char buf[IN_LEN], *s, *t; 4 | return (s == t ? t = (s = buf) + fread(buf, 1, IN_LEN, stdin), (s == t ? -1 : *s++) : *s++); 5 | } 6 | template inline void read(T &x) { 7 | static bool iosig; 8 | static char c; 9 | for(iosig = false, c = read(); !isdigit(c); c = read()) { 10 | if(c == '-') iosig = true; 11 | if(c == -1) return; 12 | } 13 | for(x = 0; isdigit(c); c = read()) 14 | x = ((x + (x << 2)) << 1) + (c ^ '0'); 15 | if(iosig) x = -x; 16 | } 17 | const int OUT_LEN = 10000000; 18 | char obuf[OUT_LEN], *ooh = obuf; 19 | inline void print(char c) { 20 | if(ooh == obuf + OUT_LEN) fwrite(obuf, 1, OUT_LEN, stdout), ooh = obuf; 21 | *ooh++ = c; 22 | } 23 | template inline void print(T x) { 24 | static int buf[30], cnt; 25 | if(x == 0) print('0'); 26 | else { 27 | if(x < 0) print('-'), x = -x; 28 | for(cnt = 0; x; x /= 10) buf[++cnt] = x % 10 + 48; 29 | while(cnt) print((char)buf[cnt--]); 30 | } 31 | } 32 | inline void flush() { fwrite(obuf, 1, ooh - obuf, stdout); } -------------------------------------------------------------------------------- /Fast Walsh Hadamard Trandform.cpp: -------------------------------------------------------------------------------- 1 | /**************************** 2 | Hadamard Matrix - 3 | 1. For XOR-Convolution - 4 | H = H_inverse = {{1, 1}, {1, -1}} 5 | 6 | 2.For AND-Convolution - 7 | H = {{0, 1}, {1, 1}} 8 | H_inverse = {{-1, 1}, {1, 0}} 9 | 10 | 3. For OR-Convolution - 11 | H = {{1, 1}, {1, 0}} 12 | H_inverse = {{0, 1}, {1, -1}} 13 | ***************************/ 14 | const int mod = 1e9 + 7; 15 | void fwht(int *p, int n) { 16 | for(int len = 1; 2 * len <= n; len <<= 1) { 17 | for(int i = 0; i < n; i += 2 * len) { 18 | for(int j = 0; j < len; j++) { 19 | int a = p[i + j]; 20 | int b = p[i + j + len]; 21 | p[i + j] = (a + b) % mod; 22 | p[i + j + len] = (mod + a - b) % mod; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Gaussian Elimination.cpp: -------------------------------------------------------------------------------- 1 | /********************** 2 | * a[n][m + 1], n equations, m variables. 3 | * returns rank of matrix 4 | * a[][] is changed to reduced row echelon form 5 | * no solution if a row is like [0, 0, ..., | some non-zero number] 6 | ***********************/ 7 | typedef long double ld; 8 | const ld eps = 1e-8; 9 | int gauss(vector > &a) { 10 | int n = a.size(), m = a[0].size(), r = 0; 11 | for(int c = 0; c < m && r < n; c++) { 12 | int idx = r; 13 | for(int i = r + 1; i < n; i++) 14 | if(fabsl(a[i][c]) > fabsl(a[idx][c])) idx = i; 15 | if(fabsl(a[idx][c]) < eps) continue; 16 | a[r].swap(a[idx]); 17 | 18 | ld t = a[r][c]; 19 | for(int i = c; i < m; i++) a[r][i] /= t; 20 | for(int i = 0; i < n; i++) if(i != r) { 21 | ld t = a[i][c]; 22 | for(int j = c; j < m; j++) 23 | a[i][j] -= a[r][j] * t; 24 | } 25 | r++; 26 | } return r; 27 | // Writing some checkers may be needed. 28 | } 29 | 30 | 31 | -------------------------------------------------------------------------------- /HLD.cpp: -------------------------------------------------------------------------------- 1 | /*////////////////////////////////////////// 2 | p[u] = parent of u; 3 | head[u] = chain head of u in its chain 4 | pos[u] = position of u in segment tree. 5 | //////////////////////////////////////////*/ 6 | 7 | vector adj[maxn]; 8 | int n, p[maxn], heavy[maxn], dep[maxn], head[maxn], pos[maxn]; 9 | int dfs(int u, int par) { 10 | if(par + 1) dep[u] = dep[par] + 1; 11 | int size = 1, Max = 0; p[u] = par; 12 | for(int v : adj[u]) if(v - par) { 13 | int sub = dfs(v, u); 14 | if(sub > Max) Max = sub, heavy[u] = v; 15 | size += sub; 16 | } return size; 17 | } 18 | template 19 | void processPath(int u, int v, BinaryOperation op) { 20 | for(; head[u] != head[v]; u = p[head[u]]) { 21 | if(dep[head[v]] > dep[head[u]]) swap(u, v); 22 | op(pos[head[u]], pos[u]); 23 | } if(dep[v] > dep[u]) swap(u, v); 24 | op(pos[v], pos[u]); 25 | } 26 | int updatePath(int u, int v, int val) { 27 | processPath(u, v, [&val](int l, int r) { tree.update(l, r, v); }); 28 | } 29 | int queryPath(int u, int v) { 30 | int ret = 0; 31 | processPath(u, v, [&ret](int l, int r) { ret += tree.query(l, r); }); 32 | return ret; 33 | } 34 | void init() { 35 | fill_n(heavy, n, -1); dfs(0, -1); 36 | for(int i = 0, idx = 0; i < n; i++) { 37 | if(p[i] == -1 || heavy[p[i]] != i) { 38 | for(int j = i; j + 1; j = heavy[j]) { 39 | head[j] = i; 40 | pos[j] = idx++; 41 | } 42 | } 43 | } tree.init(n); 44 | for(int i = 0; i < n; i++) 45 | tree.set(pos[i], value[i]); 46 | } 47 | -------------------------------------------------------------------------------- /Hash.cpp: -------------------------------------------------------------------------------- 1 | struct Hash { 2 | struct base { 3 | string s; int b, mod; 4 | vector hash, p; 5 | void init(string &_s, int _b, int _mod) { // b > 26, prime. 6 | s = _s; b = _b, mod = _mod; 7 | hash.resize(s.size()); 8 | p.resize(s.size()); 9 | hash[0] = s[0] - 'A' + 1; p[0] = 1; 10 | for(int i = 1; i < s.size(); ++i) { 11 | hash[i] = (ll) hash[i - 1] * b % mod; 12 | hash[i] += s[i] - 'A' + 1; 13 | if(hash[i] >= mod) hash[i] -= mod; 14 | p[i] = (ll) p[i - 1] * b % mod; 15 | } 16 | } 17 | int get(int l, int r) { 18 | int ret = hash[r]; 19 | if(l) ret -= (ll) hash[l - 1] * p[r - l + 1] % mod; 20 | if(ret < 0) ret += mod; 21 | return ret; 22 | } 23 | } h[2]; 24 | void init(string &s) { 25 | h[0].init(s, 29, 1e9+7); 26 | h[1].init(s, 31, 1e9+9); 27 | } 28 | pair get(int l, int r) { 29 | return { h[0].get(l, r), h[1].get(l, r) }; 30 | } 31 | } H; -------------------------------------------------------------------------------- /Hopcroft Karp.cpp: -------------------------------------------------------------------------------- 1 | const int N = 1e5 + 5; 2 | const int inf = 1e9; 3 | vector adj[N]; 4 | int match[N], dist[N], n, m, p; 5 | 6 | bool bfs() { 7 | queue q; 8 | for (int i = 1; i <= n; ++i) { 9 | if (!match[i]) 10 | dist[i] = 0, q.push(i); 11 | else 12 | dist[i] = inf; 13 | } 14 | dist[0] = inf; 15 | while(!q.empty()) { 16 | int u = q.front(); 17 | q.pop(); 18 | if(!u) continue; 19 | for(int v : adj[u]) { 20 | if(dist[match[v]] == inf) { 21 | dist[match[v]] = dist[u] + 1; 22 | q.push(match[v]); 23 | } 24 | } 25 | } 26 | return dist[0] != inf; 27 | } 28 | 29 | bool dfs(int u) { 30 | if(!u) return 1; 31 | for(int v : adj[u]) { 32 | if(dist[match[v]] == dist[u] + 1) { 33 | if(dfs(match[v])) { 34 | match[u] = v, match[v] = u; 35 | return 1; 36 | } 37 | } 38 | } 39 | dist[u] = inf; 40 | return 0; 41 | } 42 | 43 | int max_matching() { 44 | int ret = 0; 45 | while (bfs()) { 46 | for (int i = 1; i <= n; ++i) 47 | if (!match[i] && dfs(i)) ++ret; 48 | } 49 | return ret; 50 | } 51 | -------------------------------------------------------------------------------- /INF Knight.cpp: -------------------------------------------------------------------------------- 1 | //O(1) 2 | 3 | struct point { 4 | ll x, y; 5 | bool operator < (const point &p) const { 6 | return x == p.x ? y < p.y : x < p.x; 7 | } 8 | }; 9 | ll kdist(point p, point q) { 10 | ll dx = abs(p.x - q.x); 11 | ll dy = abs(p.y - q.y); 12 | ll cnt = max({(dx+1)/2, 13 | (dy+1)/2, 14 | (dx+dy+2)/3} 15 | ); 16 | while((cnt%2) != (dx+dy)%2) cnt++; 17 | if(dx == 1 && !dy) return 3; 18 | if(dy == 1 && !dx) return 3; 19 | if(dx == dy && dx == 2) return 4; 20 | return cnt; 21 | } 22 | 23 | // O(log Max) 24 | 25 | const int KN = 101; 26 | i64 dk[KN][KN]; 27 | int dx[] = {-1, -1, 1, 1, -2, -2, 2, 2}; 28 | int dy[] = {-2, 2, -2, 2, -1, 1, -1, 1}; 29 |   30 | void precalc() { 31 |     int x, y, x1, y1, i; 32 |     queue< int > Q; 33 |     memset(dk, 0x3f, sizeof dk); 34 |     x = y = (KN >> 1); 35 |     dk[x][y] = 0; 36 |     Q.push(x); Q.push(y); 37 |     while(!Q.empty()) { 38 |         x = Q.front(); Q.pop(); 39 |         y = Q.front(); Q.pop(); 40 |         for(i = 0; i < 8; i++) { 41 |             x1 = x + dx[i], y1 = y + dy[i]; 42 |             if(0 <= x1 && x1 < KN && 0 <= y1 && y1 < KN) { 43 |                 if(dk[x1][y1] > dk[x][y] + 1) { 44 |                     dk[x1][y1] = dk[x][y] + 1; 45 |                     Q.push(x1); Q.push(y1); 46 |                 } 47 |             } 48 |         } 49 |     } 50 | } 51 | 52 | // Returns knight distance between (0,0) -> (x,y) 53 | i64 knight(i64 x, i64 y) { 54 |     i64 step, res = 0; 55 |     if(x < y) swap(x, y); 56 |     while((x<<1) > KN) { 57 |         step = x / 2 / 2; res += step; 58 |         x -= step * 2; y -= step; 59 |         if(y < 0) y = ((y % 2) + 2) % 2; 60 |         if(x < y) swap(x, y); 61 |     } 62 |     res += dk[x+(KN>>1)][y+(KN>>1)]; 63 |     return res; 64 | } -------------------------------------------------------------------------------- /KMP.cpp: -------------------------------------------------------------------------------- 1 | 2 | const int maxn = 1e5 + 10; 3 | string s, t; 4 | int pi[maxn]; 5 | 6 | void prefixFn() { 7 | int now = pi[0] = -1; 8 | for(int i = 1; i < s.size(); i++) { 9 | while(now != -1 && s[now + 1] != s[i]) now = pi[now]; 10 | if(s[now + 1] == s[i]) pi[i] = ++now; 11 | else pi[i] = now = -1; 12 | } 13 | } 14 | 15 | int kmp() { 16 | prefixFn(); 17 | int cnt = 0, now = -1; 18 | for(int i = 0; i < t.size(); i++) { 19 | while(now != -1 && s[now + 1] != t[i]) now = pi[now]; 20 | if(s[now + 1] == t[i]) ++now; 21 | else now = -1; 22 | if(now == s.size() - 1) { now = pi[now]; cnt++; } 23 | } return cnt; 24 | } -------------------------------------------------------------------------------- /LCA.cpp: -------------------------------------------------------------------------------- 1 | //BinaryLifting 2 | //LCA Routine 3 | //Dont forget to memset p[][] array with -1 4 | const int N = 1e5+10; 5 | const int MAXLOG = log2(N)+5; 6 | vector adj[N]; 7 | int p[N][MAXLOG], n, lg, L[N], timer = 0; 8 | void dfs(int u, int par) { 9 | p[u][0] = par; 10 | if(par + 1) 11 | L[u] = L[par] + 1; 12 | for(int i = 1; i <= lg; i++) 13 | if(p[u][i-1] + 1) 14 | p[u][i] = p[p[u][i-1]][i-1]; 15 | for(int v : adj[u]) if(par - v) dfs(v,u); 16 | } 17 | int lca(int u, int v) { 18 | if(L[u] < L[v]) swap(u,v); 19 | for(int i = lg; i >= 0; i--) 20 | if(p[u][i] + 1 && L[p[u][i]] >= L[v]) 21 | u = p[u][i]; 22 | if(v == u) return u; 23 | for(int i = lg; i >= 0; i--) 24 | if(p[u][i] - p[v][i]) 25 | v = p[v][i], u = p[u][i]; 26 | return p[v][0]; 27 | } -------------------------------------------------------------------------------- /Lazy Array.cpp: -------------------------------------------------------------------------------- 1 | template struct lazyarray { 2 | T a[N]; 3 | int vis[N], iter; 4 | lazyarray () { 5 | memset(vis, 0, sizeof vis); 6 | iter = 1; 7 | } 8 | void clear() { ++iter; } 9 | T &operator [] (int i) { 10 | if(vis[i] == iter) { 11 | return a[i]; 12 | } else { 13 | vis[i] = iter; 14 | return a[i] = 0; 15 | } 16 | } 17 | }; -------------------------------------------------------------------------------- /LongestPathInDAG.cpp: -------------------------------------------------------------------------------- 1 | const int maxn = 1100; 2 | vector adj[maxn]; 3 | int dp[maxn], vis[maxn], n; 4 | int dfs(int u) { 5 | vis[u] = dp[u] = 1; 6 | for(int v : adj[u]) { 7 | if(!vis[v]) dfs(v); 8 | dp[u] = max(dp[u], dp[v] + 1); 9 | } return dp[u]; 10 | } 11 | int longestpath() { 12 | int ans = 0; 13 | for(int i = 1; i <= n; i++) 14 | if(!vis[i]) ans = max(ans, dfs(i)); 15 | return ans; 16 | } 17 | 18 | -------------------------------------------------------------------------------- /MO'a algo with Updates.cpp: -------------------------------------------------------------------------------- 1 | 2 | const int maxn = 1e5 + 10; 3 | int n, m, a[maxn], prv[maxn], ans[maxn], block; 4 | 5 | struct query { 6 | int l, r, id, t, blcl, blcr; 7 | query(int _a, int _b, int _c, int _d) { 8 | l = _a, r = _b; 9 | id = _c, t = _d; 10 | blcl = l / block; 11 | blcr = r / block; 12 | } 13 | bool operator < (const query &p) const { 14 | if(blcl != p.blcl) return l < p.l; 15 | if(blcr != p.blcr) return r < p.r; 16 | return t < p.t; 17 | } 18 | }; vector q; 19 | 20 | struct update { 21 | int pos, pre, now; 22 | }; vector u; 23 | 24 | 25 | struct lol { 26 | void add(int x) {} 27 | void remove(int x) {} 28 | int get() {} 29 | } ds; 30 | 31 | int l, r, t; 32 | int cnt[maxn * 2]; 33 | 34 | void add(int x) { // Add a[x] to ds 35 | } 36 | void remove(int x) { // Remove a[x] from ds 37 | } 38 | void apply(int i, int x) { // Change a[i] to x 39 | if(l <= i && i <= r) { 40 | remove(i); 41 | a[i] = x; 42 | add(i); 43 | } else a[i] = x; 44 | } 45 | 46 | int main(int argc, char const *argv[]) { 47 | read(n); read(m); 48 | block = pow(n, 0.6667); 49 | 50 | for(int i = 0; i < n; ++i) 51 | read(a[i]), last[i] = a[i]; 52 | 53 | u.push_back({-1, -1, -1}); 54 | 55 | for(int i = 0; i < m; ++i) { 56 | int t, l, r; 57 | read(t); read(l); read(r); 58 | if(t == 1) { --r; 59 | q.push_back(query(l, r, q.size(), u.size() - 1)); 60 | } else { 61 | u.push_back({l, prv[l], r}); 62 | prv[l] = r; 63 | } 64 | } 65 | 66 | sort(q.begin(), q.end()); 67 | l = 0, r = -1, t = 0; 68 | 69 | for(int i = 0; i < q.size(); i++) { 70 | while(t < q[i].t) ++t, apply(u[t].pos, u[t].now); 71 | while(t > q[i].t) apply(u[t].pos, u[t].pre), --t; 72 | 73 | while(r < q[i].r) add(++r); 74 | while(l > q[i].l) add(--l); 75 | while(r > q[i].r) remove(r--); 76 | while(l < q[i].l) remove(l++); 77 | 78 | ans[q[i].id] = ds.get(); 79 | } 80 | 81 | for(int i = 0; i < q.size(); i++) 82 | printf("%d\n", ans[i]); 83 | } -------------------------------------------------------------------------------- /MO's Algo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define left lol 5 | typedef long long ll; 6 | typedef pair ii; 7 | 8 | const int N = 1e5 + 10; 9 | 10 | int n, Q, a[N], blc[N], ans[N], c; 11 | 12 | struct query { 13 | int l, r, id; 14 | query(int l = 0, int r = 0, int id = 0): 15 | l(l), r(r), id(id) {} 16 | bool operator < (const query &q) const { 17 | return blc[l] == blc[q.l] ? ((r < q.r) ^ (blc[l] & 1)) : l < q.l; 18 | } 19 | } q[N]; 20 | 21 | inline void add(int x) { } 22 | inline void remove(int x) { } 23 | 24 | int main(int argc, char const *argv[]) { 25 | scanf("%d", &n); 26 | for(int i = 1; i <= n; ++i) { 27 | scanf("%d", &a[i]); 28 | } 29 | 30 | scanf("%d", &Q); 31 | for(int i = 1; i <= Q; i++) { 32 | scanf("%d %d", &q[i].l, &q[i].r); 33 | q[i].id = i; 34 | } 35 | 36 | int sz = n / sqrt(Q); 37 | for(int i = 1; i <= n; ++i) blc[i] = i / sz; 38 | sort(q + 1, q + Q + 1); 39 | 40 | int l = 1, r = 0; 41 | for(int i = 1; i <= Q; ++i) { 42 | while(r < q[i].r) add(a[++r]); 43 | while(l > q[i].l) add(a[--l]); 44 | while(r > q[i].r) remove(a[r--]); 45 | while(l < q[i].l) remove(a[l++]); 46 | ans[q[i].id] = c; 47 | } 48 | 49 | for(int i = 1; i <= Q; ++i) { 50 | printf("%d\n", ans[i]); 51 | } 52 | } -------------------------------------------------------------------------------- /Manacher.cpp: -------------------------------------------------------------------------------- 1 | // l[2 * i] = len of palindrome centered at s[i] 2 | // l[2*i+1] = len of palindrome centered at s[i], s[i+1] 3 | vector manacher(string &s) { 4 | int n = s.size(); vector l(2 * n); 5 | for (int i = 0, j = 0, k; i < n * 2; i += k, j = max(j - k, 0)) { 6 | while (i >= j && i + j + 1 < n * 2 && s[(i - j) / 2] == s[(i + j + 1) / 2]) ++j; 7 | l[i] = j; 8 | for (k = 1; i >= k && j >= k && l[i - k] != j - k; ++k) 9 | l[i + k] = min(l[i - k], j - k); 10 | } return l; 11 | } -------------------------------------------------------------------------------- /Manhattan MST.cpp: -------------------------------------------------------------------------------- 1 | struct point { 2 | int x, y, index; 3 | bool operator<(const point &p) const 4 | { return x == p.x ? y < p.y : x < p.x; } 5 | } p[maxn]; 6 | struct node { int value, p; } T[maxn]; 7 | 8 | int query(int x) { 9 | int r = maxint, p = -1; 10 | for(; x <= n; x += (x & -x)) 11 | if(T[x].value < r) r = T[x].value, p = T[x].p; 12 | return p; 13 | } 14 | void update(int x, int w, int p) { 15 | for(; x > 0; x -= (x & -x)) if (T[x].value > w) T[x].value = w, T[x].p = p; 16 | } 17 | void addEdge(int u, int v, int c) { /* -_- */ } 18 | int kruskal() { /* -_- */ } 19 | int manhattan() { 20 | for(int i = 1; i <= n; ++i) p[i].index = i; 21 | for(int dir = 1; dir <= 4; ++dir) { 22 | if(dir == 2 || dir == 4) { 23 | for(int i = 1; i <= n; ++i) swap(p[i].x, p[i].y); 24 | } else if(dir == 3) { 25 | for(int i = 1; i <= n; ++i) p[i].x = -p[i].x; 26 | } sort(p + 1, p + 1 + n); 27 | vector v; static int a[maxn]; 28 | for(int i = 1; i <= n; ++i) a[i] = p[i].y - p[i].x, v.push_back(a[i]); 29 | sort(v.begin(), v.end()); 30 | v.erase(unique(v.begin(), v.end()), v.end()); 31 | for(int i = 1; i <= n; ++i) a[i] = lower_bound(v.begin(), v.end(), a[i]) - v.begin() + 1; 32 | for(int i = 1; i <= n; ++i) T[i].value = maxint, T[i].p = -1; 33 | for(int i = n; i >= 1; --i) { 34 | int pos = query(a[i]); 35 | if(pos != -1) addEdge(p[i].index, p[pos].index, dist(p[i], p[pos])); 36 | update(a[i], p[i].x + p[i].y, i); 37 | } 38 | } return kruskal(); 39 | } 40 | -------------------------------------------------------------------------------- /MatrixExpo.cpp: -------------------------------------------------------------------------------- 1 | 2 | const int mod = 1e9 + 7; 3 | struct Mat { 4 | int a[10][10], d; 5 | Mat(int _d = 0) { 6 | d = _d; 7 | memset(a, 0, sizeof a); 8 | } 9 | void setIdentity() { 10 | for(int i = 0; i < d; ++i) 11 | for(int j = 0; j < d; ++j) 12 | a[i][j] = (i == j); 13 | } 14 | Mat operator *(const Mat &p) const { 15 | Mat ret(d); int i, j, k; 16 | ll y = (ll)mod * mod, x; 17 | for(i = 0; i < d; ++i) { 18 | for(j = 0; j < d; ++j) { 19 | for(k = x = 0; k < d; ++k) { 20 | x += (ll)a[i][k] * p.a[k][j]; 21 | if(x >= y) x -= y; 22 | } ret.a[i][j] = x % mod; 23 | } 24 | } return ret; 25 | } 26 | Mat pow(ll n) { 27 | Mat ret(d); ret.setIdentity(); 28 | Mat b = *this; 29 | for(; n; n >>= 1, b = b * b) 30 | if(n & 1) ret = ret * b; 31 | return ret; 32 | } 33 | }; -------------------------------------------------------------------------------- /Max BPM.cpp: -------------------------------------------------------------------------------- 1 | // Complexity $O(V * min(BPM^2, E))$. 2 | // Left nodes - 0, 1, ..., n - 1. Right rest. 3 | vector adj[N]; 4 | int vis[N], match[N], iter; 5 | int dfs(int u) { 6 | if(vis[u] == iter) return 0; 7 | vis[u] = iter; 8 | for(int v : adj[u]) { 9 | if(match[v] < 0 || dfs(match[v])) { 10 | match[u] = v, match[v] = u; 11 | return 1; 12 | } 13 | } return 0; 14 | } 15 | int kuhn() { 16 | memset(match, -1, sizeof match); 17 | int ans = 0; 18 | for(int i = 0; i < n; i++) { 19 | ++iter; ans += dfs(i); 20 | } return ans; 21 | } -------------------------------------------------------------------------------- /Max XOR Subset.cpp: -------------------------------------------------------------------------------- 1 | // Gaussian Elimination Online 2 | struct maxxor { 3 | int best[32], msb; 4 | maxxor() { memset(best, -1, sizeof best); } 5 | void add(int x) { 6 | while(x > 0) { 7 | msb = 31 - __builtin_clz(x); // clzll for ll 8 | if(best[msb] == -1) { 9 | best[msb] = x; break; 10 | } else x = x ^ best[msb]; 11 | } 12 | } 13 | int get(int ret = 0) { 14 | for(int i = 31; i >= 0; i--) { 15 | if(best[i] != -1) 16 | ret = max(ret, ret ^ best[i]); 17 | } return ret; 18 | } 19 | } ds; 20 | 21 | // Gaussian Elimination Offline 22 | 23 | int a[maxn], n; 24 | int maxxor() { 25 | int r = 0, ret = 0; 26 | for(int c = 31; c >= 0; c--) { 27 | int idx = -1; 28 | for(int i = r; i < n && idx < 0; i++) 29 | if(a[i] >> c & 1) idx = i; 30 | if(idx == -1) continue; 31 | swap(a[r], a[idx]); 32 | for(int i = 0; i < n; i++) if(i != r) 33 | if(a[i] >> c & 1) a[i] ^= a[r]; 34 | r++; 35 | } 36 | for(int i = 0; i < n; i++) ret = max(ret, ret ^ a[i]); 37 | } -------------------------------------------------------------------------------- /Mex using Trie O(log Max).cpp: -------------------------------------------------------------------------------- 1 | 2 | struct node{ 3 | node *ch[2]; int cnt; 4 | node() {ch[0] = ch[1] = NULL, cnt = 0; } 5 | } *root; 6 | 7 | void insert(int x) { 8 | node *curr = root; 9 | for(int i = 20; i >= 0; i--) { 10 | int bit = (x >> i) & 1; 11 | if(curr -> ch[bit] == NULL) 12 | curr -> ch[bit] = new node(); 13 | curr -> ch[bit] -> cnt++; 14 | curr = curr -> ch[bit]; 15 | } 16 | } 17 | int mex() { 18 | node *curr = root; int ret = 0; 19 | for(int i = 20; i >= 0; i--) { 20 | if(curr == NULL || curr -> ch[0] == NULL) return ret; 21 | if(curr -> ch[0] -> cnt >= (1 << i)) { 22 | curr = curr -> ch[1]; 23 | ret |= (1 << i); 24 | } else curr = curr -> ch[0]; 25 | } return ret; 26 | } -------------------------------------------------------------------------------- /Millar-Rabin Primality Test.cpp: -------------------------------------------------------------------------------- 1 | ll mul64(ll a, ll b, ll m) { // 64-bit long long multiplication 2 | a %= m, b %= m; 3 | ll ret = 0; 4 | for(; b; b >>= 1) { 5 | if(b & 1) ret = (ret + a) % m; 6 | a = (a + a) % m; 7 | } return ret; 8 | } 9 | ll Pow(int a, ll p, ll mod) { /* -_- */ } 10 | bool miller_rabin(ll n, ll b) { 11 | ll m = n - 1, cnt = 0; 12 | while (m % 2 == 0) m >>= 1, ++cnt; 13 | ll ret = Pow(b, m, n); 14 | if (ret == 1 || ret == n - 1) return true; 15 | while (cnt > 0) { 16 | ret = mul64(ret, ret, n); 17 | if (ret == n - 1) return true; 18 | --cnt; 19 | } return false; 20 | } 21 | bool ptest(ll n) { // miller-rabin primality test 22 | if(n < 2) return false; 23 | if(n < 4) return true; 24 | const int BASIC[12] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37 }; 25 | for(int i = 0; i < 12 && BASIC[i] < n; ++i) 26 | if(!miller_rabin(n, BASIC[i])) return false; 27 | return true; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /MinCostMaxFlow.cpp: -------------------------------------------------------------------------------- 1 | template 2 | class MCMF { 3 | public: 4 | struct Edge { 5 | int u, v; 6 | T cap, cost, flow; 7 | Edge(int u, int v, T cap, T cost, T flow) 8 | : u(u), v(v), cap(cap), cost(cost), flow(flow) {} 9 | }; 10 | const T inf = numeric_limits::max(); 11 | vector adj[N]; 12 | vector E; 13 | bitset vis; 14 | queue q; 15 | int n, s, t, ptr[N]; 16 | T dist[N], total_cost; 17 | 18 | inline void init(int _n, int _s, int _t) { 19 | n = _n, s = _s, t = _t; 20 | total_cost = 0, E.clear(); 21 | for (int i = 0; i < n; ++i) adj[i].clear(); 22 | } 23 | inline void addEdge(int u, int v, T cap, T cost, bool directed = true) { 24 | adj[u].push_back(E.size()); 25 | E.emplace_back(u, v, cap, cost, 0); 26 | adj[v].push_back(E.size()); 27 | E.emplace_back(v, u, 0, -cost, 0); 28 | if (!directed) addEdge(v, u, cap, cost, true); 29 | } 30 | inline bool spfa() { 31 | fill(dist, dist + n, inf); 32 | q.push(s), dist[s] = 0, vis[s] = 1; 33 | while (!q.empty()) { 34 | int u = q.front(); 35 | q.pop(), vis[u] = 0; 36 | for (int i : adj[u]) { 37 | if (E[i].flow < E[i].cap && dist[E[i].v] > dist[u] + E[i].cost) { 38 | dist[E[i].v] = dist[u] + E[i].cost; 39 | if (!vis[E[i].v]) q.push(E[i].v), vis[E[i].v] = 1; 40 | } 41 | } 42 | } 43 | return dist[t] != inf; 44 | } 45 | T dfs(int u, T pf) { 46 | if (u == t || !pf) return pf; 47 | vis[u] = 1; 48 | while (ptr[u] < adj[u].size()) { 49 | int i = adj[u][ptr[u]]; 50 | if (!vis[E[i].v] && dist[E[i].v] == dist[u] + E[i].cost) { 51 | if (T x = dfs(E[i].v, min(pf, E[i].cap - E[i].flow))) { 52 | total_cost += x * E[i].cost; 53 | E[i].flow += x, E[i ^ 1].flow -= x; 54 | vis[u] = 0; 55 | return x; 56 | } 57 | } 58 | ++ptr[u]; 59 | } 60 | return vis[u] = 0; 61 | } 62 | pair flow() { 63 | T mf = 0; 64 | while (spfa()) { 65 | memset(ptr, 0, n * sizeof(ptr[0])); 66 | while (T f = dfs(s, inf)) mf += f; 67 | } 68 | return {mf, total_cost}; 69 | } 70 | }; 71 | -------------------------------------------------------------------------------- /Minimum Expression.cpp: -------------------------------------------------------------------------------- 1 | int minimumExpression(string s) { s = s + s; 2 | int i = 0, j = 1, k = 0, len = s.size(); 3 | while(i + k < len && j + k < len) { 4 | if(s[i + k] == s[j + k]) k++; 5 | else if(s[i + k] < s[j + k]) { j = max(j + k + 1, i + 1); k = 0; } 6 | else { i = max(i + k + 1, j + 1); k = 0; } 7 | } return min(i, j); 8 | } 9 | -------------------------------------------------------------------------------- /Misc Geometry.cpp: -------------------------------------------------------------------------------- 1 | ///usr/bin/g++ -O2 $0 -o ${0%.cpp} && echo "----------" && ./${0%.cpp}; exit; 2 | #include 3 | using namespace std; 4 | 5 | typedef double T; 6 | struct pt { 7 | T x,y; 8 | pt(T x=0, T y=0): x(x), y(y) {} 9 | pt operator+(pt p) { return {x+p.x, y+p.y}; } 10 | pt operator-(pt p) { return {x-p.x, y-p.y}; } 11 | pt operator*(T d) { return {x*d, y*d}; } 12 | pt operator/(T d) { return {x/d, y/d}; } 13 | }; 14 | 15 | bool operator==(pt a,pt b){return a.x==b.x&&a.y==b.y;} 16 | bool operator!=(pt a, pt b) { return !(a == b); } 17 | 18 | ostream& operator<<(ostream& os, pt p) { 19 | return os << "("<< p.x << "," << p.y << ")"; 20 | } 21 | 22 | T sq(pt p) { return p.x*p.x + p.y*p.y; } 23 | double abs(pt p) { return sqrt(sq(p)); } 24 | 25 | T dot(pt v, pt w) { return v.x*w.x + v.y*w.y; } 26 | T cross(pt v, pt w) { return v.x*w.y - v.y*w.x; } 27 | 28 | template int sgn(T x) { 29 | return (T(0) < x) - (x < T(0)); 30 | } 31 | pt scale(pt c, double a, pt p) { return c + (p-c)*a; } 32 | 33 | pt rot(pt p, double a) { 34 | return {p.x*cos(a) - p.y*sin(a), 35 | p.x*sin(a) + p.y*cos(a)}; 36 | } 37 | 38 | pt perp(pt p) { return {-p.y, p.x}; } 39 | 40 | // transform r, ifp->fp, q->fq 41 | pt linearTransfo(pt p, pt q, pt r, pt fp, pt fq) { 42 | pt pq = q-p, num{cross(pq, fq-fp), dot(pq, fq-fp)}; 43 | return fp + pt{cross(r-p, num), dot(r-p, num)} / sq(pq); 44 | } 45 | 46 | bool isPerp(pt v, pt w) {return dot(v,w) == 0;} 47 | 48 | // angle between v and w, in [0, pi] 49 | double angle(pt v, pt w) { 50 | double cosTheta = dot(v,w) / abs(v) / abs(w); 51 | return acos(max(-1.0, min(1.0, cosTheta))); 52 | } 53 | 54 | // +ve ifc is left to a->b, -ve forright, else 0 55 | T orient(pt a, pt b, pt c) { return cross(b-a,c-a); } 56 | 57 | // ifp is inside smaller angle formed by ab and ac 58 | bool inAngle(pt a, pt b, pt c, pt p) { 59 | assert(orient(a,b,c) != 0); 60 | if(orient(a,b,c) < 0) swap(b,c); 61 | return orient(a,b,p) >= 0 && orient(a,c,p) <= 0; 62 | } 63 | 64 | // oriented angle between a->b and a->c 65 | double orientedAngle(pt a, pt b, pt c) { 66 | T ang = angle(b - a, c - a); 67 | if(orient(a, b, c) < 0) ang = 2*M_PI - ang; 68 | return ang; 69 | } 70 | 71 | bool isConvex(vector p) { 72 | bool hasPos = 0, hasNeg = 0; 73 | for(int i = 0, n = p.size(); i < n; i++) { 74 | int o = orient(p[i], p[(i+1)%n], p[(i+2)%n]); 75 | hasPos |= o > 0; 76 | hasNeg |= o < 0; 77 | } 78 | return !(hasPos && hasNeg); 79 | } 80 | 81 | // polar Sort 82 | bool half(pt p) { // true ifabove x axis 83 | assert(p.x != 0 || p.y != 0); 84 | return p.y > 0 || (p.y == 0 && p.x < 0); 85 | } 86 | bool half2(pt p, pt v) { // keep direction v first 87 | return cross(v,p)<0||(cross(v,p)==0&&dot(v,p)<0); 88 | } 89 | void polarSort(vector &v) { 90 | sort(v.begin(), v.end(), [](pt v, pt w) { 91 | return make_tuple(half(v), 0) < 92 | make_tuple(half(w), cross(v,w)); 93 | }); 94 | // subtract p forsorting around point p 95 | // add sq(v) in tuple forbreaking ties 96 | } 97 | 98 | 99 | struct line { 100 | pt v; T c; 101 | // from direction vector v and offset c 102 | line(pt v, T c) : v(v), c(c) {} 103 | // from equation ax+by=c 104 | line(T a, T b, T c) : v({b,-a}), c(c) {} 105 | // from points P and Q 106 | line(pt p, pt q) : v(q-p), c(cross(v,p)) {} 107 | 108 | T side(pt p) { return cross(v,p)-c; } 109 | 110 | double dist(pt p) { return abs(side(p)) / abs(v); } 111 | double sqDist(pt p) { 112 | return side(p)*side(p) / (double)sq(v); 113 | } 114 | 115 | line perpThrough(pt p) { return {p, p + perp(v)}; } 116 | 117 | // sorting points (projection) along a line 118 | bool cmpProj(pt p, pt q) { 119 | return dot(v,p) < dot(v,q); 120 | } 121 | 122 | line translate(pt t) { return {v, c + cross(v,t)}; } 123 | line shiftLeft(double dist) { 124 | return {v, c + dist * abs(v)}; 125 | } 126 | 127 | pt proj(pt p) {return p - perp(v)*side(p)/sq(v);} 128 | pt refl(pt p) {return p - perp(v)*2*side(p)/sq(v);} 129 | }; 130 | 131 | // intersection of two lines 132 | bool inter(line l1, line l2, pt &out) { 133 | T d = cross(l1.v, l2.v); 134 | if(d == 0) return false; 135 | out = (l2.v*l1.c - l1.v*l2.c) / d; 136 | return true; 137 | } 138 | 139 | // angle bisector of two lines 140 | line bisector(line l1, line l2, bool interior) { 141 | assert(cross(l1.v, l2.v) != 0); 142 | double sign = interior ? 1 : -1; 143 | return {l2.v/abs(l2.v) + l1.v/abs(l1.v) * sign, 144 | l2.c/abs(l2.v) + l1.c/abs(l1.v) * sign}; 145 | } 146 | 147 | // check ifp lies in disk of diameter ab 148 | bool inDisk(pt a, pt b, pt p) { 149 | return dot(a - p, b - p) <= 0; 150 | } 151 | 152 | bool onSegment(pt a, pt b, pt p) { 153 | return orient(a,b,p) == 0 && inDisk(a,b,p); 154 | } 155 | 156 | // segment intersection 157 | // proper intersection = 1 point, not endpoints 158 | bool properInter(pt a, pt b, pt c, pt d, pt &out) { 159 | double oa = orient(c,d,a), 160 | ob = orient(c,d,b), 161 | oc = orient(a,b,c), 162 | od = orient(a,b,d); 163 | if(oa*ob < 0 && oc*od < 0) { 164 | out = (a*ob - b*oa) / (ob-oa); 165 | return true; 166 | } 167 | return false; 168 | } 169 | // all intersections 170 | struct cmpX { 171 | bool operator()(pt a, pt b) { 172 | return make_pair(a.x, a.y) < make_pair(b.x, b.y); 173 | } 174 | }; 175 | set inters(pt a, pt b, pt c, pt d) { 176 | pt out; 177 | if(properInter(a,b,c,d,out)) return {out}; 178 | set s; 179 | if(onSegment(c,d,a)) s.insert(a); 180 | if(onSegment(c,d,b)) s.insert(b); 181 | if(onSegment(a,b,c)) s.insert(c); 182 | if(onSegment(a,b,d)) s.insert(d); 183 | return s; 184 | } 185 | 186 | // segment point distance 187 | double segPoint(pt a, pt b, pt p) { 188 | if(a != b) { 189 | line l(a,b); 190 | if(l.cmpProj(a,p) && l.cmpProj(p,b)) 191 | return l.dist(p); 192 | } 193 | return min(abs(p-a), abs(p-b)); 194 | } 195 | 196 | // segment segment distance 197 | double segSeg(pt a, pt b, pt c, pt d) { 198 | pt dummy; 199 | if(properInter(a,b,c,d,dummy)) 200 | return 0; 201 | return min({segPoint(a,b,c), segPoint(a,b,d), 202 | segPoint(c,d,a), segPoint(c,d,b)}); 203 | } 204 | 205 | double areaTriangle(pt a, pt b, pt c) { 206 | return abs(cross(b-a, c-a)) / 2.0; 207 | } 208 | 209 | double areaPolygon(vector p) { 210 | double area = 0.0; 211 | for(int i = 0, n = p.size(); i < n; i++) 212 | area += cross(p[i], p[(i+1)%n]); 213 | return abs(area) / 2.0; 214 | } 215 | 216 | // point in polygon: ray test 217 | // check if[PQ] crosses ray from A 218 | bool crossesRay(pt a, pt p, pt q) { 219 | return ((q.y>=a.y)-(p.y>=a.y)) * orient(a,p,q) > 0; 220 | } 221 | // ifstrict, returns false when A is on the boundary 222 | bool inPolygon(vector p, pt a, bool strict=true) { 223 | int numCrossings = 0; 224 | for(int i = 0, n = p.size(); i < n; i++) { 225 | if(onSegment(p[i], p[(i+1)%n], a)) 226 | return !strict; 227 | numCrossings += crossesRay(a, p[i], p[(i+1)%n]); 228 | } 229 | return numCrossings & 1; 230 | } 231 | 232 | // amplitude travelled around point A, from P to Q 233 | double angleTravelled(pt a, pt p, pt q) { 234 | double ampli = angle(p-a, q-a); 235 | if(orient(a,p,q) > 0) return ampli; 236 | else return -ampli; 237 | } 238 | 239 | // winding number (number of full turns around point) 240 | // WARNING: not defined ifa is on boundary of poly 241 | int windingNumber(vector p, pt a) { 242 | double ampli = 0; 243 | for(int i = 0, n = p.size(); i < n; i++) 244 | ampli += angleTravelled(a, p[i], p[(i+1)%n]); 245 | return round(ampli / (2*M_PI)); 246 | } 247 | 248 | // circle stuff 249 | pt circumCenter(pt a, pt b, pt c) { 250 | b = b-a, c = c-a; 251 | assert(cross(b,c) != 0); 252 | return a + perp(b*sq(c) - c*sq(b))/cross(b,c)/2; 253 | } 254 | 255 | // circle line intersection. returns # intersections 256 | int circleLine(pt o, double r, line l, 257 | pair &out) { 258 | double h2 = r*r - l.sqDist(o); 259 | if(h2 >= 0) { 260 | pt p = l.proj(o); 261 | pt h = l.v*sqrt(h2)/abs(l.v); 262 | out = {p-h, p+h}; 263 | } 264 | return 1 + sgn(h2); 265 | } 266 | 267 | // circle circle intersection. returns # intersections 268 | int circleCircle(pt o1, double r1, pt o2, double r2, 269 | pair &out) { 270 | pt d = o2 - o1; double d2 = sq(d); 271 | if(d2 == 0) { assert(r1 != r2); return 0; } 272 | double pd = (d2 + r1*r1 - r2*r2)/2; 273 | double h2 = r1*r1 - pd*pd/d2; 274 | if(h2 >= 0) { 275 | pt p = o1 + d*pd/d2, h = perp(d)*sqrt(h2/d2); 276 | out = {p-h, p+h}; 277 | } 278 | return 1 + sgn(h2); 279 | } 280 | 281 | // tangets of two circles 282 | int tangents(pt o1, double r1, pt o2, double r2, 283 | bool inner, vector> &out) { 284 | if(inner) r2 = -r2; 285 | pt d = o2-o1; 286 | double dr = r1-r2, d2 = sq(d), h2 = d2-dr*dr; 287 | if(d2 == 0 || h2 < 0) { assert(h2 != 0); return 0; } 288 | for(double sign : {-1,1}) { 289 | pt v = (d*dr + perp(d)*sqrt(h2)*sign)/d2; 290 | out.push_back({o1 + v*r1, o2 + v*r2}); 291 | } 292 | return 1 + (h2 > 0); 293 | } 294 | 295 | 296 | 297 | struct p3 { 298 | T x,y,z; 299 | p3 operator+(p3 p) { return {x+p.x, y+p.y, z+p.z}; } 300 | p3 operator-(p3 p) { return {x-p.x, y-p.y, z-p.z}; } 301 | p3 operator*(T d) { return {x*d, y*d, z*d}; } 302 | p3 operator/(T d) { return {x/d, y/d, z/d}; } 303 | 304 | bool operator==(p3 p) { 305 | return tie(x,y,z) == tie(p.x,p.y,p.z); 306 | } 307 | bool operator!=(p3 p) { return !operator==(p); } 308 | }; 309 | 310 | p3 zero{0,0,0}; 311 | 312 | 313 | // dot product 314 | T operator|(p3 v, p3 w) { 315 | return v.x*w.x + v.y*w.y + v.z*w.z; 316 | } 317 | 318 | // cross product 319 | p3 operator*(p3 v, p3 w) { 320 | return {v.y*w.z - v.z*w.y, 321 | v.z*w.x - v.x*w.z, 322 | v.x*w.y - v.y*w.x}; 323 | } 324 | 325 | T sq(p3 v) { return v|v; } 326 | double abs(p3 v) { return sqrt(sq(v)); } 327 | p3 unit(p3 v) { return v/abs(v); } 328 | 329 | double angle(p3 v, p3 w) { 330 | double cosTheta = (v|w) / abs(v) / abs(w); 331 | return acos(max(-1.0, min(1.0, cosTheta))); 332 | } 333 | 334 | // positive side is the direction of pq X pr 335 | T orient(p3 p, p3 q, p3 r, p3 s) { 336 | return (q - p)*(r - p) | (s - p); 337 | } 338 | 339 | 340 | struct plane { 341 | p3 n; T d; 342 | // from normal n and offset d 343 | plane(p3 n, T d) : n(n), d(d) {} 344 | // from normal n and point P 345 | plane(p3 n, p3 p) : n(n), d(n|p) {} 346 | // from three non-collinear points P,Q,R 347 | plane(p3 p, p3 q, p3 r) : plane((q-p)*(r-p), p) {} 348 | 349 | // positive side in direction of n 350 | T side(p3 p) { return (n|p)-d; } 351 | double dist(p3 p) { return abs(side(p))/abs(n); } 352 | plane translate(p3 t) { return {n, d+(n|t)}; } 353 | plane shiftUp(double dist) { 354 | return {n, d + dist*abs(n)}; 355 | } 356 | p3 proj(p3 p) {return p - n*side(p)/sq(n);} 357 | p3 refl(p3 p) {return p - n*2*side(p)/sq(n);} 358 | }; 359 | 360 | // 3D coords based on plane 361 | struct coords { 362 | p3 o, dx, dy, dz; 363 | // from three points P,Q,R on the plane: 364 | // build an orthonormal 3D basis 365 | coords(p3 p, p3 q, p3 r) : o(p) { 366 | dx = unit(q-p); 367 | dz = unit(dx*(r-p)); 368 | dy = dz*dx; 369 | } 370 | // from four points P,Q,R,S: 371 | // take directions PQ, PR, PS as is 372 | coords(p3 p, p3 q, p3 r, p3 s) : 373 | o(p), dx(q-p), dy(r-p), dz(s-p) {} 374 | 375 | pt pos2d(p3 p) { 376 | return {(p-o)|dx, (p-o)|dy}; 377 | } 378 | p3 pos3d(p3 p) { 379 | return {(p-o)|dx, (p-o)|dy, (p-o)|dz}; 380 | } 381 | }; 382 | 383 | // 3D line 384 | struct line3d { 385 | p3 d, o; 386 | // from two points P, Q 387 | line3d(p3 p, p3 q) : d(q-p), o(p) {} 388 | // from two planes p1, p2 389 | line3d(plane p1, plane p2) { 390 | d = p1.n*p2.n; 391 | o = (p2.n*p1.d - p1.n*p2.d)*d/sq(d); 392 | } 393 | double sqDist(p3 p) { return sq(d*(p-o))/sq(d); } 394 | double dist(p3 p) { return sqrt(sqDist(p)); } 395 | bool cmpProj(p3 p, p3 q) { return (d|p) < (d|q); } 396 | p3 proj(p3 p) { return o + d*(d|(p-o))/sq(d); } 397 | p3 refl(p3 p) { return proj(p)*2 - p; } 398 | p3 inter(plane p) {return o - d*p.side(o)/(p.n|d);} 399 | }; 400 | 401 | // line line distance 402 | double dist(line3d l1, line3d l2) { 403 | p3 n = l1.d*l2.d; 404 | if(n == zero) // parallel 405 | return l1.dist(l2.o); 406 | return abs((l2.o-l1.o)|n)/abs(n); 407 | } 408 | 409 | // closest point on L1 from L2 410 | p3 closestOnL1(line3d l1, line3d l2) { 411 | p3 n2 = l2.d*(l1.d*l2.d); 412 | return l1.o + l1.d*((l2.o-l1.o)|n2)/(l1.d|n2); 413 | } 414 | 415 | line3d perpThrough(plane p, p3 o) {return line3d(o, o+p.n);} 416 | plane perpThrough(line3d l, p3 o) {return plane(l.d, o);} 417 | 418 | // angles between planes/lines 419 | double smallAngle(p3 v, p3 w) { // in [0, pi/2] 420 | return acos(min(abs(v|w)/abs(v)/abs(w), 1.0)); 421 | } 422 | double angle(plane p1, plane p2) { 423 | return smallAngle(p1.n, p2.n); 424 | } 425 | bool isParallel(plane p1, plane p2) { 426 | return p1.n*p2.n == zero; 427 | } 428 | bool isPerpendicular(plane p1, plane p2) { 429 | return (p1.n|p2.n) == 0; 430 | } 431 | double angle(line3d l1, line3d l2) { 432 | return smallAngle(l1.d, l2.d); 433 | } 434 | bool isParallel(line3d l1, line3d l2) { 435 | return l1.d*l2.d == zero; 436 | } 437 | bool isPerpendicular(line3d l1, line3d l2) { 438 | return (l1.d|l2.d) == 0; 439 | } 440 | double angle(plane p, line3d l) { 441 | return M_PI/2 - smallAngle(p.n, l.d); 442 | } 443 | bool isParallel(plane p, line3d l) { 444 | return (p.n|l.d) == 0; 445 | } 446 | bool isPerpendicular(plane p, line3d l) { 447 | return p.n*l.d == zero; 448 | } 449 | 450 | 451 | // polyhedron 452 | p3 vectorArea2(vector p) { // area vector 453 | p3 S = zero; 454 | for(int i = 0, n = p.size(); i < n; i++) 455 | S = S + p[i]*p[(i+1)%n]; 456 | return S; 457 | } 458 | double area(vector p) { 459 | return abs(vectorArea2(p)) / 2.0; 460 | } 461 | 462 | // polyhedron orient faces 463 | bool operator<(p3 p, p3 q) { 464 | return tie(p.x, p.y, p.z) < tie(q.x, q.y, q.z); 465 | } 466 | struct edge { 467 | int v; 468 | bool same; // is the common edge in the same order? 469 | }; 470 | 471 | void reorient(vector> &fs) { 472 | int n = fs.size(); 473 | 474 | vector> g(n); 475 | map,int> es; 476 | for(int u = 0; u < n; u++) { 477 | for(int i = 0, m = fs[u].size(); i < m; i++) { 478 | p3 a = fs[u][i], b = fs[u][(i+1)%m]; 479 | if(es.count({a,b})) { 480 | int v = es[{a,b}]; 481 | g[u].push_back({v,true}); 482 | g[v].push_back({u,true}); 483 | } else if(es.count({b,a})) { 484 | int v = es[{b,a}]; 485 | g[u].push_back({v,false}); 486 | g[v].push_back({u,false}); 487 | } else { 488 | es[{a,b}] = u; 489 | } 490 | } 491 | } 492 | 493 | vector vis(n,false), flip(n); 494 | flip[0] = false; 495 | queue q; 496 | q.push(0); 497 | while (!q.empty()) { 498 | int u = q.front(); 499 | q.pop(); 500 | for(edge e : g[u]) { 501 | if(!vis[e.v]) { 502 | vis[e.v] = true; 503 | flip[e.v] = (flip[u] ^ e.same); 504 | q.push(e.v); 505 | } 506 | } 507 | } 508 | 509 | for(int u = 0; u < n; u++) 510 | if(flip[u]) 511 | reverse(fs[u].begin(), fs[u].end()); 512 | } 513 | 514 | double volume(vector> fs) { 515 | double vol6 = 0.0; 516 | for(vector f : fs) 517 | vol6 += (vectorArea2(f)|f[0]); 518 | return abs(vol6) / 6.0; 519 | } 520 | 521 | 522 | // spherical geometry 523 | // 3D point from lat, lon 524 | // lat from y to z, lon from x to y 525 | p3 sph(double r, double lat, double lon) { 526 | lat *= M_PI/180, lon *= M_PI/180; 527 | return {r*cos(lat)*cos(lon), 528 | r*cos(lat)*sin(lon), 529 | r*sin(lat)}; 530 | } 531 | 532 | // spehere line intersection, returns # intersection 533 | int sphereLine(p3 o, double r, line3d l, 534 | pair &out) { 535 | double h2 = r*r - l.sqDist(o); 536 | if(h2 < 0) return 0; 537 | p3 p = l.proj(o); 538 | p3 h = l.d*sqrt(h2)/abs(l.d); 539 | out = {p-h, p+h}; 540 | return 1 + (h2 > 0); 541 | } 542 | 543 | // great-circle-distance 544 | double greatCircleDist(p3 o, double r, p3 a, p3 b) { 545 | return r * angle(a-o, b-o); 546 | } 547 | 548 | // spherical segment intersection 549 | bool validSegment(p3 a, p3 b) { 550 | return a*b != zero || (a|b) > 0; 551 | } 552 | // 1 intersection, not endpoints 553 | bool properInter(p3 a, p3 b, p3 c, p3 d, p3 &out) { 554 | p3 ab = a*b, cd = c*d; 555 | int oa = sgn(cd|a), 556 | ob = sgn(cd|b), 557 | oc = sgn(ab|c), 558 | od = sgn(ab|d); 559 | out = ab*cd*od; 560 | return (oa != ob && oc != od && oa != oc); 561 | } 562 | // check ifp on segment a, b 563 | bool onSphSegment(p3 a, p3 b, p3 p) { 564 | p3 n = a*b; 565 | if(n == zero) 566 | return a*p == zero && (a|p) > 0; 567 | return (n|p) == 0 && (n|a*p) >= 0 && (n|b*p) <= 0; 568 | } 569 | struct directionSet : vector { 570 | using vector::vector; // import constructors 571 | void insert(p3 p) { 572 | for(p3 q : *this) if(p*q == zero) return; 573 | push_back(p); 574 | } 575 | }; 576 | // handles improper intersections 577 | directionSet intersSph(p3 a, p3 b, p3 c, p3 d) { 578 | assert(validSegment(a, b) && validSegment(c, d)); 579 | p3 out; 580 | if(properInter(a, b, c, d, out)) return {out}; 581 | directionSet s; 582 | if(onSphSegment(c, d, a)) s.insert(a); 583 | if(onSphSegment(c, d, b)) s.insert(b); 584 | if(onSphSegment(a, b, c)) s.insert(c); 585 | if(onSphSegment(a, b, d)) s.insert(d); 586 | return s; 587 | } 588 | 589 | // spherical angle 590 | // angle between plane through ab and ac 591 | double angleSph(p3 a, p3 b, p3 c) { 592 | return angle(a*b, a*c); 593 | } 594 | double orientedAngleSph(p3 a, p3 b, p3 c) { 595 | if((a*b|c) >= 0) 596 | return angleSph(a, b, c); 597 | else 598 | return 2*M_PI - angleSph(a, b, c); 599 | } 600 | 601 | // area of spherical polygon 602 | double areaOnSphere(double r, vector p) { 603 | int n = p.size(); 604 | double sum = -(n-2)*M_PI; 605 | for(int i = 0; i < n; i++) 606 | sum += orientedAngleSph(p[(i+1)%n], p[(i+2)%n], p[i]); 607 | return r*r*sum; 608 | } 609 | 610 | // 3D winding number 611 | int windingNumber3D(vector> fs) { 612 | double sum = 0; 613 | for(vector f : fs) 614 | sum += remainder(areaOnSphere(1, f), 4*M_PI); 615 | return round(sum / (4*M_PI)); 616 | } 617 | 618 | 619 | 620 | int main() { 621 | 622 | } -------------------------------------------------------------------------------- /Number Theoretic Transform.cpp: -------------------------------------------------------------------------------- 1 | const int mod = 998244353, g = 3; 2 | const int N = 1 << 20; 3 | 4 | inline int Pow(int a, int p) { 5 | int ret = 1; while(p) { 6 | if(p & 1) ret = (ll) ret * a % mod; 7 | a = (ll) a * a % mod; 8 | p >>= 1; 9 | } return ret; 10 | } 11 | 12 | 13 | vector rev; 14 | vector w; 15 | 16 | void prepare(int n) { // n is power of 2 17 | int sz = __builtin_ctz(n); 18 | if(rev.size() != n) { 19 | rev.assign(n, 0); 20 | for(int i = 0; i < n; ++i) { 21 | rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (sz - 1)); 22 | } 23 | } 24 | 25 | if(w.size() >= n) return; 26 | if(w.empty()) w = {0, 1}; 27 | 28 | sz = __builtin_ctz(w.size()); 29 | w.resize(n); 30 | 31 | // w[n + i] = w_{2n}^i, n power of 2, i < n 32 | while((1 << sz) < n) { 33 | int wn = Pow(g, (mod - 1) >> (sz + 1)); 34 | for(int i = 1 << (sz - 1); i < (1 << sz); ++i) { 35 | w[i << 1] = w[i]; 36 | w[i << 1 | 1] = (ll) w[i] * wn % mod; 37 | } ++sz; 38 | } 39 | } 40 | 41 | void fft(int *p, int n) { 42 | prepare(n); 43 | for(int i = 1; i < n - 1; ++i) 44 | if(i < rev[i]) swap(p[i], p[rev[i]]); 45 | for(int h = 1; h < n; h <<= 1) { 46 | for(int s = 0; s < n; s += h << 1) { 47 | for(int i = 0; i < h; ++i) { 48 | int &u = p[s + i], &v = p[s + h + i], 49 | t = (ll) v * w[h + i] % mod; 50 | v = u - t < 0 ? u - t + mod : u - t; 51 | u = u + t >= mod ? u + t - mod : u + t; 52 | } 53 | } 54 | } 55 | } 56 | 57 | void mul(int *a, int *b, int *c, int n, int m) { 58 | static int f[N], g[N]; 59 | 60 | int sz = n + m - 1; 61 | while(sz & (sz - 1)) sz = (sz | (sz - 1)) + 1; 62 | memcpy(f, a, n << 2), memcpy(g, b, m << 2); 63 | memset(f + n, 0, sz - n << 2), memset(g + m, 0, sz - n<< 2); 64 | 65 | fft(f, sz), fft(g, sz); 66 | for(int i = 0; i < sz; ++i) 67 | f[i] = (ll) f[i] * g[i] % mod; 68 | reverse(f + 1, f + sz); 69 | fft(f, sz); 70 | 71 | int inv_n = Pow(sz, mod - 2); 72 | for(int i = 0; i < sz; ++i) 73 | c[i] = (ll) f[i] * inv_n % mod; 74 | } 75 | 76 | // primitive root, finding the number with order p-1 77 | int primitive_root(int p) { 78 | vector factor; 79 | int tmp = p - 1; 80 | for (int i = 2; i * i <= tmp; ++i) { 81 | if (tmp % i == 0) { 82 | factor.push_back(i); 83 | while (tmp % i == 0) tmp /= i; 84 | } 85 | } 86 | if (tmp != 1) factor.push_back(tmp); 87 | for (int root = 1;; ++root) { 88 | bool flag = true; 89 | for (int i = 0; i < factor.size(); ++i) { 90 | if (Pow(root, (p - 1) / factor[i], p) == 1) { 91 | flag = false; 92 | break; 93 | } 94 | } 95 | if (flag) return root; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /Number Theory for Copy Paste.cpp: -------------------------------------------------------------------------------- 1 | // Sieve 2 | 3 | const int N = 2e5 + 10; 4 | bitset mark; 5 | vector prime; 6 | 7 | void sieve() { mark.set(); // Linear Sieve 8 | for(int i = 2; i < N; i++) { 9 | if(mark[i]) prime.push_back(i); 10 | for(int j = 0; j < prime.size() && i * prime[j] < N; j++) { 11 | mark[i * prime[j]] = 0; 12 | if(i % prime[j] == 0) break; 13 | } 14 | } 15 | } 16 | 17 | 18 | // Binomial 19 | 20 | const int mod = 1e9 + 7; 21 | 22 | int fact[N], inv[N]; 23 | inline int Pow(int a, int p) { 24 | int ret = 1; while(p) { 25 | if(p & 1) ret = (ll) ret * a % mod; 26 | a = (ll) a * a % mod; 27 | p >>= 1; 28 | } return ret; 29 | } 30 | void init() { 31 | fact[0] = 1; 32 | for(int i = 1; i < N; ++i) 33 | fact[i] = (ll) fact[i - 1] * i % mod; 34 | inv[N - 1] = Pow(fact[N - 1], mod - 2); 35 | for(int i = N - 2; i >= 0; --i) 36 | inv[i] = (ll) inv[i + 1] * (i + 1) % mod; 37 | } 38 | int C(int n, int r) { 39 | int ret = (ll) fact[n] * inv[n - r] % mod; 40 | return (ll) ret * inv[r] % mod; 41 | } 42 | 43 | 44 | 45 | // Discrete Log 46 | ll shanks(ll a, ll b, ll m) { 47 | a %= m, b %= m; ll n = sqrt(m) + 1; 48 | unordered_map mp; 49 | ll an = 1, base = 1, ans = -1; 50 | for(int i = 0; i < n; i++) an = (an * a) % m; 51 | for(int i = 1; i <= n; i++) { 52 | base = (base * an) % m; 53 | if(!mp.count(base)) 54 | mp[base] = i; 55 | } base = b; 56 | for(int j = 0; j <= n; j++) { 57 | if(mp.count(base)) { 58 | ll ret = mp[base] * n - j; 59 | if(ans == -1 || (ret < m && ans > ret)) ans = ret; 60 | } base = (base * a) % m; 61 | } return ans; 62 | } 63 | 64 | 65 | // primitive root, finding the number with order p-1 66 | int primitive_root(int p) { 67 | vector factor; 68 | int tmp = p - 1; 69 | for (int i = 2; i * i <= tmp; ++i) { 70 | if (tmp % i == 0) { 71 | factor.push_back(i); 72 | while (tmp % i == 0) tmp /= i; 73 | } 74 | } 75 | if (tmp != 1) factor.push_back(tmp); 76 | for (int root = 1;; ++root) { 77 | bool flag = true; 78 | for (int i = 0; i < factor.size(); ++i) { 79 | if (Pow(root, (p - 1) / factor[i], p) == 1) { 80 | flag = false; 81 | break; 82 | } 83 | } 84 | if (flag) return root; 85 | } 86 | } 87 | 88 | 89 | -------------------------------------------------------------------------------- /PalindromicTree.cpp: -------------------------------------------------------------------------------- 1 | const int N = 3e5 + 5; 2 | 3 | int tree[N][26], t, sz, len[N], link[N]; 4 | int slink[N], diff[N]; // not required for all problems 5 | char s[N]; 6 | 7 | void extend(int p) { 8 | while (s[p - len[t] - 1] != s[p]) t = link[t]; 9 | int x = link[t]; 10 | while (s[p - len[x] - 1] != s[p]) x = link[x]; 11 | int c = s[p] - 'a'; 12 | if (!tree[t][c]) { 13 | tree[t][c] = ++sz; 14 | len[sz] = len[t] + 2; 15 | link[sz] = len[sz] == 1 ? 2 : tree[x][c]; 16 | diff[sz] = len[sz] - len[link[sz]]; 17 | if (diff[sz] == diff[link[sz]]) 18 | slink[sz] = slink[link[sz]]; 19 | else 20 | slink[sz] = link[sz]; 21 | } 22 | t = tree[t][c]; 23 | } 24 | 25 | void build() { 26 | len[1] = -1, len[2] = 0; 27 | link[1] = link[2] = 1; 28 | t = idx = 2; 29 | for (int i = 1; i <= n; i++) extend(i); 30 | for (int i = idx; i > 2; i--) { 31 | occ[link[i]] += occ[i]; 32 | } 33 | } 34 | 35 | void dp_on_suffixes() { 36 | for(int i = 1; i <= n; ++i) { 37 | extend(i); 38 | for(int u = t; len[u] > 0; u = slink[u]) { 39 | dp[u] = ans[i - len[slink[u]] - diff[u]]; 40 | if(diff[u] == diff[link[u]]) 41 | dp[u] = min(dp[u], dp[link[u]]); 42 | ans[i] = min(ans[i], dp[u] + 1); 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /Persistent Segment Tree.cpp: -------------------------------------------------------------------------------- 1 | /*//////////////////////////////////////// 2 | Persistent Segment Tree 3 | To update in a version first copy the root, 4 | then make update in the version. Something like this - 5 | root[y] = root[x]; 6 | update(root[y], ...) 7 | /*//////////////////////////////////////// 8 | 9 | const int maxn = 1e5+10; 10 | struct node { 11 | int l, r, sum; 12 | } t[maxn * 20]; 13 | int root[maxn], a[maxn], n, m, k, idx, M; 14 | 15 | void update(int &nd, int l, int r, int &i) { 16 | t[++idx] = t[nd]; 17 | ++t[nd = idx].sum; // += v; 18 | if(l == r) return; 19 | int m = l + r >> 1; 20 | if(i <= m) update(t[nd].l, l, m, i); 21 | else update(t[nd].r, m + 1, r, i); 22 | } 23 | 24 | int query(int nd, int l, int r, int &i, int &j) { 25 | if(r < i || l > j) return 0; 26 | if(i <= l && r <= j) return t[nd].sum; 27 | int m = l + r >> 1; 28 | return query(t[nd].l, l, m, i, j) + query(t[nd].r, m + 1, r, i, j); 29 | } 30 | // a = root[r], b = root[l - 1] 31 | int lesscnt(int a, int b, int l, int r, int k) { 32 | if(r <= k) return t[a].sum - t[b].sum; 33 | int m = l + r >> 1; 34 | if(k <= m) return lesscnt(t[a].l, t[b].l, l, m, k); 35 | else return lesscnt(t[a].l, t[b].l, l, m, k) + 36 | lesscnt(t[a].r, t[b].r, m + 1, r, k); 37 | } 38 | int kthnum(int a, int b, int l, int r, int k) { 39 | if(l == r) return l; 40 | int cnt = t[t[a].l].sum - t[t[b].l].sum; 41 | int m = l + r >> 1; 42 | if(cnt >= k) return kthnum(t[a].l, t[b].l, l, m, k); 43 | else return kthnum(t[a].r, t[b].r, m + 1, r, k - cnt); 44 | } 45 | void init(int v = 1) { 46 | t[0].l = t[0].r = t[0].sum = 0; 47 | for(int i = 1; i <= n; ++i) 48 | update(root[i] = root[i - 1], 0, M, a[i]); 49 | } -------------------------------------------------------------------------------- /Persistent Trie.cpp: -------------------------------------------------------------------------------- 1 | const int maxn = 3e5 + 10; 2 | struct node { 3 | node *ch[2]; 4 | node() { ch[0] = ch[1] = NULL; } 5 | node *clone() { 6 | node *ret = new node(); 7 | if(this) { 8 | ret -> ch[0] = ch[0]; 9 | ret -> ch[1] = ch[1]; 10 | } return ret; 11 | } 12 | }; 13 | node *trie[maxn]; 14 | 15 | void insert(int v, int p, int val) { 16 | node *curr = trie[v] = trie[p] -> clone(); 17 | for(int i = 31; i >= 0; i--) { 18 | int bit = (val >> i) & 1; 19 | node* &ch = curr -> ch[bit]; 20 | curr = ch = ch -> clone(); 21 | } 22 | } 23 | int queryMin(node *curr, int val) { 24 | int ans = 0; 25 | for(int i = 31; i >= 0; i--) { 26 | int bit = (val >> i) & 1; 27 | if(curr -> ch[bit]) curr = curr -> ch[bit]; 28 | else { 29 | curr = curr -> ch[bit^1]; 30 | ans |= (1 << i); 31 | } 32 | } return ans; 33 | } 34 | int queryMax(node *curr, int val) { 35 | int ans = 0; 36 | for(int i = 31; i >= 0; i--) { 37 | int bit = (val >> i) & 1; 38 | if(curr -> ch[bit ^ 1]) { 39 | ans |= (1 << i); 40 | curr = curr -> ch[bit ^ 1]; 41 | } else curr = curr -> ch[bit]; 42 | } return ans; 43 | } 44 | void print(node *curr, stack &st) { 45 | if(curr -> ch[0] == NULL && curr -> ch[1] == NULL){ 46 | stack tmp = st; 47 | vector v; 48 | while(!st.empty()) { 49 | v.push_back(st.top()); 50 | st.pop(); 51 | } st = tmp; 52 | for(int i = v.size() - 1; i >= 0; i--) 53 | cout << v[i]; 54 | cout << endl; return; 55 | } 56 | if(curr -> ch[0]) { 57 | st.push(0); 58 | print(curr -> ch[0], st); 59 | st.pop(); 60 | } 61 | if(curr -> ch[1]) { 62 | st.push(1); 63 | print(curr -> ch[1], st); 64 | st.pop(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /PolardRho.cpp: -------------------------------------------------------------------------------- 1 | inline ll mul64(ll x, ll y, ll mod) { 2 | ll ans = 0; 3 | __asm__ ( 4 | "movq %1,%%rax\n imulq %2\n idivq %3\n" 5 | :"=d"(ans):"m"(x),"m"(y),"m"(mod):"%rax" 6 | ); 7 | return ans; 8 | } 9 | inline ll Pow(ll a, ll p, ll mod) { 10 | ll ret = 1; while(p) { 11 | if(p & 1) ret = mul64(ret, a, mod); 12 | a = mul64(a, a, mod); 13 | p >>= 1; 14 | } return ret; 15 | } 16 | bool miller_rabin(ll n, ll b) { 17 | ll m = n - 1, cnt = 0; 18 | while (m % 2 == 0) m >>= 1, ++cnt; 19 | ll ret = Pow(b, m, n); 20 | if (ret == 1 || ret == n - 1) return true; 21 | while (cnt > 0) { 22 | ret = mul64(ret, ret, n); 23 | if (ret == n - 1) return true; 24 | --cnt; 25 | } return false; 26 | } 27 | bool ptest(ll n) { // miller-rabin primality test 28 | if(n < 2) return false; 29 | if(n < 4) return true; 30 | const int BASIC[12] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37 }; 31 | for(int i = 0; i < 12 && BASIC[i] < n; ++i) 32 | if(!miller_rabin(n, BASIC[i])) return false; 33 | return true; 34 | } 35 | ll pollard_rho(ll n, ll seed) { 36 | ll x, y; 37 | x = y = rand() % (n - 1) + 1; 38 | int head = 1, tail = 2; 39 | while (true) { 40 | x = mul64(x, x, n); 41 | x = (x + seed) % n; 42 | if (x == y) return n; 43 | ll d = __gcd(max(x - y, y - x), n); 44 | if (1 < d && d < n) return d; 45 | if (++head == tail) y = x, tail <<= 1; 46 | } 47 | } 48 | void factorize(ll n, vector &divisor) { 49 | if (n == 1) return; 50 | if (ptest(n)) divisor.push_back(n); 51 | else { 52 | ll d = n; 53 | while (d >= n) d = pollard_rho(n, rand()%(n-1)+1); 54 | factorize(n / d, divisor); 55 | factorize(d, divisor); 56 | } 57 | } 58 | vector divisors(vector d) { 59 | vector ret = {1}; 60 | sort(d.begin(), d.end()); 61 | for (int i = 0, count = 1; i < d.size(); ++i) { 62 | if (i + 1 == d.size() || d[i] != d[i + 1]) { 63 | int c = ret.size(); 64 | ret.resize(ret.size() * (count+1)); 65 | ll n = 1; 66 | for (int j = 1; j <= count + 1; ++j) { 67 | for (int k = 0; k < c; ++k) { 68 | ret[(j-1)*c+k] = ret[k]*n; 69 | } 70 | n *= d[i]; 71 | } 72 | count = 1; 73 | } else count += 1; 74 | } 75 | sort(ret.begin(), ret.end()); 76 | return ret; 77 | } 78 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CodeTemplate 2 | My Code Templates 3 | -------------------------------------------------------------------------------- /Segment Tree (Lazy Prop).cpp: -------------------------------------------------------------------------------- 1 | struct tree { 2 | vector t, lazy; 3 | void init(int n) { 4 | t = vector (2 * n, 0); 5 | lazy = vector (2 * n, 0); 6 | } 7 | void upd(int node, int l, int r, ll v) { 8 | lazy[node] += v; 9 | t[node] += (r - l + 1) * v; 10 | } 11 | void shift(int node, int l, int r) { 12 | int m = l + r >> 1, L = node + 1, R = node + 2 * (m - l + 1); 13 | upd(L, l, m, lazy[node]); 14 | upd(R, m + 1, r, lazy[node]); 15 | lazy[node] = 0; 16 | } 17 | void update(int node, int l, int r, int i, int j, ll v) { 18 | if(r < i || l > j) return; 19 | if(i <= l && r <= j) { 20 | upd(node, l, r, v); 21 | return; 22 | } shift(node, l, r); 23 | int m = l + r >> 1, L = node + 1, R = node + 2 * (m - l + 1); 24 | update(L, l, m, i, j, v); 25 | update(R, m + 1, r, i, j, v); 26 | t[node] = t[L] + t[R]; 27 | } 28 | ll query(int node, int l, int r, int i, int j) { 29 | if(r < i || l > j) return 0; 30 | if(i <= l && r <= j) return t[node]; 31 | shift(node, l, r); 32 | int m = l + r >> 1, L = node + 1, R = node + 2 * (m - l + 1); 33 | return query(L, l, m, i, j) + query(R, m + 1, r, i, j); 34 | } 35 | } t; -------------------------------------------------------------------------------- /Segment Tree.cpp: -------------------------------------------------------------------------------- 1 | 2 | int tree[maxn<<2]; 3 | void build(int node, int l, int r) { 4 | if(l == r) { tree[node] = arr[l]; return; } 5 | int mid = l + r >> 1; 6 | build(node<<1, l, mid); 7 | build(node<<1|1, mid+1, r); 8 | tree[node] = tree[node<<1] + tree[node<<1|1]; 9 | } 10 | void update(int node, int l, int r, int i, int j, ll v) { 11 | if(r < i || l > j) return; 12 | if(i <= l && r <= j) { 13 | tree[node] += v; 14 | return; 15 | } int mid = l + r >> 1; 16 | update(node << 1, l, mid, i, j, v); 17 | update(node << 1|1, mid+1, r, i, j, v); 18 | tree[node] = tree[node << 1] + tree[node << 1 | 1]; 19 | } 20 | ll query(int node, int l, int r, int i, int j) { 21 | if(r < i || l > j) return 0; 22 | if(i <= l && r <= j) { 23 | return tree[node]; 24 | } int mid = l + r >> 1; 25 | return query(node << 1, l, mid, i, j) + 26 | query(node << 1|1, mid+1, r, i,j); 27 | } -------------------------------------------------------------------------------- /Simpson.cpp: -------------------------------------------------------------------------------- 1 | double f(double x) { return x * x; } 2 | 3 | double simpson(double a, double b, double eps, 4 | double whole, double fa, double fb, 5 | double fm, int rec) { 6 | double m = (a + b)/2, h = (b - a)/2; 7 | double lm = (a + m)/2, rm = (m + b)/2; 8 | // serious numerical trouble: it won't converge 9 | if ((eps/2 == eps) || (a == lm)) { 10 | errno = EDOM; return whole; 11 | } 12 | 13 | double flm = f(lm), frm = f(rm); 14 | double left = (h/6) * (fa + 4*flm + fm); 15 | double right = (h/6) * (fm + 4*frm + fb); 16 | double delta = left + right - whole; 17 | 18 | // depth limit too shallow 19 | if (rec <= 0 && errno != EDOM) errno = ERANGE; 20 | 21 | if (rec <= 0 || fabs(delta) <= 15*eps) 22 | return left + right + (delta)/15; 23 | return simpson(f,a,m,eps/2, left,fa,fm,flm,rec-1) + 24 | simpson(f,m,b,eps/2,right,fm,fb,frm,rec-1); 25 | } 26 | 27 | double integrate(double a, double b, double eps) { 28 | errno = 0; 29 | double h = b - a; 30 | if (h == 0) return 0; 31 | double fa = f(a), fb = f(b), fm = f((a + b)/2); 32 | double S = (h/6)*(fa + 4*fm + fb); 33 | return simson(a, b, eps, S, fa, fb, fm, 20); 34 | } -------------------------------------------------------------------------------- /Stoer-Wagner.cpp: -------------------------------------------------------------------------------- 1 | const int inf = 1e9; // larger than Min Cut 2 | const int maxn = 160; 3 | 4 | int cost[maxn][maxn], w[maxn]; 5 | bool vis[maxn], merged[maxn]; 6 | vector bestCut; 7 | 8 | int MinCut(int n) { 9 | int best = inf; merged[0] = 1; 10 | for(int i = 1; i < n; i++) merged[i] = 0; 11 | // vector cut; 12 | for(int phase = 1; phase < n; ++phase) { 13 | vis[0] = 1; 14 | for(int i = 1; i < n; ++i) if(!merged[i]) 15 | vis[i] = 0, w[i] = cost[0][i]; 16 | 17 | int prv = 0, nxt; 18 | for(int i = n - 1 - phase; i >= 0; --i) { 19 | nxt = -1; 20 | for(int j = 1; j < n; ++j) 21 | if(!vis[j] && (nxt == -1 || w[j] > w[nxt])) 22 | nxt = j; 23 | vis[nxt] = 1; 24 | if(i) { prv = nxt; 25 | for(int j = 1; j < n; ++j) 26 | if(!vis[j]) w[j] += cost[nxt][j]; 27 | } 28 | } 29 | for(int i = 0; i < n; i++) 30 | cost[i][prv] = (cost[prv][i] += cost[nxt][i]); 31 | merged[nxt] = 1; 32 | // cut.push_back(nxt); 33 | if(best > w[nxt]) { 34 | best = w[nxt]; 35 | // bestCut = cut; 36 | } 37 | } return best; 38 | } -------------------------------------------------------------------------------- /Strongly Connected Components.cpp: -------------------------------------------------------------------------------- 1 | /*//////////////////// 2 | adj[] is the main graph 3 | trans[] strores tranpose graph 4 | col[u] will store the component number where u belongs to 5 | ////////////////////*/ 6 | const int maxn = 1e5 + 10; 7 | vector adj[maxn], trans[maxn]; 8 | int col[maxn], vis[maxn], idx = 0, n, m; 9 | stack st; 10 | 11 | void dfs(int u) { 12 | vis[u] = 1; 13 | for(int v : adj[u]) if(!vis[v]) dfs(v); 14 | st.push(u); 15 | } 16 | void dfs2(int u) { 17 | col[u] = idx; 18 | for(int v : trans[u]) if(!col[v]) dfs2(v); 19 | } 20 | void scc() { 21 | for(int i = 1; i <= n; i++) 22 | if(!vis[i]) dfs(i); 23 | 24 | for(int u = 1; u <= n; u++) 25 | for(int v : adj[u]) 26 | trans[v].push_back(u); 27 | 28 | while(!st.empty()) { 29 | int u = st.top(); st.pop(); 30 | if(col[u]) continue; 31 | idx++; dfs2(u); 32 | } 33 | } -------------------------------------------------------------------------------- /Suffix Array.cpp: -------------------------------------------------------------------------------- 1 | const int N = 1e5 + 10; 2 | 3 | #define next asdfg 4 | 5 | char s[N]; 6 | int SA[N], iSA[N]; 7 | int cnt[N], next[N]; 8 | bool bh[N], b2h[N]; 9 | int lcp[N]; 10 | 11 | void buildSA(int n) { 12 | for(int i = 0; i < n; i++) SA[i] = i; 13 | sort(SA, SA + n, [](int i, int j) { return s[i] < s[j]; }); 14 | 15 | for(int i = 0; i < n; i++) { 16 | bh[i] = i == 0 || s[SA[i]] != s[SA[i - 1]]; 17 | b2h[i] = 0; 18 | } 19 | 20 | for(int h = 1; h < n; h <<= 1) { 21 | int tot = 0; 22 | for(int i = 0, j; i < n; i = j) { 23 | j = i + 1; 24 | while(j < n && !bh[j]) j++; 25 | next[i] = j; tot++; 26 | } if(tot == n) break; 27 | 28 | for(int i = 0; i < n; i = next[i]) { 29 | for(int j = i; j < next[i]; j++) 30 | iSA[SA[j]] = i; 31 | cnt[i] = 0; 32 | } 33 | 34 | cnt[iSA[n - h]]++; 35 | b2h[iSA[n - h]] = 1; 36 | for(int i = 0; i < n; i = next[i]) { 37 | for(int j = i; j < next[i]; j++) { 38 | int s = SA[j] - h; 39 | if(s < 0) continue; 40 | int head = iSA[s]; 41 | iSA[s] = head + cnt[head]++; 42 | b2h[iSA[s]] = 1; 43 | } 44 | for(int j = i; j < next[i]; j++) { 45 | int s = SA[j] - h; 46 | if(s < 0 || !b2h[iSA[s]]) continue; 47 | for(int k = iSA[s] + 1; !bh[k] && b2h[k]; k++) 48 | b2h[k] = 0; 49 | } 50 | } 51 | for(int i = 0; i < n; i++) { 52 | SA[iSA[i]] = i; 53 | bh[i] |= b2h[i]; 54 | } 55 | } 56 | for(int i = 0; i < n; i++) iSA[SA[i]] = i; 57 | } 58 | 59 | void buildLCP(int n) { 60 | for(int i = 0, k = 0; i < n; i++) { 61 | if(iSA[i] == n - 1) { k = 0; continue; } 62 | int j = SA[iSA[i] + 1]; 63 | while(i + k < n && j + k < n && s[i + k] == s[j + k]) ++k; 64 | lcp[iSA[i]] = k; 65 | if(k) k--; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Suffix Automata.cpp: -------------------------------------------------------------------------------- 1 | struct state { 2 | int len, link; 3 | unordered_map next; 4 | } t[2 * N]; 5 | 6 | int idx, last; 7 | 8 | void init() { 9 | t[0].len = 0; 10 | t[0].link = -1; 11 | t[0].next.clear(); 12 | idx = last = 0; 13 | } 14 | 15 | void extend(char c) { 16 | int cur = ++idx; 17 | t[cur].len = t[last].len + 1; 18 | t[cur].next.clear(); 19 | int p = last; 20 | while (p + 1 && !t[p].next.count(c)) { 21 | t[p].next[c] = cur; 22 | p = t[p].link; 23 | } 24 | if (p == -1) { 25 | t[cur].link = 0; 26 | } else { 27 | int q = t[p].next[c]; 28 | if (t[q].len == t[p].len + 1) { 29 | t[cur].link = q; 30 | } else { 31 | int clone = ++idx; 32 | t[clone] = t[q]; 33 | t[clone].len = t[p].len + 1; 34 | while (p + 1 && t[p].next[c] == q) { 35 | t[p].next[c] = clone; 36 | p = t[p].link; 37 | } 38 | t[q].link = t[cur].link = clone; 39 | } 40 | } 41 | last = cur; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /Treap (Basic Operations).cpp: -------------------------------------------------------------------------------- 1 | // Ordered Set 2 | // ---------------------------- 3 | #include 4 | #include 5 | using namespace __gnu_pbds; 6 | 7 | typedef tree< 8 | int, null_type, less, rb_tree_tag, 9 | tree_order_statistics_node_update> 10 | ordered_set; 11 | 12 | cout << *st.find_by_order(k) << endl; // k-th element, 0-indexed 13 | cout << st.order_of_key(x) << endl; // Number of elements < x 14 | //////////// 15 | 16 | struct node { 17 | int size, prior, key; 18 | node *l, *r; 19 | node(int v = 0) { 20 | size = 1; prior = rand(); key = v; 21 | l = r = NULL; 22 | } 23 | } *root; 24 | typedef node* pnode; 25 | 26 | int sz(pnode t) { 27 | return t ? t -> size : 0; 28 | } 29 | void upd_sz(pnode t) { 30 | if(t) t -> size = sz(t -> l) + sz(t -> r) + 1; 31 | } 32 | void split(pnode t, pnode &l, pnode &r, int k) { 33 | if(!t) l = r = NULL; 34 | else if(t -> key <= k) 35 | split(t -> r, t -> r, r, k), l = t; 36 | else split(t -> l, l, t -> l, k), r = t; 37 | upd_sz(t); 38 | } 39 | void merge(pnode &t, pnode l, pnode r) { 40 | if(!l || !r) t = l ? l : r; 41 | else if(l -> prior > r -> prior) 42 | merge(l -> r, l -> r, r), t = l; 43 | else merge(r -> l, l, r -> l), t = r; 44 | upd_sz(t); 45 | } 46 | void insert(pnode &t, pnode it) { 47 | if(!t) t = it; 48 | else if(t -> prior < it -> prior) 49 | split(t, it -> l, it -> r, it -> key), t = it; 50 | else insert(it -> key <= t -> key ? t -> l : t -> r, it); 51 | upd_sz(t); 52 | } 53 | void erase(pnode &t, int key) { 54 | if(!t) return; 55 | else if(t -> key == key) { 56 | pnode tmp = t; 57 | merge(t, t -> l, t -> r); 58 | free(tmp); 59 | } else erase(key <= t -> key ? t -> l : t -> r, key); 60 | upd_sz(t); 61 | } 62 | int countLess(int x) { 63 | pnode l, r; 64 | split(root, l, r, x-1); 65 | int ret = sz(l); 66 | merge(root, l, r); 67 | return ret; 68 | } 69 | int kth(pnode t, int k) { 70 | int cnt = sz(t -> l); 71 | if(cnt == k - 1) return t -> key; 72 | else if(cnt >= k) return kth(t -> l, k); 73 | else return kth(t -> r, k - cnt - 1); 74 | } 75 | void insert(int x) { 76 | insert(root, new node(x)); 77 | } 78 | bool find(pnode t, int key) { 79 | if(!t) return 0; 80 | if(t -> key == key) return 1; 81 | else if(key <= t -> key) return find(t -> l, key); 82 | else return find(t -> r, key); 83 | } -------------------------------------------------------------------------------- /Treap (Implict).cpp: -------------------------------------------------------------------------------- 1 | 2 | struct node { 3 | int prior, size; 4 | ll val, sum, lazy; 5 | node *l, *r; 6 | node(int v = 0) { 7 | val = sum = v; lazy = 0; 8 | prior = rand(); 9 | size = 1; 10 | l = r = NULL; 11 | } 12 | } *root; 13 | typedef node* pnode; 14 | 15 | int sz(pnode t) { return t ? t -> size : 0; } 16 | 17 | void upd_sz(pnode t) { 18 | if(t) t -> size = sz(t -> l) + 1 + sz(t -> r); 19 | } 20 | 21 | void push(pnode t) { 22 | if(!t || !t -> lazy) return; 23 | t -> val += t -> lazy; 24 | t -> sum += t -> lazy * sz(t); 25 | if(t -> l) t -> l -> lazy += t -> lazy; 26 | if(t -> r) t -> r -> lazy += t -> lazy; 27 | t -> lazy = 0; 28 | } 29 | void combine(pnode t) { // Note: This function should reset datas of t first (MUST!!) 30 | // Then update datas from l and r. 31 | if(!t) return; 32 | push(t -> l); push(t -> r); 33 | t -> sum = t -> val; // Reset 34 | if(t -> l) t -> sum += t -> l -> sum; 35 | if(t -> r) t -> sum += t -> r -> sum; 36 | } 37 | 38 | void split(pnode t, pnode &l, pnode &r, int pos, int add = 0) { 39 | if(!t) return void(l = r = NULL); 40 | push(t); 41 | int curr = sz(t -> l) + add; 42 | if(curr <= pos) 43 | split(t -> r, t -> r, r, pos, curr + 1), l = t; 44 | else split(t -> l, l, t -> l, pos, add), r = t; 45 | upd_sz(t); 46 | combine(t); 47 | } 48 | 49 | void merge(pnode &t, pnode l, pnode r) { 50 | push(l), push(r); 51 | if(!l || !r) t = l ? l : r; 52 | else if(l -> prior > r -> prior) 53 | merge(l -> r, l -> r, r), t = l; 54 | else merge(r -> l, l, r -> l), t = r; 55 | upd_sz(t); 56 | combine(t); 57 | } 58 | 59 | ll query(pnode t, int l, int r) { 60 | pnode L, mid, R; 61 | split(t, L, mid, l - 1); 62 | split(mid, t, R, r - l); 63 | ll ans = t -> sum; 64 | merge(mid, L, t); 65 | merge(t, mid, R); 66 | return ans; 67 | } 68 | 69 | void update(pnode t, int l, int r, ll v) { 70 | pnode L, mid, R; 71 | split(t, L, mid, l - 1); 72 | split(mid, t, R, r - l); 73 | t -> lazy += v; 74 | merge(mid, L, t); 75 | merge(t, mid, R); 76 | } 77 | 78 | void insert(pnode &t, int pos, int v) { 79 | pnode L, R, tmp, y = new node(v); 80 | split(t, L, R, pos - 1); 81 | merge(tmp, L, y); 82 | merge(t, tmp, R); 83 | } 84 | 85 | void Del(pnode &t, int pos) { 86 | pnode L, R, mid; 87 | split(t, L, mid, pos - 1); 88 | split(mid, t, R, 0); 89 | pnode tmp = t; 90 | merge(t, L, R); 91 | free(tmp); 92 | } -------------------------------------------------------------------------------- /Z-Algorithm.cpp: -------------------------------------------------------------------------------- 1 | void compute_z_function(const char *S, int N) { 2 | int L = 0, R = 0; 3 | for (int i = 1; i < N; ++i) { 4 | if (i > R) { 5 | L = R = i; 6 | while (R < N && S[R - L] == S[R]) ++R; 7 | Z[i] = R - L; --R; 8 | } else { 9 | int k = i - L; 10 | if (Z[k] < R - i + 1) Z[i] = Z[k]; 11 | else { 12 | L = i; 13 | while (R < N && S[R - k] == S[R]) ++R; 14 | Z[i] = R - L; --R; 15 | } 16 | } 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /maxHistrogram.cpp: -------------------------------------------------------------------------------- 1 | int largestRectangleArea(vector& h) { 2 | h.push_back(0); 3 | int ret = 0; 4 | stack st; 5 | 6 | for(int i = 0; i < h.size(); ++i) { 7 | while(st.size() && h[st.top()] >= h[i]) { 8 | int t = st.top(); st.pop(); 9 | ret = max(ret, h[t] * (st.size() ? i - st.top() - 1: i)); 10 | } 11 | st.push(i); 12 | } 13 | 14 | return ret; 15 | } -------------------------------------------------------------------------------- /nCr mod M.cpp: -------------------------------------------------------------------------------- 1 | /*/////////////////////////////////////////////////// 2 | C(n, r, M) calculates nCr mod M.. M is not necessarily prime! 3 | Idea: 4 | Factorize mod into p_0 ^ q_0 * p_1 ^ q_1 ..... 5 | Then calculate nCr \equiv a_i (mod p_i ^ q_i) by lucas modified! 6 | Then do CRT to calculate nCd mod(M) 7 | ////////////////////////////////////////////////////*/ 8 | 9 | ll Pow(ll n, ll p, ll mod) { 10 | if(!p) return 1; 11 | else if(p & 1) { 12 | return n*Pow(n,p-1, mod) % mod; 13 | } else { 14 | ll v = Pow(n, p/2, mod); 15 | return v*v % mod; 16 | } 17 | } 18 | ll Leg(ll n, ll p) { 19 | ll ans = 0; 20 | while(n) ans += n /= p; 21 | return ans; 22 | } 23 | vector factorize(ll n) { 24 | vector ret; 25 | for(int i=2; i*i<=n; i++) { 26 | if(n % i == 0) { 27 | int cnt = 0; 28 | while(n % i == 0) { 29 | n /= i; cnt++; 30 | } ret.push_back({i, cnt}); 31 | } 32 | } if(n > 1) ret.push_back({n,1}); 33 | return ret; 34 | } 35 | ll egcd(ll a, ll b, ll &x, ll &y) { 36 | if(!b) { x = 1, y = 0; return a; } 37 | ll ret = egcd(b, a%b, y,x); 38 | y -= (a/b)*x; 39 | return ret; 40 | } 41 | ll inv(ll n, ll mod) { 42 | ll x, y; 43 | ll gcd = egcd(n, mod, x,y); 44 | return (x+mod)%mod; 45 | } 46 | ll CRT(vector &a, vector &m) { 47 | ll M = 1, ret = 0; 48 | for(ll num : m) M *= num; 49 | for(int i = 0; i < a.size(); i++) { 50 | ll x = M / m[i]; 51 | ll add = ((a[i] * x) % M) * inv(x, m[i]) % M; 52 | ret = (ret + add) % M; 53 | } return ret; 54 | } 55 | 56 | ll s_fact[maxn]; 57 | ll spf(ll x, ll p, ll mod){ 58 | ll ret = Pow(s_fact[mod - 1], x / mod, mod); 59 | if (x >= p) ret = ret * spf(x / p, p, mod) % mod; 60 | return ret * s_fact[x % mod] % mod; 61 | } 62 | ll C_mod_p_q(ll n, ll r, ll p, ll q) { 63 | if(r > n) return 0; 64 | if(n == r || r == 0) return 1; 65 | ll M = Pow(p, q, 1e18); 66 | ll t = Leg(n, p) - Leg(r, p) - Leg(n-r, p); 67 | if(t >= q) return 0; 68 | s_fact[0] = 1; 69 | for(ll i = 1; i < M; i++) 70 | s_fact[i] = s_fact[i-1]*( (i%p) ? i : 1) % M; 71 | ll res = spf(n, p,M); 72 | res *= inv(spf(r,p,M) * spf(n-r, p, M) % M, M); 73 | res %= M; 74 | res *= Pow(p, t, M); 75 | return res % M; 76 | } 77 | ll C(ll n, ll r, int mod) { 78 | if(r > n || mod == 1) return 0; 79 | if(n == r || r == 0) return 1; 80 | vector ppf = factorize(mod); 81 | vector a, m; 82 | for(ii p : ppf) { 83 | ll pp = Pow(p.first, p.second, 1e7); 84 | ll aa = C_mod_p_q(n, r, p.first, p.second); 85 | a.push_back(aa); 86 | m.push_back(pp); 87 | } return CRT(a, m); 88 | } 89 | -------------------------------------------------------------------------------- /nextGreaterElement.cpp: -------------------------------------------------------------------------------- 1 | // O(n) 2 | vector nextGreaterElement(vector &arr) { 3 | int n = arr.size(); stack s; 4 | vector ret(n+1, n); 5 | for(int i=n-1; i>=0; i--) { 6 | while(!s.empty() && arr[s.top()] <= arr[i]) 7 | s.pop(); 8 | if(!s.empty()) ret[i] = s.top(); 9 | s.push(i); 10 | } return ret; 11 | } -------------------------------------------------------------------------------- /slidingRMQ.cpp: -------------------------------------------------------------------------------- 1 | //O(n) 2 | vector slidingRMQ(vector &arr, int k) { 3 | vector ret(arr.size(), 1e9); // ret[i] = minimum of arr[i, i+k-1] 4 | deque Q; 5 | for(int i=0; i arr[i]) 7 | Q.pop_back(); 8 | Q.push_back(arr[i]); 9 | if(i >= k && arr[i-k] == Q.front()) 10 | Q.pop_front(); 11 | if(i >= k-1) ret[i-k+1] = Q.front(); 12 | } return ret; 13 | } --------------------------------------------------------------------------------