├── Math ├── .gitkeep ├── Combinatorics.docx ├── Generating Functions and Polynomials.docx ├── Permanent of a Matrix.cpp ├── All Possible Perfect Matching XOR Values.cpp ├── Determinant of Product Matrix.cpp ├── Lagrange Multiplier.cpp ├── Max Convolution between Convex Funtions.cpp ├── Basis Vector.cpp ├── Determinant.cpp ├── Basis Vector ft Weighted Linearly Independent Vectors.cpp ├── Inverse of A Matrix modulo 2.cpp ├── Determinant under Prime Modulo.cpp ├── Determinant under Composite Modulo.cpp ├── Integration (Romberg).cpp ├── Integration (Simpsons).cpp ├── Gaussian Elimination.cpp └── Gaussian Elimination Modular.cpp ├── Geometry ├── .gitkeep] ├── Closest Pair of Points.cpp └── Maximum Area of Triangle, Given are Lengths.cpp ├── Strings ├── .gitkeep ├── Z Algorithm.cpp ├── String Matching using Bitsets.cpp ├── All Substring Longest Common Subsequence.cpp ├── De Bruijn Sequence.cpp ├── Manachers.cpp ├── KMP.cpp ├── Prefix Automaton.cpp ├── Cyclic LCS.cpp ├── Bit LCS.cpp ├── String Hashing 2D.cpp └── String Hashing.cpp ├── Game Theory └── .gitkeep ├── Graph Theory ├── .gitkeep ├── Tree and Graph Counting.docx ├── Floyd Warshall.cpp ├── Articulation Points.cpp ├── Krushkal's MST.cpp ├── Cycle Detection.cpp ├── Number of Different Cliques.cpp ├── SPFA.cpp ├── Bellman Ford.cpp ├── Chromatic Number.cpp ├── Inverse Graph.cpp ├── Prim's MST.cpp ├── LCA.cpp ├── DAG Reachability Dynamic.cpp ├── SCC.cpp ├── Min Cut in a Planar Graph.cpp ├── Minimum Weight Cycle For Each Vertex.cpp ├── HopCroft Karp Algorithm.cpp ├── Dijkstra.cpp ├── Minimum Mean Weight Cycle.cpp ├── Randomized Matching Unweighted.cpp ├── LCA in O(1).cpp ├── Maximum Clique.cpp ├── Stable Marriage Problem.cpp ├── Euler Path Directed.cpp ├── Tuttes Theorem.cpp ├── Articulation Bridges.cpp ├── Prufer Code.cpp ├── 3 CYCLE and 4 CYCLE.cpp ├── Tree Orientation.cpp ├── Dinics Algorithm.cpp ├── Stoer Wagner Algorithm.cpp ├── Dijkstra on Segment Tree.cpp └── Steiner Tree Problem.cpp ├── Miscellaneous ├── .gitkeep ├── Gray Code.cpp ├── Knight Moves in Infinity Grid.cpp ├── Josephus Problem.cpp ├── Dates.cpp ├── Fraction Binary Search.cpp └── Subset Union of Bitsets.cpp ├── Number Theory ├── .gitkeep ├── Rational Approximation.py ├── Phi Function.cpp ├── Sieve.cpp ├── Sum of Floors.cpp ├── Extended Euclid.cpp ├── Fibonacci Number Faster.cpp ├── Number of Nonnegative Integer Solutions to ax+by <= c.cpp ├── CRT.cpp ├── Linear Congruence Equation.cpp ├── Floor Sum of Arithmetic Progressions.cpp ├── Sum of Arithmetic Progression Modular and Divided.cpp ├── Linear Sieve for Multiplicative Functions.cpp ├── Continued Fractions.cpp ├── Power Tower.cpp ├── Maximum Coprime Product.cpp ├── Mobius Function.cpp ├── Intersection of Arithmetic Progressions.cpp ├── Rational Approximation.cpp ├── Number of Distinct Kth Powers Modulo n.cpp ├── Tonelli Shanks Algorithm.cpp ├── Primitive Root.cpp ├── Pells Equation.py ├── Number of ax%p in a Range.cpp ├── Linear Diophantine Equation with Nonnegative Solutions.cpp ├── Fermats Theorem on Sum of Two Squares.cpp ├── LCM of Fibonacci Numbers.cpp ├── Multiplicative Order.cpp ├── Discrete Log.cpp ├── Sum of The Number of Divisors in cbrt(n).cpp ├── Smallest Nonnegative Integer x s.t. l <= ax % p <= r.cpp ├── Linear Diophantine With N Unknowns and Two Equations.cpp └── Smallest Number Having Exactly K Divisors.cpp ├── Data Structures ├── .gitkeep ├── Venice Technique.cpp ├── Monotonous Queue.cpp ├── BIT.cpp ├── BST using STL.cpp ├── Ordered Set.cpp ├── Sparse Table.cpp ├── DSU.cpp ├── BIT with Range Update and Range Query.cpp ├── DSU on Tree.cpp ├── Segment Tree NonRecursive.cpp ├── Segment Tree.cpp ├── LCA.cpp ├── Segment Tree Lazy.cpp ├── Divide and Conquer for Insert and Query Problems.cpp ├── Augmented DSU.cpp ├── MOs Algorithm.cpp ├── Persistent Trie.cpp ├── Interval Set.cpp ├── Segment Tree Persistent.cpp ├── DSU Partially Persistent.cpp ├── Disjoint Sparse Table.cpp ├── MOs with Update.cpp ├── Trie.cpp └── BIT 2D with Range Update and Range Query.cpp ├── Dynamic Programming Optimizations ├── .gitkeep ├── Persistent CHT.cpp ├── Number of Subsequences Having Product at least K.cpp ├── Bounded Knapsack.cpp ├── DP Over Divisors.cpp ├── Connected Component DP.cpp ├── Digit DP.cpp ├── Subset Union of Bitsets.cpp ├── Knuth Optimization.cpp ├── Divide and Conquer Optimization.cpp ├── Convex Hull Trick.cpp ├── Dynamic Convex Hull Trick.cpp └── 1D1D DP.cpp ├── Guidelines.md └── LICENSE.txt /Math/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Geometry/.gitkeep]: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Strings/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Game Theory/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Graph Theory/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Miscellaneous/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Number Theory/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Data Structures/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Dynamic Programming Optimizations/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Math/Combinatorics.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/H-K-R/code-library/HEAD/Math/Combinatorics.docx -------------------------------------------------------------------------------- /Graph Theory/Tree and Graph Counting.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/H-K-R/code-library/HEAD/Graph Theory/Tree and Graph Counting.docx -------------------------------------------------------------------------------- /Math/Generating Functions and Polynomials.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/H-K-R/code-library/HEAD/Math/Generating Functions and Polynomials.docx -------------------------------------------------------------------------------- /Number Theory/Rational Approximation.py: -------------------------------------------------------------------------------- 1 | from fractions import Fraction 2 | x = 3232.45622121 3 | # gets the closest rational number to x where denominator is limited 4 | p = Fraction(x).limit_denominator(2323) 5 | print(p) -------------------------------------------------------------------------------- /Guidelines.md: -------------------------------------------------------------------------------- 1 | 1. I almost always use 1-indexing and inclusive ranges unless mentioned otherwise. That means wherever I have used 0-indexing or exclusive ranges I have commented them out explicitly. 2 | 2. If you find something wrong, then please create an issue or contact me at https://codeforces.com/profile/YouKn0wWho 3 | -------------------------------------------------------------------------------- /Miscellaneous/Gray Code.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int g (int n) { 5 | return n ^ (n >> 1); 6 | } 7 | int rev_g (int g) { 8 | int n = 0; 9 | for (; g; g >>= 1) 10 | n ^= g; 11 | return n; 12 | } 13 | 14 | // property: g(i) = g(i - 1) ^ (1 << lsb(i)) 15 | int32_t main() { 16 | ios_base::sync_with_stdio(0); 17 | cin.tie(0); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /Miscellaneous/Knight Moves in Infinity Grid.cpp: -------------------------------------------------------------------------------- 1 | #define ll long long int 2 | // Minimum number of knight moves from (x,y) to 3 | // (0,0) in non-negative infinite chessboard 4 | ll knight_move(ll x, ll y) { 5 | ll cnt = max({(x + 1) / 2, (y + 1) / 2, (x + y + 2) / 3}); 6 | while((cnt % 2) != (x + y) % 2) cnt++; 7 | if(x == 1 && !y) return 3; 8 | if(y == 1 && !x) return 3; 9 | if(x == y && x == 2) return 4; 10 | return cnt; 11 | } 12 | -------------------------------------------------------------------------------- /Miscellaneous/Josephus Problem.cpp: -------------------------------------------------------------------------------- 1 | // n = total person 2 | // will kill every kth person, if k = 2, 2,4,6,... 3 | // returns the mth killed person 4 | ll josephus(ll n, ll k, ll m) { 5 | m = n - m; 6 | if (k <= 1)return n - m; 7 | ll i = m; 8 | while (i < n) { 9 | ll r = (i - m + k - 2) / (k - 1); 10 | if ((i + r) > n) r = n - i; 11 | else if (!r) r = 1; 12 | i += r; 13 | m = (m + (r * k)) % i; 14 | } return m + 1; 15 | } 16 | -------------------------------------------------------------------------------- /Number Theory/Phi Function.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1e5 + 9; 5 | int phi[N]; 6 | void totient() { 7 | for (int i = 1; i < N; i++) phi[i] = i; 8 | for (int i = 2; i < N; i++) { 9 | if (phi[i] == i) { 10 | for (int j = i; j < N; j += i) phi[j] -= phi[j] / i; 11 | } 12 | } 13 | } 14 | int32_t main() { 15 | ios_base::sync_with_stdio(0); 16 | cin.tie(0); 17 | 18 | return 0; 19 | } -------------------------------------------------------------------------------- /Data Structures/Venice Technique.cpp: -------------------------------------------------------------------------------- 1 | template struct PQ { 2 | long long sum = 0; 3 | priority_queue, greater> Q; 4 | void push(T x) { x.w -= sum; Q.push(x); } 5 | T pop() { auto ans = Q.top(); Q.pop(); ans.w += sum; return ans; } 6 | int size() { return Q.size(); } 7 | void add(long long x) { sum += x; } 8 | void merge(PQ &&x) { 9 | if (size() < x.size()) swap(sum, x.sum), swap(Q, x.Q); 10 | while (x.size()) { 11 | auto tmp = x.pop(); 12 | tmp.w -= sum; 13 | Q.push(tmp); 14 | } 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /Graph Theory/Floyd Warshall.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 105; 5 | int d[N][N]; 6 | int main() { 7 | int n = 10; 8 | for (int i = 1; i <= n; i++) { 9 | for (int j = 1; j <= n; j++) { 10 | if (i != j) { 11 | d[i][j] = 1e9; 12 | } 13 | } 14 | } 15 | for (int k = 1; k <= n; ++k) { 16 | for (int i = 1; i <= n; ++i) { 17 | for (int j = 1; j <= n; ++j) { 18 | d[i][j] = min(d[i][j], d[i][k] + d[k][j]); 19 | } 20 | } 21 | } 22 | return 0; 23 | } -------------------------------------------------------------------------------- /Number Theory/Sieve.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1e5 + 9; 5 | 6 | int spf[N]; 7 | vector primes; 8 | void sieve() { 9 | for(int i = 2; i < N; i++) { 10 | if (spf[i] == 0) spf[i] = i, primes.push_back(i); 11 | int sz = primes.size(); 12 | for (int j = 0; j < sz && i * primes[j] < N && primes[j] <= spf[i]; j++) { 13 | spf[i * primes[j]] = primes[j]; 14 | } 15 | } 16 | } 17 | 18 | int32_t main() { 19 | ios_base::sync_with_stdio(0); 20 | cin.tie(0); 21 | 22 | return 0; 23 | } -------------------------------------------------------------------------------- /Number Theory/Sum of Floors.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | using ll = long long; 5 | 6 | // \sum{k=1}^{n}{floor(n/k)} 7 | // count of numbers such that n/i = k -> n/k - n/(k+1) 8 | ll floor_sum(ll n) { 9 | ll sum = 0; 10 | for (ll i = 1, last; i <= n; i = last + 1) { 11 | last = n / (n / i); 12 | sum += (n / i) * (last - i + 1); 13 | // n / x yields the same value for i <= x <= last. 14 | } 15 | return sum; 16 | } 17 | int32_t main() { 18 | ios_base::sync_with_stdio(0); 19 | cin.tie(0); 20 | return 0; 21 | } -------------------------------------------------------------------------------- /Miscellaneous/Dates.cpp: -------------------------------------------------------------------------------- 1 | int intToDay(int jd) { return jd % 7; } 2 | int dateToInt(int y, int m, int d) { 3 | return 1461 * (y + 4800 + (m - 14) / 12) / 4 + 4 | 367 * (m - 2 - (m - 14) / 12 * 12) / 12 - 5 | 3 * ((y + 4900 + (m - 14) / 12) / 100) / 4 + 6 | d - 32075; 7 | } 8 | void intToDate(int jd, int &y, int &m, int &d) { 9 | int x, n, i, j; 10 | x = jd + 68569; 11 | n = 4 * x / 146097; 12 | x -= (146097 * n + 3) / 4; 13 | i = (4000 * (x + 1)) / 1461001; 14 | x -= 1461 * i / 4 - 31; 15 | j = 80 * x / 2447; 16 | d = x - 2447 * j / 80; 17 | x = j / 11; 18 | m = j + 2 - 12 * x; 19 | y = 100 * (n - 49) + i + x; 20 | } 21 | -------------------------------------------------------------------------------- /Number Theory/Extended Euclid.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | using ll = long long; 5 | ll extended_euclid(ll a, ll b, ll &x, ll &y) { 6 | if (b == 0) { 7 | x = 1; y = 0; 8 | return a; 9 | } 10 | ll x1, y1; 11 | ll d = extended_euclid(b, a % b, x1, y1); 12 | x = y1; 13 | y = x1 - y1 * (a / b); 14 | return d; 15 | } 16 | ll inverse(ll a, ll m) { 17 | ll x, y; 18 | ll g = extended_euclid(a, m, x, y); 19 | if (g != 1) return -1; 20 | return (x % m + m) % m; 21 | } 22 | int32_t main() { 23 | ios_base::sync_with_stdio(0); 24 | cin.tie(0); 25 | ll x = 100, m = 37; 26 | cout << inverse(x, m) << '\n'; 27 | return 0; 28 | } -------------------------------------------------------------------------------- /Number Theory/Fibonacci Number Faster.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int fib(long long n, int mod) { 5 | assert (n >= 0); 6 | if (n <= 1) return n; 7 | int a = 0, b = 1; 8 | long long i = 1ll << (63 - __builtin_clzll(n) - 1); 9 | for (; i; i >>= 1) { 10 | int na = (a *(long long) a + b *(long long) b) % mod; 11 | int nb = (2ll * a + b) * b % mod; 12 | a = na; b = nb; 13 | if (n & i) { 14 | int c = a + b; if (c >= mod) c -= mod; 15 | a = b; b = c; 16 | } 17 | } 18 | return b; 19 | } 20 | int32_t main() { 21 | ios_base::sync_with_stdio(0); 22 | cin.tie(0); 23 | cout << fib(10, 100) << '\n'; 24 | return 0; 25 | } -------------------------------------------------------------------------------- /Data Structures/Monotonous Queue.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9; 5 | 6 | struct monotonous_queue { //max, stores strictly decreasing sequence of the current queue 7 | int a[N + 10], b[N + 10], l = 0, r = -1; 8 | void push(int val) { 9 | int cnt = 0; 10 | while(l <= r && a[r] <= val) { 11 | cnt += b[r] + 1; 12 | r--; 13 | } 14 | a[++r] = val, b[r] = cnt; 15 | }; 16 | int top() { 17 | return a[l]; 18 | } 19 | void pop() { 20 | if(l > r) return; 21 | if (b[l] > 0) { 22 | b[l] --; 23 | return; 24 | } 25 | l++; 26 | } 27 | }; 28 | 29 | int32_t main() { 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /Data Structures/BIT.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9; 5 | 6 | template 7 | struct BIT { //1-indexed 8 | int n; vector t; 9 | BIT() {} 10 | BIT(int _n) { 11 | n = _n; t.assign(n + 1, 0); 12 | } 13 | T query(int i) { 14 | T ans = 0; 15 | for (; i >= 1; i -= (i & -i)) ans += t[i]; 16 | return ans; 17 | } 18 | void upd(int i, T val) { 19 | if (i <= 0) return; 20 | for (; i <= n; i += (i & -i)) t[i] += val; 21 | } 22 | void upd(int l, int r, T val) { 23 | upd(l, val); 24 | upd(r + 1, -val); 25 | } 26 | T query(int l, int r) { 27 | return query(r) - query(l - 1); 28 | } 29 | }; 30 | int32_t main() { 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /Math/Permanent of a Matrix.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 20; 5 | 6 | long long dp[1 << N]; 7 | int n, a[N][N]; 8 | int32_t main() { 9 | ios_base::sync_with_stdio(0); 10 | cin.tie(0); 11 | int t; cin >> t; 12 | while (t--) { 13 | cin >> n; 14 | for (int i = 0; i < n; i++) { 15 | for (int j = 0; j < n; j++) cin >> a[i][j]; 16 | } 17 | memset(dp, 0, sizeof dp); 18 | dp[(1 << n) - 1] = 1; 19 | for (int mask = (1 << n) - 2; mask >= 0; mask--) { 20 | int i = __builtin_popcount(mask); 21 | for (int j = 0; j < n; j++) if (!(mask >> j & 1)) dp[mask] += dp[mask | 1 << j] * a[i][j]; 22 | } 23 | cout << dp[0] << '\n'; // permanent of the matrix 24 | } 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /Data Structures/BST using STL.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9; 5 | 6 | //the code returns a BST which will create if we add the values one by one 7 | //here nodes are indicated by values and every node must be distinct 8 | setse; 9 | mapl, r; //l contains the left child of the node, r contains right child of the node 10 | int main() { 11 | int n; 12 | cin >> n; 13 | int k; 14 | cin >> k; //root of the tree 15 | se.insert(k); 16 | for(int i = 1; i < n; i++) { 17 | int k; 18 | cin >> k; 19 | auto it = se.upper_bound(k); 20 | if(it != se.end() && l.find(*it) == l.end()) l[*it] = k; 21 | else --it, r[*it] = k; 22 | se.insert(k); 23 | } 24 | for(int i = 1; i <= n; i++) cout << l[i] << ' ' << r[i] << '\n'; 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /Strings/Z Algorithm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // An element Z[i] of Z array stores length of the longest substring 5 | // starting from str[i] which is also a prefix of str[0..n-1]. 6 | // The first entry of Z array is meaning less as complete string is always prefix of itself. 7 | // Here Z[0]=0. 8 | vector z_function(string s) { 9 | int n = (int) s.length(); 10 | vector z(n); 11 | for (int i = 1, l = 0, r = 0; i < n; ++i) { 12 | if (i <= r) 13 | z[i] = min (r - i + 1, z[i - l]); 14 | while (i + z[i] < n && s[z[i]] == s[i + z[i]]) 15 | ++z[i]; 16 | if (i + z[i] - 1 > r) 17 | l = i, r = i + z[i] - 1; 18 | } 19 | return z; 20 | } 21 | int32_t main() { 22 | string s; 23 | cin >> s; 24 | vector ans = z_function(s); 25 | for(auto x : ans) cout << x << ' '; 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Data Structures/Ordered Set.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace __gnu_pbds; 5 | using namespace std; 6 | 7 | template using o_set = tree, rb_tree_tag, tree_order_statistics_node_update>; 8 | template using o_map = tree, rb_tree_tag, tree_order_statistics_node_update>; 9 | int main() { 10 | int i, j, k, n, m; 11 | o_setse; 12 | se.insert(1); 13 | se.insert(2); 14 | cout << *se.find_by_order(0) << endl; ///k th element 15 | cout << se.order_of_key(2) << endl; ///number of elements less than k 16 | o_mapmp; 17 | mp.insert({1, 10}); 18 | mp.insert({2, 20}); 19 | cout << mp.find_by_order(0)->second << endl; ///k th element 20 | cout << mp.order_of_key(2) << endl; ///number of first elements less than k 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /Data Structures/Sparse Table.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1e5 + 9; 5 | 6 | int t[N][18], a[N]; 7 | void build(int n) { 8 | for(int i = 1; i <= n; ++i) t[i][0] = a[i]; 9 | for(int k = 1; k < 18; ++k) { 10 | for(int i = 1; i + (1 << k) - 1 <= n; ++i) { 11 | t[i][k] = min(t[i][k - 1], t[i + (1 << (k - 1))][k - 1]); 12 | } 13 | } 14 | } 15 | 16 | int query(int l, int r) { 17 | int k = 31 - __builtin_clz(r - l + 1); 18 | return min(t[l][k], t[r - (1 << k) + 1][k]); 19 | } 20 | 21 | int32_t main() { 22 | ios_base::sync_with_stdio(0); 23 | cin.tie(0); 24 | 25 | int n; 26 | cin >> n; 27 | for(int i = 1; i <= n; i++) cin >> a[i]; 28 | build(n); 29 | int q; 30 | cin >> q; 31 | while(q--) { 32 | int l, r; 33 | cin >> l >> r; 34 | ++l; 35 | ++r; 36 | cout << query(l, r) << '\n'; 37 | } 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /Data Structures/DSU.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9; 5 | 6 | struct DSU { 7 | vector par, rnk, sz; 8 | int c; 9 | DSU(int n) : par(n + 1), rnk(n + 1, 0), sz(n + 1, 1), c(n) { 10 | for (int i = 1; i <= n; ++i) par[i] = i; 11 | } 12 | int find(int i) { 13 | return (par[i] == i ? i : (par[i] = find(par[i]))); 14 | } 15 | bool same(int i, int j) { 16 | return find(i) == find(j); 17 | } 18 | int get_size(int i) { 19 | return sz[find(i)]; 20 | } 21 | int count() { 22 | return c; //connected components 23 | } 24 | int merge(int i, int j) { 25 | if ((i = find(i)) == (j = find(j))) return -1; 26 | else --c; 27 | if (rnk[i] > rnk[j]) swap(i, j); 28 | par[i] = j; 29 | sz[j] += sz[i]; 30 | if (rnk[i] == rnk[j]) rnk[j]++; 31 | return j; 32 | } 33 | }; 34 | 35 | int32_t main() { 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /Data Structures/BIT with Range Update and Range Query.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9; 5 | 6 | struct BIT { 7 | long long M[N], A[N]; 8 | BIT() { 9 | memset(M, 0, sizeof M); 10 | memset(A, 0, sizeof A); 11 | } 12 | void update(int i, long long mul, long long add) { 13 | while (i < N) { 14 | M[i] += mul; 15 | A[i] += add; 16 | i |= (i + 1); 17 | } 18 | } 19 | void upd(int l, int r, long long x) { 20 | update(l, x, -x * (l - 1)); 21 | update(r, -x, x * r); 22 | } 23 | long long query(int i) { 24 | long long mul = 0, add = 0; 25 | int st = i; 26 | while (i >= 0) { 27 | mul += M[i]; 28 | add += A[i]; 29 | i = (i & (i + 1)) - 1; 30 | } 31 | return (mul * st + add); 32 | } 33 | long long query(int l, int r) { 34 | return query(r) - query(l - 1); 35 | } 36 | } t; 37 | 38 | int32_t main() { 39 | 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /Number Theory/Number of Nonnegative Integer Solutions to ax+by <= c.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | using ll = long long; 5 | 6 | // number of integer solutions to ax + by <= c s.t. x, y >= 0 7 | // number of nonnegative integer lattice points under or on the line ax + by = c 8 | ll lattice_cnt(ll a, ll b, ll c) { 9 | assert(a >= 0 && b >= 0); 10 | if (c < 0) return 0; 11 | if (a == 0 or b == 0) { 12 | // infinite solutions 13 | assert(0); 14 | return -1; 15 | } 16 | assert(a > 0 && b > 0); 17 | if (a > b) swap(a, b); 18 | ll ans = 0; 19 | while (c >= 0) { 20 | ll k = b / a; 21 | ll l = b % a; 22 | ll f = c / b; 23 | ll e = c % b / a; 24 | ll g = c % b % a; 25 | ans += (f + 1) * (e + 1) + (f + 1) * f / 2 * k; 26 | c = f * l - a + g; 27 | b = a; 28 | a = l; 29 | } 30 | return ans; 31 | } 32 | int32_t main() { 33 | ios_base::sync_with_stdio(0); 34 | cin.tie(0); 35 | cout << lattice_cnt(2, 3, 5) << '\n'; 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021 Shahjalal Shohag 2 | License: MIT 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | -------------------------------------------------------------------------------- /Strings/String Matching using Bitsets.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1e5 + 9; 5 | vector v; 6 | bitsetbs[26], oc; 7 | int main() { 8 | int i, j, k, n, q, l, r; 9 | string s, p; 10 | cin >> s; 11 | for(i = 0; s[i]; i++) bs[s[i] - 'a'][i] = 1; 12 | cin >> q; 13 | while(q--) { 14 | cin >> p; 15 | oc.set(); 16 | for(i = 0; p[i]; i++) oc &= (bs[p[i] - 'a'] >> i); 17 | cout << oc.count() << endl; // number of occurences 18 | int ans = N, sz = p.size(); 19 | int pos = oc._Find_first(); 20 | v.push_back(pos); 21 | pos = oc._Find_next(pos); 22 | while(pos < N) { 23 | v.push_back(pos); 24 | pos = oc._Find_next(pos); 25 | } 26 | for(auto x : v) cout << x << ' '; // position of occurences 27 | cout << endl; 28 | v.clear(); 29 | cin >> l >> r; // number of occurences from l to r,where l and r is 1-indexed 30 | if(sz > r - l + 1) cout << 0 << endl; 31 | else cout << (oc >> (l - 1)).count() - (oc >> (r - sz + 1)).count() << endl; 32 | } 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /Math/All Possible Perfect Matching XOR Values.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1030; 5 | 6 | int a[N][N], p[N], n, vis[N]; 7 | void yo(int cur) { 8 | if (vis[cur]) return; 9 | vis[cur] = 1; 10 | for (int i = 1; i <= n; i++) { 11 | for (int j = i + 1; j <= n; j++) { 12 | int nxt = cur ^ a[i][p[i]] ^ a[j][p[j]] ^ a[i][p[j]] ^ a[j][p[i]]; 13 | swap(p[i], p[j]); 14 | yo(nxt); 15 | swap(p[i], p[j]); 16 | } 17 | } 18 | } 19 | int32_t main() { 20 | ios_base::sync_with_stdio(0); 21 | cin.tie(0); 22 | int t; cin >> t; 23 | while (t--) { 24 | cin >> n; 25 | int cur = 0; 26 | for (int i = 1; i <= n; i++) { 27 | for (int j = 1; j <= n; j++) { 28 | cin >> a[i][j]; 29 | if (i == j) p[i] = i, cur ^= a[i][i]; 30 | } 31 | } 32 | memset(vis, 0, sizeof vis); 33 | yo(cur); 34 | for (int i = 0; i < N; i++) if (vis[i]) cout << i << ' '; 35 | cout << '\n'; 36 | } 37 | return 0; 38 | } 39 | //https://www.codechef.com/problems/CHEFLST -------------------------------------------------------------------------------- /Number Theory/CRT.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | using T = __int128; 5 | // ax + by = __gcd(a, b) 6 | // returns __gcd(a, b) 7 | T extended_euclid(T a, T b, T &x, T &y) { 8 | T xx = y = 0; 9 | T yy = x = 1; 10 | while (b) { 11 | T q = a / b; 12 | T t = b; b = a % b; a = t; 13 | t = xx; xx = x - q * xx; x = t; 14 | t = yy; yy = y - q * yy; y = t; 15 | } 16 | return a; 17 | } 18 | // finds x such that x % m1 = a1, x % m2 = a2. m1 and m2 may not be coprime 19 | // here, x is unique modulo m = lcm(m1, m2). returns (x, m). on failure, m = -1. 20 | pair CRT(T a1, T m1, T a2, T m2) { 21 | T p, q; 22 | T g = extended_euclid(m1, m2, p, q); 23 | if (a1 % g != a2 % g) return make_pair(0, -1); 24 | T m = m1 / g * m2; 25 | p = (p % m + m) % m; 26 | q = (q % m + m) % m; 27 | return make_pair((p * a2 % m * (m1 / g) % m + q * a1 % m * (m2 / g) % m) % m, m); 28 | } 29 | 30 | int32_t main() { 31 | ios_base::sync_with_stdio(0); 32 | cin.tie(0); 33 | cout << (int)CRT(1, 31, 0, 7).first << '\n'; 34 | return 0; 35 | } -------------------------------------------------------------------------------- /Strings/All Substring Longest Common Subsequence.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 2002; 5 | int f[N][N], g[N][N]; 6 | int32_t main() { 7 | ios_base::sync_with_stdio(0); 8 | cin.tie(0); 9 | string s, t; cin >> s >> t; 10 | int n = s.size(), m = t.size(); 11 | s = "#" + s; 12 | t = "#" + t; 13 | for (int i = 1; i <= m; ++i) f[0][i] = i; 14 | for (int i = 1; i <= n; ++i) { 15 | for (int j = 1; j <= m; ++j) { 16 | if (s[i] == t[j]) { 17 | f[i][j] = g[i][j - 1]; 18 | g[i][j] = f[i - 1][j]; 19 | } 20 | else { 21 | f[i][j] = max(f[i - 1][j], g[i][j - 1]); 22 | g[i][j] = min(g[i][j - 1], f[i - 1][j]); 23 | } 24 | } 25 | } 26 | for (int i = 1; i <= m; ++i) { 27 | for (int j = i, ans = 0; j <= m; ++j) { 28 | if (i > f[n][j]) ++ans; 29 | cout << ans << ' '; //lcs of s and t[i, j] 30 | } 31 | cout << '\n'; 32 | } 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /Graph Theory/Articulation Points.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9; 5 | 6 | int T, low[N], dis[N], art[N]; 7 | vector g[N]; 8 | void dfs(int u, int pre = 0) { 9 | low[u] = dis[u] = ++T; 10 | int child = 0; 11 | for(auto v: g[u]) { 12 | if(!dis[v]) { 13 | dfs(v, u); 14 | low[u] = min(low[u], low[v]); 15 | if(low[v] >= dis[u] && pre != 0) art[u] = 1; 16 | ++child; 17 | } 18 | else if(v != pre) low[u] = min(low[u], dis[v]); 19 | } 20 | if(pre == 0 && child > 1) art[u] = 1; 21 | } 22 | int32_t main() { 23 | ios_base::sync_with_stdio(0); 24 | cin.tie(0); 25 | while(1){ 26 | int n, m; cin >> n >> m; 27 | if(!n) break; 28 | while(m--) { 29 | int u, v; cin >> u >> v; 30 | g[u].push_back(v); 31 | g[v].push_back(u); 32 | } 33 | dfs(1); 34 | int ans = 0; 35 | for(int i = 1; i <= n; i++) ans += art[i]; 36 | cout << ans << '\n'; 37 | T = 0; for(int i = 1; i <= n; i++) low[i] = dis[i] = art[i] = 0, g[i].clear(); 38 | } 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /Math/Determinant of Product Matrix.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int mod = 1e9 + 7; 5 | 6 | // Given two arrays and x 7 | // Matrix M(i, j) = a(i) * b(j) if i != j, (x + a(i) * b(j)) if i == j 8 | // Find the determinant 9 | // Solution = x^n + x^(n - 1) * sum_of(a(i) * b(i)) 10 | 11 | int32_t main() { 12 | ios_base::sync_with_stdio(0); 13 | cin.tie(0); 14 | int n, x; 15 | while (cin >> n >> x) { 16 | vector a(n), b(n); 17 | for (int i = 0; i < n; i++) { 18 | cin >> a[i]; 19 | } 20 | for (int i = 0; i < n; i++) { 21 | cin >> b[i]; 22 | } 23 | int ans = 0; 24 | for (int i = 0; i < n; i++) { 25 | ans += 1LL * a[i] * b[i] % mod; 26 | ans %= mod; 27 | } 28 | int p = x; 29 | for (int i = 0; i + 1 < n; i++) { 30 | ans = 1LL * ans * x % mod; 31 | p = 1LL * p * x % mod; 32 | } 33 | ans = (ans + p) % mod; 34 | cout << ans << '\n'; 35 | } 36 | return 0; 37 | } 38 | // https://official.contest.yandex.ru/opencupXXI/contest/23124/problems/D/?success=43031828#7/2020_11_27/m1N1edUCxn -------------------------------------------------------------------------------- /Data Structures/DSU on Tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1e5 + 9; 5 | vector g[N]; 6 | int ans[N], col[N], sz[N], cnt[N]; 7 | bool big[N]; 8 | void dfs(int u, int p) { 9 | sz[u] = 1; 10 | for (auto v : g[u]) { 11 | if (v == p) continue; 12 | dfs(v, u); 13 | sz[u] += sz[v]; 14 | } 15 | } 16 | void add(int u, int p, int x) { 17 | cnt[col[u]] += x; 18 | for (auto v : g[u]) { 19 | if (v == p || big[v] == 1) continue; 20 | add(v, u, x); 21 | } 22 | } 23 | void dsu(int u, int p, bool keep) { 24 | int bigchild = -1, mx = -1; 25 | for (auto v : g[u]) { 26 | if (v == p) continue; 27 | if (sz[v] > mx) mx = sz[v], bigchild = v; 28 | } 29 | for (auto v : g[u]) { 30 | if (v == p || v == bigchild) continue; 31 | dsu(v, u, 0); 32 | } 33 | if (bigchild != -1) dsu(bigchild, u, 1), big[bigchild] = 1; 34 | add(u, p, 1); 35 | ans[u] = cnt[u]; 36 | if (bigchild != -1) big[bigchild] = 0; 37 | if (keep == 0) add(u, p, -1); 38 | } 39 | 40 | int32_t main() { 41 | ios_base::sync_with_stdio(0); 42 | cin.tie(0); 43 | int t; 44 | cin >> t; 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /Math/Lagrange Multiplier.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1010; 5 | 6 | double p[N]; 7 | int b[N], c[N]; 8 | int32_t main() { 9 | ios_base::sync_with_stdio(0); 10 | cin.tie(0); 11 | int n; cin >> n; 12 | int tot = 0; 13 | for (int i = 1; i <= n; i++) { 14 | cin >> b[i]; 15 | tot += b[i]; 16 | } 17 | int sum = 0; 18 | for (int i = 1; i <= n; i++) { 19 | cin >> c[i]; 20 | sum += c[i]; 21 | } 22 | for (int i = 1; i <= n; i++) { 23 | p[i] = 1.0 * c[i] / sum; 24 | } 25 | double l = 0, r = 2e6; 26 | int it = 100; 27 | while (it--) { 28 | double mid = (l + r) * 0.5; 29 | double sum = 0; 30 | for (int i = 1; i <= n; i++) { 31 | sum += sqrt(p[i] * b[i] / mid); 32 | } 33 | if (sum <= 1) { 34 | r = mid; 35 | } 36 | else { 37 | l = mid; 38 | } 39 | } 40 | cout << fixed << setprecision(10) << tot << ' ' << l << '\n'; 41 | for (int i = 1; i <= n; i++) { 42 | cout << fixed << setprecision(10) << sqrt(p[i] * b[i] / l) << ' '; 43 | } 44 | return 0; 45 | } 46 | // https://toph.co/p/betting-business -------------------------------------------------------------------------------- /Math/Max Convolution between Convex Funtions.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // a[i + 1] - a[i] >= a[i] - a[i - 1] -> convex 5 | // b[i + 1] - b[i] >= b[i] - b[i - 1] -> convex 6 | // compute ans(i + j) = max(a(i) + b(j)) 7 | vector multiply(vector a, vector b) { 8 | int n = a.size() - 1, m = b.size() - 1; 9 | vector ans(n + m + 1); 10 | int sum = a[0] + b[0]; ans[0] = sum; 11 | int l = 0, r = 0; 12 | while (l < n && r < m) { 13 | if (a[l + 1] - a[l] > b[r + 1] - b[r]) { 14 | sum += a[l + 1] - a[l]; 15 | l++; 16 | } else { 17 | sum += b[r + 1] - b[r]; 18 | r++; 19 | } 20 | ans[l + r] = sum; 21 | } 22 | while (l < n) sum += a[l + 1] - a[l], l++, ans[l + r] = sum; 23 | while (r < m) sum += b[r + 1] - b[r], r++, ans[l + r] = sum; 24 | return ans; 25 | } 26 | int32_t main() { 27 | ios_base::sync_with_stdio(0); 28 | cin.tie(0); 29 | vector a({1, 2, 4, 8, 20}); 30 | vector b({4, 6, 10, 18}); 31 | auto ans = multiply(a, b); 32 | for (int i = 0; i < ans.size(); i++) { 33 | cout << ans[i] << ' '; 34 | } 35 | return 0; 36 | } -------------------------------------------------------------------------------- /Data Structures/Segment Tree NonRecursive.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9; 5 | 6 | int n, a[N]; 7 | struct ST { 8 | int t[2 * N]; 9 | ST() { 10 | memset(t, 0, sizeof t); 11 | } 12 | inline int combine(int l, int r) { 13 | return l + r; 14 | } 15 | void build() { 16 | for(int i = 0; i < n; i++) t[i + n] = a[i + 1]; 17 | for(int i = n - 1; i > 0; --i) t[i] = combine(t[i << 1], t[i << 1 | 1]); 18 | } 19 | void upd(int p, int v) { 20 | p--; 21 | for (t[p += n] = v; p >>= 1; ) t[p] = combine(t[p << 1], t[p << 1 | 1]); 22 | } 23 | int query(int l, int r) { 24 | int resl = 0, resr = 0; 25 | --l; 26 | for(l += n, r += n; l < r; l >>= 1, r >>= 1) { 27 | if(l & 1) resl = combine(resl, t[l++]); 28 | if(r & 1) resr = combine(t[--r], resr); 29 | } 30 | return combine(resl, resr); 31 | } 32 | } t; 33 | 34 | int32_t main() { 35 | n = 3; 36 | a[1] = 1; 37 | a[2] = 2; 38 | a[3] = 3; 39 | t.build(); 40 | cout << t.query(1, 2) << '\n'; 41 | t.upd(2, 10); 42 | cout << t.query(1, 3) << '\n'; 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /Number Theory/Linear Congruence Equation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | using ll = long long; 5 | 6 | ll extended_euclid(ll a, ll b, ll &x, ll &y) { 7 | if (b == 0) { 8 | x = 1; y = 0; 9 | return a; 10 | } 11 | ll x1, y1; 12 | ll d = extended_euclid(b, a % b, x1, y1); 13 | x = y1; 14 | y = x1 - y1 * (a / b); 15 | return d; 16 | } 17 | ll inverse(ll a, ll m) { 18 | ll x, y; 19 | ll g = extended_euclid(a, m, x, y); 20 | if (g != 1) return -1; 21 | return (x % m + m) % m; 22 | } 23 | // ax = b (mod m) 24 | vector congruence_equation(ll a, ll b, ll m) { 25 | vector ret; 26 | ll g = gcd(a, m), x; 27 | if (b % g != 0) return ret; 28 | a /= g, b /= g; 29 | x = inverse(a, m / g); 30 | for (int k = 0; k < g; ++k) { // exactly g solutions 31 | ret.push_back((x * b + m / g * k) % m); 32 | } 33 | return ret; 34 | } 35 | int32_t main() { 36 | ios_base::sync_with_stdio(0); 37 | cin.tie(0); 38 | auto ret = congruence_equation(4, 0, 12); 39 | for (auto x: ret) { 40 | cout << x << ' '; 41 | } 42 | return 0; 43 | } 44 | // https://cp-algorithms.com/algebra/linear_congruence_equation.html -------------------------------------------------------------------------------- /Strings/De Bruijn Sequence.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9; // >= k^n 5 | 6 | // creates a cyclic string of length k^n that contains every length n string as a substring. alphabet = [0, k - 1] 7 | // O(k^n) 8 | int ans[N], aux[N]; 9 | int de_bruijn(int k, int n) { // returns size (k^n) 10 | if (k == 1) { 11 | ans[0] = 0; 12 | return 1; 13 | } 14 | for (int i = 0; i < k * n; i++) { 15 | aux[i] = 0; 16 | } 17 | int sz = 0; 18 | function db = [&](int t, int p) { 19 | if (t > n) { 20 | if (n % p == 0) { 21 | for (int i = 1; i <= p; i++) { 22 | ans[sz++] = aux[i]; 23 | } 24 | } 25 | } 26 | else { 27 | aux[t] = aux[t - p]; 28 | db(t + 1, p); 29 | for (int i = aux[t - p] + 1; i < k; i++) { 30 | aux[t] = i; 31 | db(t + 1, t); 32 | } 33 | } 34 | }; 35 | db(1, 1); 36 | return sz; 37 | } 38 | int32_t main() { 39 | ios_base::sync_with_stdio(0); 40 | cin.tie(0); 41 | int k, n; cin >> k >> n; 42 | int len = de_bruijn(k, n); 43 | for (int i = 0; i < len; i++) cout << ans[i] << ' '; 44 | cout << '\n'; 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /Number Theory/Floor Sum of Arithmetic Progressions.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | using ll = long long; 5 | ll sumsq(ll n) { 6 | return n / 2 * ((n - 1) | 1); 7 | } 8 | // \sum_{i = 0}^{n - 1}{(a + d * i) / m}, O(log m) 9 | ll floor_sum(ll a, ll d, ll m, ll n) { 10 | ll res = d / m * sumsq(n) + a / m * n; 11 | d %= m; a %= m; 12 | if (!d) return res; 13 | ll to = (n * d + a) / m; 14 | return res + (n - 1) * to - floor_sum(m - 1 - a, m, d, to); 15 | } 16 | // \sum_{i = 0}^{n - 1}{(a + d * i) % m} 17 | ll mod_sum(ll a, ll d, ll m, ll n) { 18 | a = ((a % m) + m) % m; 19 | d = ((d % m) + m) % m; 20 | return n * a + d * sumsq(n) - m * floor_sum(a, d, m, n); 21 | } 22 | int main() { 23 | ios_base::sync_with_stdio(0); 24 | cin.tie(0); 25 | ll a, d, n; 26 | while (cin >> a >> n >> d) { 27 | n = (n - a) / d; 28 | ll ans = 0; 29 | for (int k = 0; k < 32; k++) { 30 | ll cur = mod_sum(a, d, (1LL << k + 1), n + 1); 31 | cur -= mod_sum(a, d, (1LL << k), n + 1); 32 | if (cur / (1LL << k) & 1) { 33 | ans += 1LL << k; 34 | } 35 | } 36 | cout << ans << '\n'; 37 | } 38 | return 0; 39 | } 40 | // http://poj.org/problem?id=3495 -------------------------------------------------------------------------------- /Number Theory/Sum of Arithmetic Progression Modular and Divided.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9; 5 | /* 6 | Sums of arithmetic progressions. 7 | mod_sum(n, a, d, m) = \sum_{i = 0}^{n - 1}{(a + d * i) % m}. 8 | floor_sum(n, a, d, m) = \sum_{i = 0}^{n - 1}{(a + d * i) / m}. 9 | log(m), with a large constant. 10 | */ 11 | long long sumsq(long long n) { 12 | return n / 2 * ((n - 1) | 1); 13 | } 14 | long long floor_sum(long long a, long long d, long long m, long long n) { 15 | long long res = d / m * sumsq(n) + a / m * n; 16 | d %= m; a %= m; 17 | if (!d) return res; 18 | long long to = (n * d + a) / m; 19 | return res + (n - 1) * to - floor_sum(m - 1 - a, m, d, to); 20 | } 21 | long long mod_sum(long long a, long long d, long long m, long long n) { 22 | a = ((a % m) + m) % m; 23 | d = ((d % m) + m) % m; 24 | return n * a + d * sumsq(n) - m * floor_sum(a, d, m, n); 25 | } 26 | int32_t main() { 27 | ios_base::sync_with_stdio(0); 28 | cin.tie(0); 29 | int t; cin >> t; 30 | while (t--) { 31 | int n, m, a, b; cin >> n >> m >> a >> b; 32 | cout << floor_sum(b, a, m, n) << '\n'; 33 | } 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /Math/Basis Vector.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9; 5 | 6 | struct Basis { 7 | vector a; 8 | void insert(int x) { 9 | for (auto &i: a) x = min(x, x ^ i); 10 | if (!x) return; 11 | for (auto &i: a) if ((i ^ x) < i) i ^= x; 12 | a.push_back(x); 13 | sort(a.begin(), a.end()); 14 | } 15 | bool can(int x) { 16 | for (auto &i: a) x = min(x, x ^ i); 17 | return !x; 18 | } 19 | int maxxor(int x = 0) { 20 | for (auto &i: a) x = max(x, x ^ i); 21 | return x; 22 | } 23 | int minxor(int x = 0) { 24 | for (auto &i: a) x = min(x, x ^ i); 25 | return x; 26 | } 27 | int kth(int k) { // 1st is 0 28 | int sz = (int)a.size(); 29 | if (k > (1LL << sz)) return -1; 30 | k--; int ans = 0; 31 | for (int i = 0; i < sz; i++) if (k >> i & 1) ans ^= a[i]; 32 | return ans; 33 | } 34 | }t; 35 | int main() { 36 | ios_base::sync_with_stdio(0); 37 | cin.tie(0); 38 | int q; cin >> q; 39 | while (q--) { 40 | int ty, k; cin >> ty >> k; 41 | if (ty == 1) t.insert(k); 42 | else cout << t.kth(k) << '\n'; 43 | } 44 | return 0; 45 | } 46 | //https://codeforces.com/group/qcIqFPYhVr/contest/203881/problem/S 47 | -------------------------------------------------------------------------------- /Dynamic Programming Optimizations/Persistent CHT.cpp: -------------------------------------------------------------------------------- 1 | struct PT { 2 | int x, y; 3 | PT(int x = 0, int y = 0): x(x), y(y) {} 4 | friend ll dot(PT &a, PT &b) { 5 | return 1ll * a.x * b.x + 1ll * a.y * b.y; 6 | } 7 | friend int orientation(PT &a, PT &b, PT &c) { 8 | ll s = 1ll * (b.x - a.x) * (c.y - a.y) - 1ll * (b.y - a.y) * (c.x - a.x); 9 | return (s > 0) - (s < 0); 10 | } 11 | }; 12 | struct PersistentCHT { //minimizes dot product 13 | const static int N = 1e6 + 6; 14 | const static int lg = 22; 15 | int p[N][lg], sz; 16 | PT pnt[N]; 17 | int insert(PT a, int rt) { 18 | for (int u, v, i = lg - 1; i >= 0; i--) 19 | if ((u = p[rt][i]) && (v = p[u][0]) && orientation(pnt[v], pnt[u], a) <= 0) 20 | rt = u; 21 | if (p[rt][0] && orientation(pnt[p[rt][0]], pnt[rt], a) <= 0) rt = p[rt][0]; 22 | pnt[++sz] = a; 23 | p[sz][0] = rt; 24 | for (int i = 1; i < lg; i++) p[sz][i] = p[p[sz][i - 1]][i - 1]; 25 | return sz; 26 | } 27 | ll query(PT a, int rt) { 28 | for (int u, v, i = lg - 1; i >= 0; i--) 29 | if ((u = p[rt][i]) && (v = p[u][0]) && dot(a, pnt[v]) > dot(a, pnt[u])) 30 | rt = u; 31 | if (p[rt][0] && dot(a, pnt[p[rt][0]]) > dot(a, pnt[rt])) rt = p[rt][0]; 32 | return rt ? dot(a, pnt[rt]) : -1e18; 33 | } 34 | } cht; 35 | -------------------------------------------------------------------------------- /Math/Determinant.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9; 5 | 6 | const double eps = 1e-9; 7 | int Gauss(vector> a) { 8 | int n = (int)a.size(), m = (int)a[0].size(); 9 | double det = 1; int rank = 0; 10 | for(int col = 0, row = 0; col < m && row < n; ++col) { 11 | int mx = row; 12 | for(int i = row; i < n; i++) if(fabs(a[i][col]) > fabs(a[mx][col])) mx = i; 13 | if(fabs(a[mx][col]) < eps) {det = 0; continue;} 14 | for(int i = col; i < m; i++) swap(a[row][i], a[mx][i]); 15 | if (row != mx) det = -det; 16 | det *= a[row][col]; 17 | for(int i = 0; i < n; i++) { 18 | if(i != row && fabs(a[i][col]) > eps) { 19 | double c = a[i][col] / a[row][col]; 20 | for(int j = col; j < m; j++) a[i][j] -= a[row][j] * c; 21 | } 22 | } 23 | ++row; ++rank; 24 | } 25 | return det; 26 | } 27 | int main() { 28 | int n, m; cin >> n >> m; 29 | vector< vector > v(n); 30 | for(int i = 0; i < n; i++) { 31 | for(int j = 0; j < m; j++) { 32 | double x; cin >> x; v[i].push_back(x); 33 | } 34 | } 35 | cout << Gauss(v) << '\n'; 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /Number Theory/Linear Sieve for Multiplicative Functions.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1e7 + 9; 5 | 6 | // f is multiplicative with f(p^k) = k 7 | int spf[N], f[N], cnt[N]; // cnt[i] = power of spf[i] in i 8 | vector primes; 9 | void sieve() { 10 | f[1] = 1; 11 | for(int i = 2; i < N; i++) { 12 | if (spf[i] == 0) { // i is prime 13 | spf[i] = i, primes.push_back(i); 14 | f[i] = 1; cnt[i] = 1; 15 | } 16 | int sz = primes.size(); 17 | for (int j = 0; j < sz && i * primes[j] < N && primes[j] <= spf[i]; j++) { 18 | int p = i * primes[j]; 19 | spf[p] = primes[j]; 20 | if (primes[j] == spf[i]) { // primes[j] divides i 21 | f[p] = f[i] / cnt[i] * (cnt[i] + 1); // f(i * primes[j]) = f(i / (primes[j]^cnt[i])) * f(primes[j]^(cnt[i] + 1)) 22 | cnt[p] = cnt[i] + 1; 23 | } 24 | else { // primes[j] does not divide i 25 | f[p] = f[i] * f[primes[j]]; 26 | cnt[p] = 1; 27 | } 28 | } 29 | } 30 | } 31 | 32 | int32_t main() { 33 | ios_base::sync_with_stdio(0); 34 | cin.tie(0); 35 | sieve(); 36 | for (int i = 1; i <= 10; i++) { 37 | cout << f[i] << '\n'; 38 | } 39 | return 0; 40 | } 41 | // https://codeforces.com/blog/entry/54090 -------------------------------------------------------------------------------- /Data Structures/Segment Tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9; 5 | 6 | int a[N]; 7 | struct ST { 8 | int t[4 * N]; 9 | static const int inf = 1e9; 10 | ST() { 11 | memset(t, 0, sizeof t); 12 | } 13 | void build(int n, int b, int e) { 14 | if (b == e) { 15 | t[n] = a[b]; 16 | return; 17 | } 18 | int mid = (b + e) >> 1, l = n << 1, r = l | 1; 19 | build(l, b, mid); 20 | build(r, mid + 1, e); 21 | t[n] = max(t[l], t[r]); 22 | } 23 | void upd(int n, int b, int e, int i, int x) { 24 | if (b > i || e < i) return; 25 | if (b == e && b == i) { 26 | t[n] = x; 27 | return; 28 | } 29 | int mid = (b + e) >> 1, l = n << 1, r = l | 1; 30 | upd(l, b, mid, i, x); 31 | upd(r, mid + 1, e, i, x); 32 | t[n] = max(t[l], t[r]); 33 | } 34 | int query(int n, int b, int e, int i, int j) { 35 | if (b > j || e < i) return -inf; 36 | if (b >= i && e <= j) return t[n]; 37 | int mid = (b + e) >> 1, l = n << 1, r = l | 1; 38 | int L = query(l, b, mid, i, j); 39 | int R = query(r, mid + 1, e, i, j); 40 | return max(L, R); 41 | } 42 | }t; 43 | 44 | int32_t main() { 45 | ios_base::sync_with_stdio(0); 46 | cin.tie(0); 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /Geometry/Closest Pair of Points.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9; 5 | #define x first 6 | #define y second 7 | long long dist2(pair a, pair b) { 8 | return 1LL * (a.x - b.x) * (a.x - b.x) + 1LL * (a.y - b.y) * (a.y - b.y); 9 | } 10 | pair closest_pair(vector> a) { 11 | int n = a.size(); 12 | assert(n >= 2); 13 | vector, int>> p(n); 14 | for (int i = 0; i < n; i++) p[i] = {a[i], i}; 15 | sort(p.begin(), p.end()); 16 | int l = 0, r = 2; 17 | long long ans = dist2(p[0].x, p[1].x); 18 | pair ret = {0, 1}; 19 | while (r < n) { 20 | while (l < r && 1LL * (p[r].x.x - p[l].x.x) * (p[r].x.x - p[l].x.x) >= ans) l++; 21 | for (int i = l; i < r; i++) { 22 | long long nw = dist2(p[i].x, p[r].x); 23 | if (nw < ans) { 24 | ans = nw; 25 | ret = {p[i].y, p[r].y}; 26 | } 27 | } 28 | r++; 29 | } 30 | return ret; 31 | } 32 | int32_t main() { 33 | ios_base::sync_with_stdio(0); 34 | cin.tie(0); 35 | int n; cin >> n; 36 | vector> p(n); 37 | for (int i = 0; i < n; i++) cin >> p[i].x >> p[i].y; 38 | pair z = closest_pair(p); 39 | if (z.x > z.y) swap(z.x, z.y); 40 | cout << z.x << ' ' << z.y << ' ' << fixed << setprecision(6) << sqrtl(dist2(p[z.x], p[z.y])) << '\n'; 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /Dynamic Programming Optimizations/Number of Subsequences Having Product at least K.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1010, mod = 1e9 + 7, SQ = sqrt(mod) + 1; 5 | 6 | int a[N], k; 7 | int dp1[N][SQ], dp2[N][SQ]; 8 | int mul_back(int i, int p) { 9 | if (i <= 0) return p >= 1; 10 | int &ret = dp1[i][p]; 11 | if (ret != -1) return ret; 12 | ret = mul_back(i - 1, p); 13 | ret += mul_back(i - 1, p / a[i]); 14 | if (ret >= mod) ret -= mod; 15 | return ret; 16 | } 17 | int mul_front(int i, int p) { 18 | if (i <= 0) return p <= k; 19 | int &ret = dp2[i][p]; 20 | if (ret != -1) return ret; 21 | ret = mul_front(i - 1, p); 22 | if (1LL * a[i] * p < SQ) ret += mul_front(i - 1, p * a[i]); 23 | else ret += mul_back(i - 1, k / (1LL * p * a[i])); 24 | if (ret >= mod) ret -= mod; 25 | return ret; 26 | } 27 | int32_t main() { 28 | ios_base::sync_with_stdio(0); 29 | cin.tie(0); 30 | memset(dp1, -1, sizeof dp1); 31 | memset(dp2, -1, sizeof dp2); 32 | int n; cin >> n >> k; 33 | --k; 34 | for (int i = 1; i <= n; i++) { 35 | cin >> a[i]; 36 | } 37 | int ans = 1; 38 | for (int i = 1; i <= n; i++) { 39 | ans = (ans + ans) % mod; 40 | } 41 | cout << (ans - mul_front(n, 1) + mod) % mod << '\n'; 42 | return 0; 43 | } 44 | // https://codeforces.com/group/NOwIbqv33y/contest/307527/problem/J 45 | -------------------------------------------------------------------------------- /Graph Theory/Krushkal's MST.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9, mod = 1e9; 5 | 6 | struct dsu { 7 | vector par, rnk, size; int c; 8 | dsu(int n) : par(n+1), rnk(n+1,0), size(n+1,1), c(n) { 9 | for (int i = 1; i <= n; ++i) par[i] = i; 10 | } 11 | int find(int i) { return (par[i] == i ? i : (par[i] = find(par[i]))); } 12 | bool same(int i, int j) { return find(i) == find(j); } 13 | int get_size(int i) { return size[find(i)]; } 14 | int count() { return c; } //connected components 15 | int merge(int i, int j) { 16 | if ((i = find(i)) == (j = find(j))) return -1; else --c; 17 | if (rnk[i] > rnk[j]) swap(i, j); 18 | par[i] = j; size[j] += size[i]; 19 | if (rnk[i] == rnk[j]) rnk[j]++; 20 | return j; 21 | } 22 | }; 23 | 24 | int32_t main() { 25 | ios_base::sync_with_stdio(0); 26 | cin.tie(0); 27 | int n, m; cin >> n >> m; 28 | vector> ed; 29 | for(int i = 1; i <= m; i++){ 30 | int u, v, w; cin >> u >> v >> w; 31 | ed.push_back({w, u , v}); 32 | } 33 | sort(ed.begin(), ed.end()); 34 | long long ans = 0; 35 | dsu d(n); 36 | for (auto e: ed){ 37 | int u = e[1], v = e[2], w = e[0]; 38 | if (d.same(u, v)) continue; 39 | ans += w; 40 | d.merge(u, v); 41 | } 42 | cout << ans << '\n'; 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /Graph Theory/Cycle Detection.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 5e5 + 9; 5 | 6 | vector> g[N]; 7 | int vis[N], par[N], e_id[N]; 8 | vector cycle; // simple cycle, contains edge ids 9 | 10 | bool dfs(int u) { 11 | if (!cycle.empty()) return 1; 12 | vis[u] = 1; 13 | for (auto [v, id] : g[u]) { 14 | if (v != par[u]) { 15 | if (vis[v] == 0) { 16 | par[v] = u; 17 | e_id[v] = id; 18 | if (dfs(v)) return 1; 19 | } 20 | else if (vis[v] == 1) { 21 | // cycle here 22 | cycle.push_back(id); 23 | for (int x = u; x != v; x = par[x]) { 24 | cycle.push_back(e_id[x]); 25 | } 26 | return 1; 27 | } 28 | } 29 | } 30 | vis[u] = 2; 31 | return 0; 32 | } 33 | 34 | int32_t main() { 35 | ios_base::sync_with_stdio(0); 36 | cin.tie(0); 37 | int n, m; cin >> n >> m; 38 | for (int i = 1; i <= m; i++) { 39 | int u, v; cin >> u >> v; 40 | ++u; ++v; 41 | g[u].push_back({v, i}); 42 | } 43 | for (int u = 1; u <= n; u++) { 44 | if (vis[u] == 0 and dfs(u)) { 45 | cout << cycle.size() << '\n'; 46 | for (auto x: cycle) cout << x - 1 << '\n'; 47 | return 0; 48 | } 49 | } 50 | cout << -1 << '\n'; 51 | return 0; 52 | } 53 | // https://judge.yosupo.jp/problem/cycle_detection -------------------------------------------------------------------------------- /Number Theory/Continued Fractions.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | using ll = long long; 5 | // returns the continued fraction of p / q 6 | // [a[0]; a[1], ..., a[n]] = a[0] + 1 / (a[1] + 1 / (a[2] + ...) + 1 / (a[n - 1] + 1 / a[n])))) 7 | // a[0] is integer number and a[1],a[2],…,a[n] are positive integer numbers and either n = 0 or a[n] != 1 8 | // its unique 9 | vector get_frac(ll p, ll q) { 10 | vector a; 11 | while (q) { 12 | a.push_back(p / q); 13 | p %= q; swap(p, q); 14 | } 15 | return a; 16 | } 17 | // ans[k] = [a[0]; a[1], ..., a[k]] 18 | vector> convergents(vector a) { 19 | ll lp = 1, lq = 0; 20 | vector> ans({{a[0], 1}}); 21 | for (int i = 1; i < a.size(); i++) { 22 | ll p = a[i] * ans.back().first + lp; 23 | ll q = a[i] * ans.back().second + lq; 24 | // assert(__gcd(p, q) == 1) 25 | lp = ans.back().first; 26 | lq = ans.back().second; 27 | ans.push_back({p, q}); 28 | } 29 | return ans; 30 | } 31 | int32_t main() { 32 | ios_base::sync_with_stdio(0); 33 | cin.tie(0); 34 | ll i = 10, j = 23; 35 | auto a = get_frac(i, j); 36 | for (auto x: a) cout << x << ' '; cout << '\n'; 37 | auto p = convergents(a); 38 | for (auto [x, y]: p) { 39 | cout << x << ' ' << y << '\n'; 40 | } 41 | return 0; 42 | } 43 | // https://codeforces.com/blog/entry/73655 -------------------------------------------------------------------------------- /Math/Basis Vector ft Weighted Linearly Independent Vectors.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | template 5 | struct Basis { 6 | static const int B = 127; 7 | T a[B]; 8 | long long wt[B]; 9 | Basis() { 10 | memset(a, 0, sizeof a); 11 | memset(wt, 0, sizeof wt); 12 | } 13 | void insert(T x, long long w) { 14 | for (int i = B - 1; i >= 0; i--) { 15 | if (x >> i & 1) { 16 | if (a[i] == 0) { 17 | a[i] = x; 18 | wt[i] = w; 19 | break; 20 | } 21 | if (wt[i] < w) { 22 | swap(wt[i], w); 23 | swap(a[i], x); 24 | } 25 | x ^= a[i]; 26 | } 27 | } 28 | } 29 | // maximum sum of linearly independent vectors 30 | long long query() { 31 | long long ans = 0; 32 | for (int i = 0; i < B; i++) { 33 | ans += wt[i]; 34 | } 35 | return ans; 36 | } 37 | }; 38 | Basis<__int128> t; 39 | int32_t main() { 40 | ios_base::sync_with_stdio(0); 41 | cin.tie(0); 42 | int n, q; cin >> n >> q; 43 | while (q--) { 44 | int u, v; 45 | long long x, w; cin >> u >> v >> x >> w; 46 | __int128 cur = x, b = 1; 47 | cur |= b << (62 + u); 48 | cur |= b << (62 + v); 49 | t.insert(cur, w); 50 | cout << t.query() << '\n'; 51 | } 52 | return 0; 53 | } 54 | // https://codeforces.com/gym/102331/problem/E -------------------------------------------------------------------------------- /Number Theory/Power Tower.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1e5 + 9; 5 | using ll = long long; 6 | 7 | map mp; 8 | ll phi(ll n) { 9 | if (mp.count(n)) return mp[n]; 10 | ll ans = n, m = n; 11 | for (ll i = 2; i * i <= m; i++) { 12 | if (m % i == 0) { 13 | while (m % i == 0) m /= i; 14 | ans = ans / i * (i - 1); 15 | } 16 | } 17 | if (m > 1) ans = ans / m * (m - 1); 18 | return mp[n] = ans; 19 | } 20 | inline ll MOD(ll x, ll m) { 21 | if (x < m) return x; 22 | return x % m + m; 23 | } 24 | ll power(ll n, ll k, ll mod) { 25 | ll ans = MOD(1, mod); 26 | while (k) { 27 | if (k & 1) ans = MOD(ans * n, mod); 28 | n = MOD(n * n, mod); 29 | k >>= 1; 30 | } 31 | return ans; 32 | } 33 | int a[N]; 34 | // if x >= log2(m), then a^x = a^(MOD(x, phi(m))) % m 35 | ll yo(ll l, ll r, ll m) { 36 | if (l == r) return MOD(a[l], m); 37 | if (m == 1) return 1; 38 | return power(a[l], yo(l + 1, r, phi(m)), m); 39 | } 40 | int32_t main() { 41 | ios_base::sync_with_stdio(0); 42 | cin.tie(0); 43 | int n, m; cin >> n >> m; 44 | for (int i = 1; i <= n; i++) { 45 | cin >> a[i]; 46 | } 47 | int q; cin >> q; 48 | while (q--) { 49 | int l, r; cin >> l >> r; 50 | cout << yo(l, r, m) % m << '\n'; 51 | } 52 | return 0; 53 | } 54 | // https://codeforces.com/contest/906/problem/D -------------------------------------------------------------------------------- /Miscellaneous/Fraction Binary Search.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | /** 5 | Given a function f and n, finds the smallest fraction p / q in [0, 1] or [0,n] 6 | such that f(p / q) is true, and p, q <= n. 7 | Time: O(log(n)) 8 | **/ 9 | struct frac { long long p, q; }; 10 | bool f(frac x) { 11 | return 6 + 8 * x.p >= 17 * x.q + 12; 12 | } 13 | frac fracBS(long long n) { 14 | bool dir = 1, A = 1, B = 1; 15 | frac lo{0, 1}, hi{1, 0}; // Set hi to 1/0 to search within [0, n] and {1, 1} to search within [0, 1] 16 | if (f(lo)) return lo; 17 | assert(f(hi)); //checking if any solution exists or not 18 | while (A || B) { 19 | long long adv = 0, step = 1; // move hi if dir, else lo 20 | for (int si = 0; step; (step *= 2) >>= si) { 21 | adv += step; 22 | frac mid{lo.p * adv + hi.p, lo.q * adv + hi.q}; 23 | if (abs(mid.p) > n || mid.q > n || dir == !f(mid)) { 24 | adv -= step; si = 2; 25 | } 26 | } 27 | hi.p += lo.p * adv; 28 | hi.q += lo.q * adv; 29 | dir = !dir; 30 | swap(lo, hi); 31 | A = B; B = !!adv; 32 | } 33 | return dir ? hi : lo; 34 | } 35 | 36 | int32_t main() { 37 | ios_base::sync_with_stdio(0); 38 | cin.tie(0); 39 | frac ans=fracBS(10); 40 | cout << ans.p << ' ' << ans.q << '\n'; 41 | return 0; 42 | } 43 | // Relevant Problem: https://codeforces.com/gym/102354/submission/69260720 -------------------------------------------------------------------------------- /Number Theory/Maximum Coprime Product.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | using ll = long long; 5 | const int N = 1e5; 6 | 7 | // credit: mango_lassi 8 | int arr[N + 1]; 9 | int u[N + 1]; 10 | int cnt[N + 1]; 11 | 12 | vector d[N + 1]; 13 | bool b[N + 1]; 14 | 15 | bool coprime(int x) { 16 | int ret = 0; 17 | for (int i : d[x]) ret += cnt[i] * u[i]; 18 | return ret; 19 | } 20 | 21 | void update(int x, int a) { 22 | for (int i : d[x]) cnt[i] += a; 23 | } 24 | 25 | int main() { 26 | for (int i = 1; i <= N; i++) { 27 | for (int j = i; j <= N; j += i) d[j].push_back(i); 28 | if (i == 1) u[i] = 1; 29 | else if ((i / d[i][1]) % d[i][1] == 0) u[i] = 0; 30 | else u[i] = -u[i / d[i][1]]; 31 | } 32 | 33 | int n; 34 | cin >> n; 35 | 36 | ll ans = 0; 37 | for (int i = 0; i < n; i++) { 38 | int a; 39 | cin >> a; 40 | ans = max(ans, (ll)a); 41 | b[a] = 1; 42 | } 43 | for (int i = 1; i <= N; ++i) { 44 | for (int j = 2; i * j <= N; ++j) b[i] |= b[i * j]; 45 | } 46 | 47 | vector s; 48 | for (int i = N; i > 0; --i) { 49 | if (! b[i]) continue; 50 | while(coprime(i)) { 51 | ans = max(ans, (ll)i * s.back()); 52 | update(s.back(), -1); 53 | s.pop_back(); 54 | } 55 | update(i, 1); 56 | s.push_back(i); 57 | } 58 | cout << ans << '\n'; 59 | } 60 | // https://codeforces.com/contest/1285/submission/68564248 61 | -------------------------------------------------------------------------------- /Number Theory/Mobius Function.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 5e5 + 9; 5 | 6 | int mob[N]; 7 | void mobius() { 8 | mob[1] = 1; 9 | for (int i = 2; i < N; i++){ 10 | mob[i]--; 11 | for (int j = i + i; j < N; j += i) { 12 | mob[j] -= mob[i]; 13 | } 14 | } 15 | } 16 | bool vis[N]; 17 | vector d[N]; 18 | int mul[N]; 19 | void add(int x, int k) { 20 | for (auto y: d[x]) { 21 | mul[y] += k; 22 | } 23 | } 24 | int query(int x) { 25 | int ans = 0; 26 | for (auto y: d[x]) { 27 | ans += mul[y] * mob[y]; 28 | } 29 | return ans; 30 | } 31 | int a[N]; 32 | int32_t main() { 33 | ios_base::sync_with_stdio(0); 34 | cin.tie(0); 35 | mobius(); 36 | for (int i = 1; i < N; i++) { 37 | if (mob[i]) { 38 | for (int j = i; j < N; j += i) { 39 | d[j].push_back(i); 40 | } 41 | } 42 | } 43 | int n, q; cin >> n >> q; 44 | for (int i = 1; i <= n; i++) { 45 | cin >> a[i]; 46 | } 47 | long long ans = 0; 48 | while (q--) { 49 | int i; cin >> i; 50 | if (vis[i]) { 51 | ans -= query(a[i]); 52 | ans += a[i] == 1; 53 | add(a[i], -1); 54 | } 55 | else { 56 | ans += query(a[i]); 57 | add(a[i], 1); 58 | } 59 | vis[i] ^= 1; 60 | cout << ans << '\n'; 61 | } 62 | return 0; 63 | } 64 | // https://codeforces.com/contest/547/problem/C -------------------------------------------------------------------------------- /Graph Theory/Number of Different Cliques.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int M = 42; 5 | using ll = long long; 6 | // number of cliques in a graph including null clique 7 | // meet in the middle 8 | // Complexity: O((M/2)*2^(M/2)) 9 | int dp[(1 << (M / 2))]; 10 | ll g[M]; 11 | int32_t main() { 12 | int n, m; cin >> n >> m; 13 | for(int i = 0; i < m; i++) { 14 | int u, v; cin >> u >> v; 15 | --u;--v; 16 | g[u] |= 1LL << v; 17 | g[v] |= 1LL << u; 18 | } 19 | for (int i = 0; i < n; i++) g[i] |= 1LL << i; 20 | int k = n / 2; 21 | dp[0] = 1; 22 | for (int i = 1; i < (1 << k); i++) { 23 | ll nw = (1LL << n) - 1; 24 | for (int j = 0; j < k; j++) { 25 | if ((i >> j) & 1) nw &= g[j]; 26 | } 27 | if ((nw & i) == i) dp[i] = 1; 28 | } 29 | for (int i = 0; i < k; i++) { 30 | for (int mask = 0; mask < (1 << k); mask++) { 31 | if ((mask >> i) & 1) dp[mask] += dp[mask ^ (1 << i)]; 32 | } 33 | } 34 | ll ans = dp[(1 << k) - 1]; 35 | k = n - k; 36 | for (int i = 1; i < (1 << k); i++) { 37 | ll nw = (1LL << n) - 1; 38 | for (int j = 0; j < k; j++) { 39 | if ((i >> j) & 1) nw &= g[n / 2 + j]; 40 | } 41 | ll p = (1LL * i) << (n / 2); 42 | if ((nw & p) == p) { 43 | ll x = nw & ((1LL << (n / 2)) - 1); 44 | ans += dp[x]; 45 | } 46 | } 47 | cout << ans << '\n'; 48 | return 0; 49 | } -------------------------------------------------------------------------------- /Dynamic Programming Optimizations/Bounded Knapsack.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // ps-profits 5 | // ws-weights 6 | // ms-maximum limit of each element 7 | // W-maximum weight 8 | // O(n*W) 9 | int boundedKnapsack(vector ps, vector ws, vector ms, int W) { 10 | int n = ps.size(); 11 | vector> dp(n + 1, vector(W + 1)); 12 | for (int i = 0; i < n; ++i) { 13 | for (int s = 0; s < ws[i]; ++s) { 14 | int alpha = 0; 15 | queue que; 16 | deque peek; 17 | for (int w = s; w <= W; w += ws[i]) { 18 | alpha += ps[i]; 19 | int a = dp[i][w] - alpha; 20 | que.push(a); 21 | while (!peek.empty() && peek.back() < a) peek.pop_back(); 22 | peek.push_back(a); 23 | while (que.size() > ms[i] + 1) { 24 | if (que.front() == peek.front()) peek.pop_front(); 25 | que.pop(); 26 | } 27 | dp[i + 1][w] = peek.front() + alpha; 28 | } 29 | } 30 | } 31 | int ans = 0; 32 | for (int w = 0; w <= W; ++w) 33 | ans = max(ans, dp[n][w]); 34 | return ans; 35 | } 36 | int32_t main() { 37 | int i, j, k, n, m; 38 | n = 10; 39 | int W = 100; 40 | vector ps(n), ws(n), ms(n); 41 | for (int i = 0; i < n; ++i) { 42 | ps[i] = rand() % n + 1; 43 | ws[i] = rand() % n + 1; 44 | ms[i] = rand() % n + 1; 45 | } 46 | cout << boundedKnapsack(ps, ws, ms, W) << endl; 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /Graph Theory/SPFA.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 5050; 5 | 6 | vector> g[N]; 7 | bool vis[N]; 8 | long long d[N]; 9 | bool spfa(int u) { 10 | vis[u] = 1; 11 | for(auto e: g[u]) { 12 | int w = e.second, v = e.first; 13 | if(d[u] + w < d[v]) { 14 | if(vis[v]) return 0; 15 | d[v] = d[u] + w; 16 | if(!spfa(v)) return 0; 17 | } 18 | } 19 | vis[u] = 0; 20 | return 1; 21 | } 22 | 23 | int32_t main() { 24 | ios_base::sync_with_stdio(0); 25 | cin.tie(0); 26 | 27 | int t; 28 | cin >> t; 29 | while(t--) { 30 | int n, m; 31 | cin >> n >> m; 32 | for(int i = 0; i <= n; i++) g[i].clear(); 33 | int ans = 1e9; 34 | for(int i = 1; i <= m; i++) { 35 | int u, v, w; cin >> u >> v >> w; 36 | g[u].push_back({v, w}); 37 | ans = min(ans, w); 38 | } 39 | if(ans >= 0) { 40 | cout << ans << '\n'; 41 | continue; 42 | } 43 | for(int i = 1; i <= n; i++) g[0].push_back({i, 0}); 44 | for(int i = 0; i <= n; i++) d[i] = 1e10, vis[i] = 0; 45 | int s = 0; 46 | d[s] = 0; 47 | if(spfa(s) == 0) cout << "-inf\n"; // negative cycle 48 | else { 49 | long long ans = d[1]; 50 | for(int i = 1; i <= n; i++) ans= min(ans, d[i]); 51 | cout << ans << '\n'; 52 | } 53 | } 54 | return 0; 55 | } 56 | // https://codeforces.com/gym/101498/problem/L 57 | -------------------------------------------------------------------------------- /Dynamic Programming Optimizations/DP Over Divisors.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace __gnu_pbds; 5 | using namespace std; 6 | 7 | #define pii pair 8 | #define pll pair 9 | #define eb emplace_back 10 | #define ll long long 11 | #define nl '\n' 12 | #define deb(x) cerr<<#x" = "< d[N]; 20 | int cnt[N], ans[N]; 21 | int32_t main() { 22 | for(int i = 1; i < N; i++) for(int j = i; j < N; j += i) d[j].eb(i); 23 | int n = 72; 24 | vector di = d[n]; 25 | int s = di.size(); 26 | map id; 27 | for(int i = 0; i < s; i++) id[di[i]] = i; 28 | for(int i = 0; i < s; i++) ans[i] = rand(), cnt[i] = ans[i]; 29 | for(int i = 0; i < s; i++) cout << ans[i] << ' '; 30 | cout << nl; 31 | vector P = {2, 3}; 32 | for(auto k : P) { 33 | for(int i = 0; i < s; i++) { 34 | if(di[i] % k == 0) { 35 | ans[id[di[i] / k]] -= ans[i]; 36 | //assert(id[di[i]/x.F]= 0; i--) { 41 | for(int j = i + 1; j < s; j++) if(di[j] % di[i] == 0) cnt[i] -= cnt[j]; 42 | } 43 | for(int i = 0; i < s; i++) cout << ans[i] << ' '; 44 | cout << nl; 45 | for(int i = 0; i < s; i++) cout << cnt[i] << ' '; 46 | cout << nl; 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /Graph Theory/Bellman Ford.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9; 5 | 6 | struct st { 7 | int a, b, cost; 8 | } e[N]; 9 | const int INF = 2e9; 10 | int32_t main() { 11 | int n, m; 12 | cin >> n >> m; 13 | for(int i = 0; i < m; i++) cin >> e[i].a >> e[i].b >> e[i].cost; 14 | int s; 15 | cin >> s;//is there any negative cycle which is reachable from s? 16 | vector d (n, INF);//for finding any cycle(not necessarily from s) set d[i] = 0 for all i 17 | d[s] = 0; 18 | vector p (n, -1); 19 | int x; 20 | for (int i=0; i d[e[j].a] + e[j].cost) { 25 | d[e[j].b] = max (-INF, d[e[j].a] + e[j].cost);//for overflow 26 | p[e[j].b] = e[j].a; 27 | x = e[j].b; 28 | } 29 | } 30 | } 31 | } 32 | if (x == -1) cout << "No negative cycle from "< path; 38 | for (int cur=y; ; cur=p[cur]) { 39 | path.push_back (cur); 40 | if (cur == y && path.size() > 1) break; 41 | } 42 | reverse (path.begin(), path.end()); 43 | 44 | cout << "Negative cycle: "; 45 | for (int i=0; i 2 | using namespace std; 3 | 4 | const int N = 2005; 5 | 6 | bitset z; 7 | // permanent after inverting mat[i][j] = mat[i][j] ^ inv[j][i] 8 | vector> inverse(int n, vector> mat) { 9 | vector> inv(n, z); 10 | for (int i = 0; i < n; i++) inv[i][i] = 1; 11 | for (int i = 0; i < n; i++) { 12 | for (int j = i; j < n; j++) { 13 | if (mat[j][i]) { 14 | swap(mat[i], mat[j]); 15 | swap(inv[i], inv[j]); 16 | break; 17 | } 18 | } 19 | for (int j = i + 1; j < n; j++) { 20 | if (mat[j][i]) { 21 | mat[j] ^= mat[i]; 22 | inv[j] ^= inv[i]; 23 | } 24 | } 25 | } 26 | for (int i = n - 1; i >= 0; i--) { 27 | for (int j = i + 1; j < n; j++) { 28 | if (mat[i][j]) inv[i] ^= inv[j]; 29 | } 30 | } 31 | return inv; 32 | } 33 | int a[500500], b[500500]; 34 | int32_t main() { 35 | ios_base::sync_with_stdio(0); 36 | cin.tie(0); 37 | z.reset(); 38 | int n, m; cin >> n >> m; 39 | vector> mat(n, z); 40 | for (int i = 0; i < m; i++) { 41 | cin >> a[i] >> b[i]; 42 | --a[i]; --b[i]; 43 | mat[a[i]][b[i]] = 1; 44 | } 45 | auto inv = inverse(n, mat); 46 | for (int i = 0; i < m; i++) { 47 | if (inv[b[i]][a[i]]) cout << "NO\n"; 48 | else cout << "YES\n"; 49 | } 50 | return 0; 51 | } 52 | // https://codeforces.com/contest/736/problem/D 53 | -------------------------------------------------------------------------------- /Graph Theory/Chromatic Number.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | vector g[20]; 5 | //O(n*2^n) 6 | int chromatic_number(int n) { 7 | const int N = 1 << n; 8 | vector adj(n); 9 | for (int u = 0; u < n; ++u) 10 | for (int v : g[u]) 11 | adj[u] |= (1 << v); 12 | 13 | int ans = n; 14 | for (int d : {7}) { //,11,21,33,87,93}) { 15 | long long mod = 1e9 + d; 16 | vector ind(N), aux(N, 1); 17 | ind[0] = 1; 18 | for (int S = 1; S < N; ++S) { 19 | int u = __builtin_ctz(S); 20 | ind[S] = ind[S ^ (1 << u)] + ind[(S ^ (1 << u)) & ~adj[u]]; 21 | } 22 | for (int k = 1; k < ans; ++k) { 23 | long long w = 0; 24 | for (int i = 0; i < N; ++i) { 25 | int S = i ^ (i >> 1); // gray-code 26 | aux[S] = (aux[S] * ind[S]) % mod; 27 | w += (i & 1) ? aux[S] : -aux[S]; 28 | } 29 | if (w % mod) ans = min(ans, k); 30 | } 31 | } 32 | return ans; 33 | } 34 | int32_t main() { 35 | ios_base::sync_with_stdio(0); 36 | cin.tie(0); 37 | int n; cin >> n; 38 | cin.ignore(); 39 | for (int u = 0; u < n; u++) { 40 | string s, x; getline(cin, s); 41 | stringstream ss(s); 42 | while (ss >> x) { 43 | int v = atoi(x.c_str()); 44 | g[u].push_back(v); 45 | g[v].push_back(u); 46 | } 47 | } 48 | cout << chromatic_number(n) << '\n'; 49 | return 0; 50 | } 51 | // https://open.kattis.com/problems/coloring -------------------------------------------------------------------------------- /Dynamic Programming Optimizations/Connected Component DP.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 105, mod = 1e9 + 7; 5 | 6 | int n, k, a[N], dp[N][N][1005][3]; 7 | int yo(int i, int c, int sum, int ends) { //(id, components, sum, borders) 8 | if (ends > 2 || sum > k)return 0; 9 | if (c == 0 && i > 1) return 0; 10 | if (i == n + 1) return ends == 2 && c == 1; 11 | int &ret = dp[i][c][sum][ends]; 12 | if (ret != -1) return ret; 13 | int nsum = sum + (a[i] - a[i - 1]) * (2 * c - ends); 14 | long long ans = 0; 15 | if (c >= 2) ans += 1LL * (c - 1) * yo(i + 1, c - 1, nsum, ends); //merge two components 16 | if (c >= 1) ans += 1LL * (2 * c - ends) * yo(i + 1, c, nsum, ends); //add to a component's end 17 | ans += 1LL * (c + 1 - ends) * yo(i + 1, c + 1, nsum, ends); //create a new component 18 | if (ends < 2) ans += 1LL * (2 - ends) * yo(i + 1, c + 1, nsum, ends + 1); //create a new end 19 | if (ends < 2) ans += 1LL * (2 - ends) * yo(i + 1, c, nsum, ends + 1); //extend a component to make it a border 20 | ans %= mod; 21 | return ret = ans; 22 | } 23 | int32_t main() { 24 | ios_base::sync_with_stdio(0); 25 | cin.tie(0); 26 | cin >> n >> k; 27 | for (int i = 1; i <= n; i++) cin >> a[i]; 28 | sort(a + 1, a + n + 1); 29 | if (n == 1) return cout << 1 << '\n', 0; 30 | memset(dp, -1, sizeof dp); 31 | cout << yo(1, 0, 0, 0) << '\n'; 32 | return 0; 33 | } 34 | // https://oj.uz/problem/view/JOI16_skyscraper 35 | -------------------------------------------------------------------------------- /Strings/Manachers.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | int i, j, k, n, m; 6 | string s; 7 | cin >> s; 8 | n = s.size(); 9 | vector d1(n); // maximum odd length palindrome centered at i 10 | // here d1[i]=the palindrome has d1[i]-1 right characters from i 11 | // e.g. for aba, d1[1]=2; 12 | for (int i = 0, l = 0, r = -1; i < n; i++) { 13 | int k = (i > r) ? 1 : min(d1[l + r - i], r - i); 14 | while (0 <= i - k && i + k < n && s[i - k] == s[i + k]) { 15 | k++; 16 | } 17 | d1[i] = k--; 18 | if (i + k > r) { 19 | l = i - k; 20 | r = i + k; 21 | } 22 | } 23 | vector d2(n); // maximum even length palindrome centered at i 24 | // here d2[i]=the palindrome has d2[i]-1 right characters from i 25 | // e.g. for abba, d2[2]=2; 26 | for (int i = 0, l = 0, r = -1; i < n; i++) { 27 | int k = (i > r) ? 0 : min(d2[l + r - i + 1], r - i + 1); 28 | while (0 <= i - k - 1 && i + k < n && s[i - k - 1] == s[i + k]) { 29 | k++; 30 | } 31 | d2[i] = k--; 32 | if (i + k > r) { 33 | l = i - k - 1; 34 | r = i + k ; 35 | } 36 | } 37 | for(i = 0; i < n; i++) cout << d1[i] << ' '; 38 | cout << endl; 39 | for(i = 0; i < n; i++) cout << d2[i] << ' '; 40 | cout << endl; 41 | // number of palindromes 42 | long long ans = 0; 43 | for(i = 0; i < n; i++) { 44 | ans += 1LL * d1[i]; 45 | ans += 1LL * d2[i]; 46 | } 47 | cout << ans << endl; 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /Graph Theory/Inverse Graph.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9; 5 | 6 | // given edges which are not in the graph you need to apply dfs 7 | // 2 coloring for this problem 8 | int par[N], col[N], vis[N], ty[N], n; 9 | vector g[N]; 10 | int Find(int x) { 11 | return par[x] == x ? x : par[x] = Find(par[x]); 12 | } 13 | void dfs(int u, int c) { 14 | if(vis[u]) return; 15 | vis[u] = 1; 16 | par[u] = Find(u + 1); 17 | col[u] = c; 18 | if(!ty[u]) for(auto v: g[u]) dfs(v, c ^ 1); 19 | else { 20 | int v = 0; 21 | for(auto nw: g[u]) { 22 | v = Find(v + 1); 23 | while(v < nw) dfs(v, c ^ 1), v = Find(v + 1); 24 | v = nw; 25 | } 26 | v = Find(v + 1); 27 | while(v <= n) dfs(v, c ^ 1), v = Find(v + 1); 28 | } 29 | } 30 | int32_t main() { 31 | cin >> n; 32 | for(int i = 1; i <= n; i++) { 33 | char ch; 34 | cin >> ch; 35 | if(ch == 'N') ty[i] = 1; //'N' means these are the inverse edges 36 | int k; 37 | cin >> k; 38 | if(!ty[i] && k == 0 || ty[i] && k == n - 1) return cout << "Impossible\n", 0; 39 | vector v; 40 | int m; 41 | while(k--) cin >> m, v.push_back(m); 42 | sort(v.begin(), v.end()); 43 | g[i] = v; 44 | } 45 | for(int i = 1; i <= n + 1; i++) par[i] = i; //n + 1 is important 46 | for(int i = 1; i <= n; i++) if(!vis[i]) dfs(i, 0); 47 | for(int i = 1; i <= n; i++) cout << (!col[i] ? 'S' : 'V'); 48 | cout << '\n'; 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /Number Theory/Intersection of Arithmetic Progressions.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | using T = __int128; 5 | using ll = long long; 6 | // ax + by = __gcd(a, b) 7 | // returns __gcd(a, b) 8 | T extended_euclid(T a, T b, T &x, T &y) { 9 | T xx = y = 0; 10 | T yy = x = 1; 11 | while (b) { 12 | T q = a / b; 13 | T t = b; b = a % b; a = t; 14 | t = xx; xx = x - q * xx; x = t; 15 | t = yy; yy = y - q * yy; y = t; 16 | } 17 | return a; 18 | } 19 | // finds x such that x % m1 = a1, x % m2 = a2. m1 and m2 may not be coprime 20 | // here, x is unique modulo m = lcm(m1, m2). returns (x, m). on failure, m = -1. 21 | pair CRT(T a1, T m1, T a2, T m2) { 22 | T p, q; 23 | T g = extended_euclid(m1, m2, p, q); 24 | if (a1 % g != a2 % g) return make_pair(0, -1); 25 | T m = m1 / g * m2; 26 | p = (p % m + m) % m; 27 | q = (q % m + m) % m; 28 | return make_pair((p * a2 % m * (m1 / g) % m + q * a1 % m * (m2 / g) % m) % m, m); 29 | } 30 | // intersecting AP of two APs: (a1 + d1x) and (a2 + d2x) 31 | pair intersect(ll a1, ll d1, ll a2, ll d2) { 32 | auto x = CRT(a1 % d1, d1, a2 % d2, d2); 33 | ll a = x.first, d = x.second; 34 | if (d == -1) return {0, 0}; // empty 35 | ll st = max(a1, a2); 36 | a = st % d == a ? st : st - st % d + a; 37 | return {a, d}; 38 | } 39 | int32_t main() { 40 | ios_base::sync_with_stdio(0); 41 | cin.tie(0); 42 | auto x = intersect(7, 9, 13, 12); 43 | cout << x.first << ' ' << x.second << '\n'; 44 | return 0; 45 | } -------------------------------------------------------------------------------- /Number Theory/Rational Approximation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | using ll = long long; 5 | /** 6 | Given n and a real number x >= 0, returns the closest rational approximation p/q s.t. p, q <= n. 7 | It will obey that |p/q - x| is minimum for p, q <= n 8 | Time: O(log n) 9 | **/ 10 | using ld = long double; 11 | pair approximate(ld x, ll n) { 12 | ll LP = 0, LQ = 1, P = 1, Q = 0, inf = LLONG_MAX; ld y = x; 13 | while (1) { 14 | ll lim = min(P ? (n - LP) / P : inf, Q ? (n - LQ) / Q : inf), 15 | a = (ll)floor(y), b = min(a, lim), 16 | NP = b * P + LP, NQ = b * Q + LQ; 17 | if (a > b) { 18 | // If b > a/2, we have a semi-convergent that gives us a 19 | // better approximation; if b = a/2, we *may* have one. 20 | // Return {P, Q} here for a more canonical approximation. 21 | return (abs(x - (ld)NP / (ld)NQ) < abs(x - (ld)P / (ld)Q)) ? 22 | make_pair(NP, NQ) : make_pair(P, Q); 23 | } 24 | if (abs(y = 1 / (y - (ld)a)) > 3 * n) { 25 | return {NP, NQ}; 26 | } 27 | LP = P; P = NP; 28 | LQ = Q; Q = NQ; 29 | } 30 | } 31 | int32_t main() { 32 | ios_base::sync_with_stdio(0); 33 | cin.tie(0); 34 | int t; cin >> t; 35 | while (t--) { 36 | long double x; cin >> x; 37 | ll n = 1e9; 38 | auto ans = approximate(x, n); 39 | cout << ans.first << ' ' << ans.second << '\n'; 40 | } 41 | return 0; 42 | } 43 | // https://official.contest.yandex.ru/opencupXVIII/contest/5457/problems/E/?success=51368253#7/2017_10_14/fqGQVSrCf7 44 | -------------------------------------------------------------------------------- /Graph Theory/Prim's MST.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 2020; 5 | int g[N][N], w[N], to[N], selected[N]; 6 | long long Prims(int n, vector< pair > &edges) { 7 | long long ans = 0; 8 | for(int i = 1; i <= n; i++) w[i] = 1e9, selected[i] = 0, to[i] = -1; 9 | w[1] = 0; 10 | for(int i = 1; i <= n; i++) { 11 | int u = -1; 12 | for(int j = 1; j <= n; j++) if(!selected[j] && (u == -1 || w[j] < w[u])) u = j; 13 | if (w[u] == 1e9) return - 1; //NO MST 14 | selected[u] = 1; 15 | ans += w[u]; 16 | if(to[u] != -1) edges.emplace_back(u, to[u]); //order of the edges may be changed 17 | for(int v = 1; v <= n; v++) if(g[u][v] < w[v]) w[v] = g[u][v], to[v] = u; 18 | } 19 | return ans; 20 | } 21 | string s[N]; 22 | int main() { 23 | ios_base::sync_with_stdio(0); 24 | cin.tie(0); 25 | 26 | int n, m; cin >> n >> m; 27 | for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) g[i][j] = 1e9; 28 | for(int i = 1; i <= n; i++) cin >> s[i]; 29 | for(int i = 1; i <= n; i++){ 30 | for(int j = i + 1; j <= n; j++){ 31 | int w = 0; 32 | for(int k = 0; k < m; k++) w = max(w, (int)abs(s[i][k] - s[j][k])); 33 | g[i][j] = min(g[i][j], w); 34 | g[j][i] = min(g[j][i], w); 35 | } 36 | } 37 | vector< pair > ed; 38 | long long ans = Prims(n, ed); 39 | int res = 0; for(auto e: ed) res = max(res, g[e.first][e.second]); 40 | cout << res << '\n'; 41 | return 0; 42 | } 43 | /* 44 | https://www.codechef.com/ICL2016/problems/ICL16A 45 | */ 46 | -------------------------------------------------------------------------------- /Geometry/Maximum Area of Triangle, Given are Lengths.cpp: -------------------------------------------------------------------------------- 1 | #pragma GCC optimize("Ofast") 2 | #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,fma") 3 | #pragma GCC optimize("unroll-loops") 4 | 5 | #include 6 | using namespace std; 7 | 8 | const int N = 1e5 + 9; 9 | inline double area( double a, double b, double c ) { 10 | double p = (a + b + c) / 2; 11 | return p * (p - a) * (p - b) * (p - c); 12 | } 13 | 14 | bitset f; 15 | // values are distinct 16 | // find the maximum area triangle, given are lengths 17 | int32_t main() { 18 | ios_base::sync_with_stdio(0); 19 | cin.tie(0); 20 | int t; cin >> t; 21 | while (t--) { 22 | int n, m; cin >> n >> m; 23 | f.reset(); 24 | for (int i = 0; i < n; i++) { 25 | int k; cin >> k; 26 | f[k] = 1; 27 | } 28 | while (!f[m]) --m; 29 | double ans = 1e100; 30 | int a = 1; 31 | // triples are (a, b, c) (a < b < c) 32 | for (int d = 1; d * 2 <= m; d++) { // fix the difference between b and c 33 | while (a <= d or !f[a]) ++a; // find the first a > c 34 | auto g = f & (f >> d); 35 | int b = g._Find_next(a); // find the first b > a s.t. b and b + d is in the array 36 | if (b <= m) { 37 | ans = min(ans, area(a, b, b + d)); 38 | } 39 | } 40 | if (ans < 1e100) { 41 | cout << fixed << setprecision(10) << sqrt(ans) << '\n'; 42 | } 43 | else { 44 | cout << -1 << '\n'; 45 | } 46 | } 47 | return 0; 48 | } 49 | // https://codeforces.com/gym/100956/attachments 50 | // problem L 51 | -------------------------------------------------------------------------------- /Number Theory/Number of Distinct Kth Powers Modulo n.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | using ll = long long; 5 | ll power(ll n, ll k) { 6 | ll ans = 1; 7 | while (k--) { 8 | ans *= n; 9 | } 10 | return ans; 11 | } 12 | // returns the number of distinct values of (a^k % p^cnt) over all integers a (p is prime) 13 | // can be optimized by precalculating powers 14 | // current complexity: O(cnt * cnt) 15 | ll f(ll p, ll cnt, ll k) { 16 | if (cnt <= 0 or k == 0) return 1; 17 | if (p == 2) { 18 | if (cnt == 1) return 2; 19 | ll u = power(2, cnt - 2) / __gcd(k, power(2, cnt - 2)); 20 | if (k % 2) u *= 2; 21 | return u + f(2, cnt - k, k); 22 | } 23 | ll phi = power(p, cnt) - power(p, cnt - 1); 24 | ll u = phi / __gcd(k, phi); 25 | return u + f(p, cnt - k, k); 26 | } 27 | // returns the number of distinct values of (a^k % n) over all integers a 28 | ll yo(ll k, ll n) { 29 | ll ans = 1; 30 | for (ll i = 2; i * i <= n; i++) { 31 | if (n % i == 0) { 32 | int cnt = 0; 33 | while (n % i == 0) { 34 | cnt++; 35 | n /= i; 36 | } 37 | ans *= f(i, cnt, k); 38 | } 39 | } 40 | if (n > 1) ans *= f(n, 1, k); 41 | return ans; 42 | } 43 | int32_t main() { 44 | ios_base::sync_with_stdio(0); 45 | cin.tie(0); 46 | for (int k = 0; k <= 5; k++) { 47 | for (int p = 1; p <= 12; p++) { 48 | set se; 49 | for (int i = 0; i <= p; i++) { 50 | se.insert(power(i, k) % p); 51 | } 52 | assert(se.size() == yo(k, p)); 53 | } 54 | } 55 | return 0; 56 | } -------------------------------------------------------------------------------- /Math/Determinant under Prime Modulo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 105, mod = 998244353; 5 | 6 | int power(long long n, long long k) { 7 | int ans = 1 % mod; n %= mod; if (n < 0) n += mod; 8 | while (k) { 9 | if (k & 1) ans = (long long) ans * n % mod; 10 | n = (long long) n * n % mod; 11 | k >>= 1; 12 | } 13 | return ans; 14 | } 15 | int Gauss(vector> a) { 16 | int n = a.size(), m = (int)a[0].size(); 17 | int free_var = 0; 18 | const long long MODSQ = (long long)mod * mod; 19 | int det = 1, rank = 0; 20 | for (int col = 0, row = 0; col < m && row < n; col++) { 21 | int mx = row; 22 | for (int k = row; k < n; k++) if (a[k][col] > a[mx][col]) mx = k; 23 | if (a[mx][col] == 0) {det = 0; continue;} 24 | for (int j = col; j < m; j++) swap(a[mx][j], a[row][j]); 25 | if (row != mx) det = det == 0 ? 0 : mod - det; 26 | det = 1LL * det * a[row][col] % mod; 27 | int inv = power(a[row][col], mod - 2); 28 | for (int i = 0; i < n && inv; i++){ 29 | if (i != row && a[i][col]) { 30 | int x = ((long long)a[i][col] * inv) % mod; 31 | for (int j = col; j < m && x; j++){ 32 | if (a[row][j]) a[i][j] = (MODSQ + a[i][j] - ((long long)a[row][j] * x)) % mod; 33 | } 34 | } 35 | } 36 | row++; ++rank; 37 | } 38 | return det; 39 | } 40 | 41 | int32_t main() { 42 | int n; cin >> n; 43 | vector> a(n, vector(n)); 44 | for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) cin >> a[i][j]; 45 | cout << Gauss(a) << '\n'; 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /Strings/KMP.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9; 5 | 6 | // returns the longest proper prefix array of pattern p 7 | // where lps[i]=longest proper prefix which is also suffix of p[0...i] 8 | vector build_lps(string p) { 9 | int sz = p.size(); 10 | vector lps; 11 | lps.assign(sz + 1, 0); 12 | int j = 0; 13 | lps[0] = 0; 14 | for(int i = 1; i < sz; i++) { 15 | while(j >= 0 && p[i] != p[j]) { 16 | if(j >= 1) j = lps[j - 1]; 17 | else j = -1; 18 | } 19 | j++; 20 | lps[i] = j; 21 | } 22 | return lps; 23 | } 24 | vectorans; 25 | // returns matches in vector ans in 0-indexed 26 | void kmp(vector lps, string s, string p) { 27 | int psz = p.size(), sz = s.size(); 28 | int j = 0; 29 | for(int i = 0; i < sz; i++) { 30 | while(j >= 0 && p[j] != s[i]) 31 | if(j >= 1) j = lps[j - 1]; 32 | else j = -1; 33 | j++; 34 | if(j == psz) { 35 | j = lps[j - 1]; 36 | // pattern found in string s at position i-psz+1 37 | ans.push_back(i - psz + 1); 38 | } 39 | // after each loop we have j=longest common suffix of s[0..i] which is also prefix of p 40 | } 41 | } 42 | 43 | int main() { 44 | int i, j, k, n, m, t; 45 | cin >> t; 46 | while(t--) { 47 | string s, p; 48 | cin >> s >> p; 49 | vectorlps = build_lps(p); 50 | kmp(lps, s, p); 51 | if(ans.empty()) cout << "Not Found\n"; 52 | else { 53 | cout << ans.size() << endl; 54 | for(auto x : ans) cout << x << ' '; 55 | cout << endl; 56 | } 57 | ans.clear(); 58 | cout << endl; 59 | } 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /Math/Determinant under Composite Modulo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9; 5 | 6 | //O(n^3 logn) 7 | int Gauss(vector> a, const int mod) { 8 | int n = (int)a.size(); if (n != a[0].size()) return 0; 9 | int det = 1; 10 | for(int col = 0, row = 0; col < n && row < n; ++col) { 11 | int mx = row; 12 | for(int i = row; i < n; i++) if(a[i][col] > a[mx][col]) mx = i; 13 | if(a[mx][col] == 0) return 0; 14 | for(int i = col; i < n; i++) swap(a[row][i], a[mx][i]); 15 | if (row != mx) det = det == 0 ? 0: mod - det; 16 | for(int i = row + 1; i < n; i++) { 17 | while (a[row][col]) { 18 | int t = a[i][col] / a[row][col]; 19 | for (int j = col; j < n; j++) { 20 | a[i][j] -= 1LL * a[row][j] * t % mod; 21 | if (a[i][j] < 0) a[i][j] += mod; 22 | swap(a[i][j], a[row][j]); 23 | } 24 | det = det == 0 ? 0: mod - det; 25 | } 26 | for (int j = col; j < n; j++) swap(a[row][j], a[i][j]); 27 | det = det == 0 ? 0: mod - det; 28 | } 29 | det = 1LL * det * a[row][col] % mod; 30 | ++row; 31 | } 32 | return det; 33 | } 34 | int32_t main() { 35 | int n, mod; 36 | while (cin >> n >> mod) { 37 | vector> a(n, vector(n, 0)); 38 | for (int i = 0; i < n; i++) { 39 | for (int j = 0; j < n; j++) { 40 | int k; cin >> k; 41 | k %= mod; if (k < 0) k += mod; 42 | a[i][j] = k; 43 | } 44 | } 45 | cout << Gauss(a, mod) << '\n'; 46 | } 47 | return 0; 48 | } 49 | //https://www.spoj.com/problems/DETER3/en/ 50 | -------------------------------------------------------------------------------- /Graph Theory/LCA.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9, LG = 18; 5 | 6 | vector g[N]; 7 | int par[N][LG + 1], dep[N], sz[N]; 8 | void dfs(int u, int p = 0) { 9 | par[u][0] = p; 10 | dep[u] = dep[p] + 1; 11 | sz[u] = 1; 12 | for (int i = 1; i <= LG; i++) par[u][i] = par[par[u][i - 1]][i - 1]; 13 | for (auto v: g[u]) if (v != p) { 14 | dfs(v, u); 15 | sz[u] += sz[v]; 16 | } 17 | } 18 | int lca(int u, int v) { 19 | if (dep[u] < dep[v]) swap(u, v); 20 | for (int k = LG; k >= 0; k--) if (dep[par[u][k]] >= dep[v]) u = par[u][k]; 21 | if (u == v) return u; 22 | for (int k = LG; k >= 0; k--) if (par[u][k] != par[v][k]) u = par[u][k], v = par[v][k]; 23 | return par[u][0]; 24 | } 25 | int kth(int u, int k) { 26 | assert(k >= 0); 27 | for (int i = 0; i <= LG; i++) if (k & (1 << i)) u = par[u][i]; 28 | return u; 29 | } 30 | int dist(int u, int v) { 31 | int l = lca(u, v); 32 | return dep[u] + dep[v] - (dep[l] << 1); 33 | } 34 | //kth node from u to v, 0th node is u 35 | int go(int u, int v, int k) { 36 | int l = lca(u, v); 37 | int d = dep[u] + dep[v] - (dep[l] << 1); 38 | assert(k <= d); 39 | if (dep[l] + k <= dep[u]) return kth(u, k); 40 | k -= dep[u] - dep[l]; 41 | return kth(v, dep[v] - dep[l] - k); 42 | } 43 | int32_t main() { 44 | int n; cin >> n; 45 | for (int i = 1; i < n; i++) { 46 | int u, v; cin >> u >> v; 47 | g[u].push_back(v); 48 | g[v].push_back(u); 49 | } 50 | dfs(1); 51 | int q; cin >> q; 52 | while (q--) { 53 | int u, v; cin >> u >> v; 54 | cout << dist(u, v) << '\n'; 55 | } 56 | return 0; 57 | } -------------------------------------------------------------------------------- /Graph Theory/DAG Reachability Dynamic.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9; 5 | 6 | /*add_edge(s, t): insert edge (s,t) to the network if it does not make a cycle 7 | is_reachable(s, t): return true iff there is a path s --> t 8 | Algorithm by G.F. ITALIANO 9 | Complexity: amortized O(n) per update*/ 10 | //0-indexed 11 | struct Italiano { 12 | int n; 13 | vector> par; 14 | vector>> child; 15 | Italiano(int n) : n(n), par(n, vector(n, -1)), child(n, vector>(n)) { } 16 | bool is_reachable(int s, int t) { 17 | return s == t || par[s][t] >= 0; 18 | } 19 | bool add_edge(int s, int t) { 20 | if (is_reachable(t, s)) return 0; // break DAG condition 21 | if (is_reachable(s, t)) return 1; // no-modification performed 22 | for (int p = 0; p < n; ++p) { 23 | if (is_reachable(p, s) && !is_reachable(p, t)) meld(p, t, s, t); 24 | } 25 | return 1; 26 | } 27 | void meld(int root, int sub, int u, int v) { 28 | par[root][v] = u; 29 | child[root][u].push_back(v); 30 | for (int c : child[sub][v]) { 31 | if (!is_reachable(root, c)) meld(root, sub, v, c); 32 | } 33 | } 34 | }; 35 | //add edges one by one. if it breaks DAG law then print it 36 | int32_t main() { 37 | int n, m; 38 | cin >> n >> m; 39 | Italiano t(n); 40 | while(m--) { 41 | int u, v; 42 | cin >> u >> v; 43 | --u; --v; 44 | if(t.is_reachable(v, u)) cout << u + 1 << ' ' << v + 1 << '\n'; 45 | else t.add_edge(u, v); 46 | } 47 | cout << 0 << ' ' << 0 << '\n'; 48 | return 0; 49 | } 50 | // https://www.spoj.com/problems/GHOSTS/ 51 | -------------------------------------------------------------------------------- /Math/Integration (Romberg).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define double long double 5 | const double eps = 1e-6; 6 | 7 | int z, d; 8 | double f(double x) { 9 | double t1 = sqrt(x * x + z * z); 10 | double t2 = sqrt((x + d) * (x + d) + z * z); 11 | double w = (t2 - t1) + (d - (t2 - t1)) / 2.0; 12 | double ans = w * w * 0.5 + t1 * w; 13 | ans += (d - w) * (d - w) * 0.5 + t2 * (d - w); 14 | ans /= d; 15 | return ans; 16 | } 17 | double integrate(double l, double r){ 18 | vector t; 19 | double h = r - l; 20 | double last, curr; 21 | int k = 1; 22 | int i = 1; 23 | t.push_back(h * (f(l) + f(r)) / 2); 24 | while (true) { 25 | last = t.back(); curr = 0; 26 | double x = l + h / 2; 27 | for (int j = 0; j < k; j++) curr += f(x), x += h; 28 | curr = (t[0] + h * curr) / 2; 29 | double k1 = 4.0 / 3.0, k2 = 1.0 / 3.0; 30 | for (int j = 0; j < i; j++){ 31 | double temp = k1 * curr - k2 * t[j]; 32 | t[j] = curr; curr = temp; 33 | k2 /= 4 * k1 - k2; 34 | k1 = k2 + 1; 35 | } 36 | t.push_back(curr); 37 | k *= 2; h /= 2; i++; 38 | if (fabs(last - curr) < eps) break; 39 | } 40 | return t.back(); 41 | } 42 | int32_t main() { 43 | ios_base::sync_with_stdio(0); 44 | cin.tie(0); 45 | int t, cs = 0; cin >> t; 46 | while (t--) { 47 | int r, l; cin >> z >> r >> l >> d; 48 | r -= d; 49 | double ans; 50 | if (l == r) ans = f(l); 51 | else ans = integrate(l, r) / (r - l); 52 | cout << "Case " << ++cs << ": " << fixed << setprecision(10) << ans << '\n'; 53 | } 54 | return 0; 55 | } 56 | // https://vjudge.net/problem/UVA-12997 -------------------------------------------------------------------------------- /Number Theory/Tonelli Shanks Algorithm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9; 5 | 6 | int power(long long n, long long k, const int mod) { 7 | int ans = 1 % mod; n %= mod; if (n < 0) n += mod; 8 | while (k) { 9 | if (k & 1) ans = (long long) ans * n % mod; 10 | n = (long long) n * n % mod; 11 | k >>= 1; 12 | } 13 | return ans; 14 | } 15 | // find sqrt(a) % p, i.e. find any x such that x^2 = a (mod p) 16 | // if a solution exist, then if a == 0 or p == 2, there are 1 solution, otherwise, there are exactly 2 solutions (x and p - x) 17 | // p is prime 18 | // complexity: O(log^2 p) worst case, O(log p) on average 19 | int SQRT(int a, int p) { 20 | a %= p; if (a < 0) a += p; 21 | if (a == 0) return 0; 22 | if (power(a, (p - 1) / 2, p) != 1) return -1; // solution does not exist 23 | if (p % 4 == 3) return power(a, (p + 1) / 4, p); 24 | int s = p - 1, n = 2; 25 | int r = 0, m; 26 | while (s % 2 == 0) ++r, s /= 2; 27 | // find a non-square mod p 28 | while (power(n, (p - 1) / 2, p) != p - 1) ++n; 29 | int x = power(a, (s + 1) / 2, p); 30 | int b = power(a, s, p), g = power(n, s, p); 31 | for (;; r = m) { 32 | int t = b; 33 | for (m = 0; m < r && t != 1; ++m) t = 1LL * t * t % p; 34 | if (m == 0) return x; 35 | int gs = power(g, 1LL << (r - m - 1), p); 36 | g = 1LL * gs * gs % p; 37 | x = 1LL * x * gs % p; 38 | b = 1LL * b * g % p; 39 | } 40 | } 41 | int32_t main() { 42 | ios_base::sync_with_stdio(0); 43 | cin.tie(0); 44 | int t; cin >> t; 45 | while (t--) { 46 | int x, p; cin >> x >> p; 47 | cout << SQRT(x, p) << '\n'; 48 | } 49 | return 0; 50 | } -------------------------------------------------------------------------------- /Graph Theory/SCC.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int N = 3e5 + 9; 4 | 5 | // given a directed graph return the minimum number of edges to be added so that the whole graph become an SCC 6 | bool vis[N]; 7 | vector g[N], r[N], G[N], vec; //G is the condensed graph 8 | void dfs1(int u) { 9 | vis[u] = 1; 10 | for(auto v: g[u]) if(!vis[v]) dfs1(v); 11 | vec.push_back(u); 12 | } 13 | 14 | vector comp; 15 | void dfs2(int u) { 16 | comp.push_back(u); 17 | vis[u] = 1; 18 | for(auto v: r[u]) if(!vis[v]) dfs2(v); 19 | } 20 | 21 | int idx[N], in[N], out[N]; 22 | int main() { 23 | ios_base::sync_with_stdio(0); 24 | cin.tie(0); 25 | 26 | int n, m; 27 | cin >> n >> m; 28 | for(int i = 1; i <= m; i++) { 29 | int u, v; 30 | cin >> u >> v; 31 | g[u].push_back(v); 32 | r[v].push_back(u); 33 | } 34 | for(int i = 1; i <= n; i++) if(!vis[i]) dfs1(i); 35 | reverse(vec.begin(), vec.end()); 36 | memset(vis, 0, sizeof vis); 37 | int scc = 0; 38 | for(auto u: vec) { 39 | if(!vis[u]) { 40 | comp.clear(); 41 | dfs2(u); 42 | scc++; 43 | for(auto x: comp) idx[x]=scc; 44 | } 45 | } 46 | for(int u = 1; u <= n; u++) { 47 | for(auto v: g[u]) { 48 | if(idx[u] != idx[v]) { 49 | in[idx[v]]++, out[idx[u]]++; 50 | G[idx[u]].push_back(idx[v]); 51 | } 52 | } 53 | } 54 | int needed_in=0, needed_out=0; 55 | for(int i = 1; i <= scc; i++) { 56 | if(!in[i]) needed_in++; 57 | if(!out[i]) needed_out++; 58 | } 59 | int ans = max(needed_in, needed_out); 60 | if(scc == 1) ans = 0; 61 | cout << ans << '\n'; 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /Dynamic Programming Optimizations/Digit DP.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define ll long long 5 | #define eb emplace_back 6 | #define nl '\n' 7 | #define deb(x) cerr << #x" = " << x << nl 8 | #define in() ( { int a ; scanf("%d", &a); a; } ) 9 | 10 | const int N = 3e5 + 9; 11 | const int mod = 1e9 + 7; 12 | 13 | int pw[20][20], b[1 << 10][3000], cnt[1 << 10], dp[2][20][1 << 10][2520]; 14 | vector v; 15 | int yo(int i, int mask, int rem, int f) { 16 | if(i == -1) return pw[b[mask][rem]][cnt[mask]]; 17 | int &ret = dp[f][i][mask][rem]; 18 | if(ret != -1 && !f) return ret; 19 | int m = f ? v[i] : 9; 20 | int ans = 0; 21 | for(int k = 0; k <= m; k++) { 22 | ans += yo(i - 1, mask | (1 << k), (rem * 10 + k) % 2520, k == m ? f : 0); 23 | if(ans >= mod) ans -= mod; 24 | } 25 | if(!f) ret = ans; 26 | return ans; 27 | } 28 | int solve(ll n) { 29 | if(n == 0) return 0; 30 | v.clear(); 31 | while(n) { 32 | v.eb(n % 10); 33 | n /= 10; 34 | } 35 | return yo(v.size() - 1, 0, 0, 1); 36 | } 37 | int32_t main() { 38 | memset(dp, -1, sizeof dp); 39 | for(int i = 1; i < 20; i++) { 40 | pw[i][0] = 1; 41 | for(int k = 1; k < 20; k++) pw[i][k] = pw[i][k - 1] * 1LL * i % mod; 42 | } 43 | for(int mask = 1; mask < (1 << 10); mask++) cnt[mask] = __builtin_popcount(mask) - (mask & 1); 44 | for(int mask = 1; mask < (1 << 10); mask++) { 45 | for(int rem = 0; rem < 2530; rem++) { 46 | for(int i = 1; i < 10; i++) if(mask >> i & 1) b[mask][rem] += rem % i == 0; 47 | } 48 | } 49 | int t; 50 | cin >> t; 51 | while(t--) { 52 | ll l, r; 53 | cin >> l >> r; 54 | cout << (solve(r) - solve(l - 1) + mod) % mod << nl; 55 | } 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /Data Structures/LCA.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9, LG = 18; 5 | 6 | vector g[N]; 7 | int par[N][LG + 1], dep[N], sz[N]; 8 | void dfs(int u, int p = 0) { 9 | par[u][0] = p; 10 | dep[u] = dep[p] + 1; 11 | sz[u] = 1; 12 | for (int i = 1; i <= LG; i++) par[u][i] = par[par[u][i - 1]][i - 1]; 13 | for (auto v: g[u]) if (v != p) { 14 | dfs(v, u); 15 | sz[u] += sz[v]; 16 | } 17 | } 18 | int lca(int u, int v) { 19 | if (dep[u] < dep[v]) swap(u, v); 20 | for (int k = LG; k >= 0; k--) if (dep[par[u][k]] >= dep[v]) u = par[u][k]; 21 | if (u == v) return u; 22 | for (int k = LG; k >= 0; k--) if (par[u][k] != par[v][k]) u = par[u][k], v = par[v][k]; 23 | return par[u][0]; 24 | } 25 | int kth(int u, int k) { 26 | assert(k >= 0); 27 | for (int i = 0; i <= LG; i++) if (k & (1 << i)) u = par[u][i]; 28 | return u; 29 | } 30 | int dist(int u, int v) { 31 | int l = lca(u, v); 32 | return dep[u] + dep[v] - (dep[l] << 1); 33 | } 34 | //kth node from u to v, 0th node is u 35 | int go(int u, int v, int k) { 36 | int l = lca(u, v); 37 | int d = dep[u] + dep[v] - (dep[l] << 1); 38 | assert(k <= d); 39 | if (dep[l] + k <= dep[u]) return kth(u, k); 40 | k -= dep[u] - dep[l]; 41 | return kth(v, dep[v] - dep[l] - k); 42 | } 43 | int32_t main() { 44 | int n; cin >> n; 45 | for (int i = 1; i < n; i++) { 46 | int u, v; cin >> u >> v; 47 | g[u].push_back(v); 48 | g[v].push_back(u); 49 | } 50 | dfs(1); 51 | int q; cin >> q; 52 | while (q--) { 53 | int u, v; cin >> u >> v; 54 | cout << dist(u, v) << '\n'; 55 | } 56 | return 0; 57 | } -------------------------------------------------------------------------------- /Dynamic Programming Optimizations/Subset Union of Bitsets.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 2e5 + 9; 5 | 6 | int x[N], y[N], c[N], dp[1 << 20], msk[N], ans[N]; 7 | 8 | int32_t main() { 9 | ios_base::sync_with_stdio(0); 10 | cin.tie(0); 11 | int n, m, r; cin >> n >> m >> r; 12 | for (int i = 1; i <= n; i++) { 13 | cin >> x[i] >> y[i]; 14 | } 15 | // total m bitsets and size of each is n 16 | for (int i = 1; i <= m; i++) { 17 | int X, Y; cin >> X >> Y >> c[i]; 18 | for (int j = 1; j <= n; j++) { 19 | if (1LL * (X - x[j]) * (X - x[j]) + 1LL * (Y - y[j]) * (Y - y[j]) <= 1LL * r * r) { 20 | msk[j] |= 1 << (i - 1); 21 | } 22 | } 23 | } 24 | //msk[i] = mask of the i-th index 25 | for (int i = 1; i <= n; i++) { 26 | dp[msk[i] ^ ((1 << m) - 1)]++; 27 | } 28 | for (int i = 0; i < m; i++) { 29 | for (int mask = (1 << m) - 1; mask >= 0; mask--) { 30 | if (~mask >> i & 1) { 31 | dp[mask] += dp[mask ^ (1 << i)]; 32 | } 33 | } 34 | } 35 | // dp[mask] = n - (popcount of the union of the bitsets which are on in mask) 36 | for (int i = 1; i <= n; i++) { 37 | ans[i] = 2e9 + 9; 38 | } 39 | for (int mask = 0; mask < (1 << m); mask++) { 40 | int cost = 0; 41 | for (int i = 0; i < m; i++) { 42 | if (mask >> i & 1) { 43 | cost += c[i + 1]; 44 | } 45 | } 46 | ans[n - dp[mask]] = min(ans[n - dp[mask]], cost); 47 | } 48 | for (int i = n - 1; i >= 1; i--) { 49 | ans[i] = min(ans[i], ans[i + 1]); 50 | } 51 | for (int i = 1; i <= n; i++) { 52 | if (ans[i] == 2e9 + 9) ans[i] = -1; 53 | cout << ans[i] << '\n'; 54 | } 55 | return 0; 56 | } 57 | // https://tlx.toki.id/contests/troc-16/problems/F 58 | -------------------------------------------------------------------------------- /Math/Integration (Simpsons).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define double long double 5 | const double eps = 1e-6; 6 | 7 | int z, d; 8 | double f(double x) { 9 | double t1 = sqrt(x * x + z * z); 10 | double t2 = sqrt((x + d) * (x + d) + z * z); 11 | double w = (t2 - t1) + (d - (t2 - t1)) / 2.0; 12 | double ans = w * w * 0.5 + t1 * w; 13 | ans += (d - w) * (d - w) * 0.5 + t2 * (d - w); 14 | ans /= d; 15 | return ans; 16 | } 17 | inline double simpson(double fl, double fr, double fmid, double l, double r){ 18 | return (fl + fr + 4.0 * fmid) * (r - l) / 6.0; 19 | } 20 | double solve(double slr, double fl, double fr, double fmid, double l, double r){ 21 | double mid = (l + r) / 2; 22 | double fml = f((l + mid) / 2); 23 | double fmr = f((mid + r) / 2); 24 | double slm = simpson(fl, fmid, fml, l, mid); 25 | double smr = simpson(fmid, fr, fmr, mid, r); 26 | if (fabs(slr - slm - smr) < eps) return slm + smr; 27 | return solve(slm, fl, fmid, fml, l, mid) + solve(smr, fmid, fr, fmr, mid, r); 28 | } 29 | // integrate in range [l, r] 30 | double integrate(double l, double r){ 31 | double mid = (l + r) / 2, fl = f(l), fr = f(r), fmid = f(mid); 32 | double slr = simpson(fl, fr, fmid, l, r); 33 | return solve(slr, fl, fr, fmid, l, r); 34 | } 35 | int32_t main() { 36 | ios_base::sync_with_stdio(0); 37 | cin.tie(0); 38 | int t, cs = 0; cin >> t; 39 | while (t--) { 40 | int r, l; cin >> z >> r >> l >> d; 41 | r -= d; 42 | double ans; 43 | if (l == r) ans = f(l); 44 | else ans = integrate(l, r) / (r - l); 45 | cout << "Case " << ++cs << ": " << fixed << setprecision(10) << ans << '\n'; 46 | } 47 | return 0; 48 | } 49 | // https://vjudge.net/problem/UVA-12997 -------------------------------------------------------------------------------- /Miscellaneous/Subset Union of Bitsets.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 2e5 + 9; 5 | 6 | int x[N], y[N], c[N], dp[1 << 20], msk[N], ans[N]; 7 | int32_t main() { 8 | ios_base::sync_with_stdio(0); 9 | cin.tie(0); 10 | int n, m, r; cin >> n >> m >> r; 11 | for (int i = 1; i <= n; i++) { 12 | cin >> x[i] >> y[i]; 13 | } 14 | // total m bitsets and size of each is n 15 | for (int i = 1; i <= m; i++) { 16 | int X, Y; cin >> X >> Y >> c[i]; 17 | for (int j = 1; j <= n; j++) { 18 | if (1LL * (X - x[j]) * (X - x[j]) + 1LL * (Y - y[j]) * (Y - y[j]) <= 1LL * r * r) { 19 | msk[j] |= 1 << (i - 1); 20 | } 21 | } 22 | } 23 | //msk[i] = mask of the i-th index 24 | for (int i = 1; i <= n; i++) { 25 | dp[msk[i] ^ ((1 << m) - 1)]++; 26 | } 27 | for (int i = 0; i < m; i++) { 28 | for (int mask = (1 << m) - 1; mask >= 0; mask--) { 29 | if (~mask >> i & 1) { 30 | dp[mask] += dp[mask ^ (1 << i)]; 31 | } 32 | } 33 | } 34 | // dp[mask] = n - (popcount of the union of the bitsets which are on in mask) 35 | for (int i = 1; i <= n; i++) { 36 | ans[i] = 2e9 + 9; 37 | } 38 | for (int mask = 0; mask < (1 << m); mask++) { 39 | int cost = 0; 40 | for (int i = 0; i < m; i++) { 41 | if (mask >> i & 1) { 42 | cost += c[i + 1]; 43 | } 44 | } 45 | ans[n - dp[mask]] = min(ans[n - dp[mask]], cost); 46 | } 47 | for (int i = n - 1; i >= 1; i--) { 48 | ans[i] = min(ans[i], ans[i + 1]); 49 | } 50 | for (int i = 1; i <= n; i++) { 51 | if (ans[i] == 2e9 + 9) ans[i] = -1; 52 | cout << ans[i] << '\n'; 53 | } 54 | return 0; 55 | } 56 | // https://tlx.toki.id/contests/troc-16/problems/F -------------------------------------------------------------------------------- /Number Theory/Primitive Root.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int totient(int n) { 5 | int ans = n; 6 | for (int i = 2; i * i <= n; i++) { 7 | if (n % i == 0) { 8 | while (n % i == 0) n /= i; 9 | ans = ans / i * (i - 1); 10 | } 11 | } 12 | if (n > 1) ans = ans / n * (n - 1); 13 | return ans; 14 | } 15 | int power(int a, int b, int m) { 16 | int res = 1; 17 | while (b > 0) { 18 | if (b & 1) res = 1LL * res * a % m; 19 | a = 1LL * a * a % m; 20 | b >>= 1; 21 | } 22 | return res; 23 | } 24 | // g is a primitive root modulo p if and only if for any integer a such that 25 | // gcd(a, p) = 1, there exists an integer k such that: g^k = a(mod p). 26 | // primitive root modulo n exists iff n = 1, 2, 4 or n = p^k or 2 * p^k for some odd prime p 27 | int primitive_root(int p) { 28 | // first check if primitive root exists or not. I have omitted this part here 29 | vector fact; 30 | int phi = totient(p), n = phi; 31 | for (int i = 2; i * i <= n; ++i) { 32 | if (n % i == 0) { 33 | fact.push_back(i); 34 | while (n % i == 0) n /= i; 35 | } 36 | } 37 | if (n > 1) fact.push_back(n); 38 | for (int res = 2; res <= p; ++res) { // this loop will run at most (logp ^ 6) times i.e. until a root is found 39 | bool ok = true; 40 | // check if this is a primitive root modulo p 41 | for (size_t i = 0; i < fact.size() && ok; ++i) 42 | ok &= power(res, phi / fact[i], p) != 1; 43 | if (ok) return res; 44 | } 45 | return -1; 46 | } 47 | int32_t main() { 48 | ios_base::sync_with_stdio(0); 49 | cin.tie(0); 50 | cout << primitive_root(200003) << '\n'; 51 | return 0; 52 | } 53 | // https://cp-algorithms.com/algebra/primitive-root.html 54 | -------------------------------------------------------------------------------- /Data Structures/Segment Tree Lazy.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 5e5 + 9; 5 | int a[N]; 6 | struct ST { 7 | #define lc (n << 1) 8 | #define rc ((n << 1) | 1) 9 | long long t[4 * N], lazy[4 * N]; 10 | ST() { 11 | memset(t, 0, sizeof t); 12 | memset(lazy, 0, sizeof lazy); 13 | } 14 | inline void push(int n, int b, int e) { 15 | if (lazy[n] == 0) return; 16 | t[n] = t[n] + lazy[n] * (e - b + 1); 17 | if (b != e) { 18 | lazy[lc] = lazy[lc] + lazy[n]; 19 | lazy[rc] = lazy[rc] + lazy[n]; 20 | } 21 | lazy[n] = 0; 22 | } 23 | inline long long combine(long long a,long long b) { 24 | return a + b; 25 | } 26 | inline void pull(int n) { 27 | t[n] = t[lc] + t[rc]; 28 | } 29 | void build(int n, int b, int e) { 30 | lazy[n] = 0; 31 | if (b == e) { 32 | t[n] = a[b]; 33 | return; 34 | } 35 | int mid = (b + e) >> 1; 36 | build(lc, b, mid); 37 | build(rc, mid + 1, e); 38 | pull(n); 39 | } 40 | void upd(int n, int b, int e, int i, int j, long long v) { 41 | push(n, b, e); 42 | if (j < b || e < i) return; 43 | if (i <= b && e <= j) { 44 | lazy[n] = v; //set lazy 45 | push(n, b, e); 46 | return; 47 | } 48 | int mid = (b + e) >> 1; 49 | upd(lc, b, mid, i, j, v); 50 | upd(rc, mid + 1, e, i, j, v); 51 | pull(n); 52 | } 53 | long long query(int n, int b, int e, int i, int j) { 54 | push(n, b, e); 55 | if (i > e || b > j) return 0; //return null 56 | if (i <= b && e <= j) return t[n]; 57 | int mid = (b + e) >> 1; 58 | return combine(query(lc, b, mid, i, j), query(rc, mid + 1, e, i, j)); 59 | } 60 | }; 61 | int32_t main() { 62 | 63 | } 64 | -------------------------------------------------------------------------------- /Graph Theory/Min Cut in a Planar Graph.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e6 + 9; 5 | vector> g[N]; 6 | vector dijkstra(int s, int t, vector> g[]) { 7 | int n = t; 8 | const long long inf = 1e18; 9 | priority_queue, vector>, greater>> q; 10 | vector d(n + 1, inf); 11 | vector vis(n + 1, 0); 12 | q.push({0, s}); 13 | d[s] = 0; 14 | while(!q.empty()) { 15 | auto x = q.top(); 16 | q.pop(); 17 | int u = x.second; 18 | if(vis[u]) continue; 19 | vis[u] = 1; 20 | for(auto y : g[u]) { 21 | int v = y.first; 22 | long long w = y.second; 23 | if(d[u] + w < d[v]) { 24 | d[v] = d[u] + w; 25 | q.push({d[v], v}); 26 | } 27 | } 28 | } 29 | return d; 30 | } 31 | int n, s, t, a[N]; 32 | inline void add_edge(int u, int v) { 33 | if (u == -69 || v == -69 || u == v) return; 34 | int w = a[u] + a[v]; 35 | g[u].push_back({v, w}); 36 | g[v].push_back({u, w}); 37 | } 38 | inline int id(int i, int j) { 39 | if (i < 0 || i >= n) return -69; 40 | if (j < 0) return s; 41 | if (j >= n) return t; 42 | return i * n + j; 43 | } 44 | int32_t main() { 45 | ios_base::sync_with_stdio(0); 46 | cin.tie(0); 47 | cin >> n; 48 | s = n * n + 1; 49 | t = s + 1; 50 | for (int i = 0; i < n; i++) { 51 | for (int j = 0; j < n; j++) { 52 | cin >> a[id(i, j)]; 53 | } 54 | } 55 | for (int i = 0; i < n; i++) { 56 | for (int j = 0; j <= n; j++) { 57 | add_edge(id(i, j), id(i - 1, j)); 58 | add_edge(id(i, j), id(i, j - 1)); 59 | } 60 | } 61 | cout << dijkstra(s, t, g)[t] << '\n'; 62 | return 0; 63 | } 64 | //https://www.spoj.com/problems/ADAHOSE/ 65 | -------------------------------------------------------------------------------- /Graph Theory/Minimum Weight Cycle For Each Vertex.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 305, inf = 1e9; 5 | 6 | int g[N][N], d[N], vis[N], par[N]; 7 | int32_t main() { 8 | ios_base::sync_with_stdio(0); 9 | cin.tie(0); 10 | int n; cin >> n; 11 | for (int i = 1; i <= n; i++) { 12 | for (int j = 1; j <= n; j++) { 13 | cin >> g[i][j]; 14 | if (g[i][j] == -1) { 15 | g[i][j] = inf; 16 | } 17 | } 18 | } 19 | for (int u = 1; u <= n; u++) { 20 | memset(vis, 0, sizeof vis); 21 | for (int i = 0; i <= n; i++) { 22 | d[i] = inf; par[i] = i; 23 | } 24 | d[u] = 0; 25 | par[u] = u; 26 | int ans = inf; 27 | while (1) { 28 | int cur = 0; 29 | for (int i = 1; i <= n; i++) { 30 | if (!vis[i] and d[i] < d[cur]) { 31 | cur = i; 32 | } 33 | } 34 | if (cur == 0) break; 35 | if (vis[cur]) break; 36 | vis[cur] = 1; 37 | if (par[cur] != cur) { 38 | ans = min(ans, d[cur] + g[cur][u]); 39 | } 40 | for (int i = 1; i <= n; i++) { 41 | if (i != u) { 42 | if (vis[i]) { 43 | if (par[i] != par[cur]) { 44 | ans = min(ans, d[cur] + d[i] + g[cur][i]); 45 | } 46 | } 47 | else if (d[cur] + g[cur][i] < d[i]) { 48 | d[i] = d[cur] + g[cur][i]; 49 | if (cur == u) { 50 | par[i] = i; 51 | } 52 | else { 53 | par[i] = par[cur]; 54 | } 55 | } 56 | } 57 | } 58 | } 59 | if (ans == inf) ans = -1; 60 | cout << ans << '\n'; 61 | } 62 | return 0; 63 | } 64 | // https://codeforces.com/gym/100917/problem/F 65 | -------------------------------------------------------------------------------- /Data Structures/Divide and Conquer for Insert and Query Problems.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | if problems have following characteristics- 3 | 1.it can be solved offline 4 | 2.if every insert operations were before query operations 5 | each query operations could have been solved in O(L)(i mean faster like logn) 6 | 3.query operation is cumulative i.e. we don't need every insert at once to solve this query 7 | this type of problem can be solved using divide and conquer 8 | complexity: nlogn*O(L) 9 | **/ 10 | Problem: 11 | 12 | You have an empty set. You need to perform following operations – 13 | Insert a given number X in the set. 14 | Count how many numbers in the set is less than or equal to a given number X 15 | 16 | Solution: 17 | 18 | op[1...n] = operations 19 | ans[1...n] = array to store answers 20 | solve(l, r) { 21 | if op[l...r] has no queries: return 22 | m = (l + r) / 2 23 | ds = statically built DS using insert operations in op[l...m] 24 | for each query operation i in op[m+1...r]: 25 | ans[i] += ds.query(op[i]) 26 | solve(l, m) 27 | solve(m+1, r) 28 | } 29 | 30 | /** 31 | some dp can be solved using this trick 32 | **/ 33 | Problem: 34 | 35 | Lets have a look at the LIS problem. it has following solution- 36 | for(int i = 1; i <= n; i++) { 37 | for(int j = 1; j < i; j++) if(a[j] < a[i]) 38 | dp[i] = max(dp[i], dp[j] + 1) 39 | } 40 | it can modeled like update-query problem 41 | for(int i = 1; i <= n; i++) { 42 | dp[i] = query(a[i]); 43 | insert({a[i], dp[i]}); 44 | } 45 | 46 | Solution: 47 | 48 | solve(l, r) { 49 | m = (l + r) / 2 50 | solve(l, m) 51 | make ds with a[l..m] and dp[l..m] 52 | update dp[m+1..r] using the ds 53 | solve(m+1, r) 54 | } 55 | -------------------------------------------------------------------------------- /Data Structures/Augmented DSU.cpp: -------------------------------------------------------------------------------- 1 | /* Augmented Dsu 2 | Application:- used for maintaining a system of equations of the form ( y-x = d ) along 3 | with their consistencial queries dynamically using disjoint set union and find data structure. 4 | Inspired by the problem http://www.spoj.com/problems/CHAIN/ which utilises this concept, which can extended for solving 5 | problems of kind as explained above. 6 | Credit:Arpit Gupta(@alphawizard) 7 | */ 8 | #include 9 | using namespace std; 10 | const int N = 10000; 11 | int flaw; //counting numbers of inconsistent assertions 12 | int pot[N], prec[N]; 13 | 14 | void initialize(int n) { 15 | flaw = 0; 16 | for(int i = 1; i <= n; ++i) { 17 | prec[i] = i; 18 | pot[i] = 0; 19 | } 20 | 21 | } 22 | int find(int x) { 23 | if(prec[x] == x) return x; 24 | int rx = find(prec[x]); // rx is the root of x 25 | pot[x] = pot[prec[x]] + pot[x]; //add all potentials along the path,i.e.,potential calculated wrt root 26 | prec[x] = rx; 27 | return rx; 28 | } 29 | void merge(int a, int b, int d) { 30 | int ra = find(a); 31 | int rb = find(b); 32 | if(ra == rb && pot[a] - pot[b] != d) flaw++; 33 | else if(ra != rb) { 34 | pot[ra] = d + pot[b] - pot[a]; 35 | prec[ra] = rb; 36 | } 37 | } 38 | int main() { 39 | int n; //no. of variables 40 | cin >> n; 41 | int m; // no. of equations 42 | cin >> m; 43 | initialize(n); 44 | for(int i = 1; i <= m; ++i) { //consider 1-based indexing of variables 45 | int a, b, d; //asserting a-b=d; 46 | cin >> a >> b >> d; 47 | merge(a, b, d); 48 | } 49 | cout << "No. of inconsistencies= " << flaw; 50 | //queries of type y-x=? can be given through pot[y]-pot[x] (only when then are in same component 51 | //i.e., can be extracted from the information so far ) 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /Data Structures/MOs Algorithm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1e6 + 9, B = 440; 5 | 6 | struct query { 7 | int l, r, id; 8 | bool operator < (const query &x) const { 9 | if(l / B == x.l / B) return ((l / B) & 1) ? r > x.r : r < x.r; 10 | return l / B < x.l / B; 11 | } 12 | } Q[N]; 13 | int cnt[N], a[N]; 14 | long long sum; 15 | inline void add_left(int i) { 16 | int x = a[i]; 17 | sum += 1LL * (cnt[x] + cnt[x] + 1) * x; 18 | ++cnt[x]; 19 | } 20 | inline void add_right(int i) { 21 | int x = a[i]; 22 | sum += 1LL * (cnt[x] + cnt[x] + 1) * x; 23 | ++cnt[x]; 24 | } 25 | inline void rem_left(int i) { 26 | int x = a[i]; 27 | sum -= 1LL * (cnt[x] + cnt[x] - 1) * x; 28 | --cnt[x]; 29 | } 30 | inline void rem_right(int i) { 31 | int x = a[i]; 32 | sum -= 1LL * (cnt[x] + cnt[x] - 1) * x; 33 | --cnt[x]; 34 | } 35 | long long ans[N]; 36 | int32_t main() { 37 | ios_base::sync_with_stdio(0); 38 | cin.tie(0); 39 | 40 | int n, q; 41 | cin >> n >> q; 42 | for(int i = 1; i <= n; i++) cin >> a[i]; 43 | for(int i = 1; i <= q; i++) { 44 | cin >> Q[i].l >> Q[i].r; 45 | Q[i].id = i; 46 | } 47 | sort(Q + 1, Q + q + 1); 48 | int l = 1, r = 0; 49 | for(int i = 1; i <= q; i++) { 50 | int L = Q[i].l, R = Q[i].r; 51 | if(R < l) { 52 | while (l > L) add_left(--l); 53 | while (l < L) rem_left(l++); 54 | while (r < R) add_right(++r); 55 | while (r > R) rem_right(r--); 56 | } else { 57 | while (r < R) add_right(++r); 58 | while (r > R) rem_right(r--); 59 | while (l > L) add_left(--l); 60 | while (l < L) rem_left(l++); 61 | } 62 | ans[Q[i].id] = sum; 63 | } 64 | for(int i = 1; i <= q; i++) cout << ans[i] << '\n'; 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /Number Theory/Pells Equation.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from math import sqrt 3 | 4 | # continued fraction of sqrt(x) 5 | # there will always be a cycle of size <= 2 * sqrt(x) in the continued fraction 6 | def get_continued_fraction(ans, x): 7 | a0 = int(sqrt(x)) 8 | n, m, a = 1, 0, 0 9 | f = True 10 | if (a0 * a0 != x): 11 | while (a != 2 * a0): 12 | m = n * a - m; 13 | n = (x - m * m) / n; 14 | a = int((a0 + m) / n); 15 | if not f: 16 | ans.append(a) 17 | f = False 18 | 19 | # generating (x, y) 20 | def gen(a, x, y, i, cur): 21 | if (i >= cur): 22 | return x * a[i] + 1, a[i] 23 | else: 24 | rx, ry = gen(a, y, a[i + 1], i + 1, cur) 25 | x = x * rx + ry 26 | y = rx 27 | return x, y 28 | 29 | # generate the solutions to the equation x^2 - n*y^2 = 1 30 | # (1, 0) is always a solution, so try to generate a solution with positive x and y 31 | # O(sqrt(n)) but solutions can be too large 32 | # when n > 1e6 it gets RecursionError 33 | # when n is a square or n <= 0, it outputs (1, 0) only 34 | def main(): 35 | n = int(input()) 36 | a = [] 37 | if n >= 0: 38 | get_continued_fraction(a, n) 39 | cycle = len(a) - 1 40 | p, q = 1, 0 41 | if (cycle > 0): 42 | if (cycle % 2 == 0): 43 | p, q = gen(a, a[0], a[1], 1, cycle - 2) 44 | else: 45 | a += a[1:] + a[1:] 46 | p, q = gen(a, a[0], a[1], 1, 2 * cycle - 1) 47 | 48 | # printing first k solutions with increasing (x, y) 49 | k = 5 50 | x, y = p, q 51 | print(x, y) 52 | lx, ly = x, y 53 | for _ in range(k - 1): 54 | cx = lx * x + n * ly * y 55 | cy = lx * y + ly * x 56 | print(cx, cy) 57 | lx, ly = cx, cy 58 | 59 | if __name__ == '__main__': 60 | main() 61 | 62 | # https://brilliant.org/wiki/quadratic-diophantine-equations-pells-equation/ -------------------------------------------------------------------------------- /Data Structures/Persistent Trie.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | // find maximum value (x^a[j]) in the range (l,r) where l<=j<=r 6 | const int N = 1e5 + 100; 7 | const int K = 15; 8 | 9 | struct node_t; 10 | typedef node_t * pnode; 11 | 12 | struct node_t { 13 | int time; 14 | pnode to[2]; 15 | node_t() : time(0) { 16 | to[0] = to[1] = 0; 17 | } 18 | bool go(int l) const { 19 | if (!this) return false; 20 | return time >= l; 21 | } 22 | pnode clone() { 23 | pnode cur = new node_t(); 24 | if (this) { 25 | cur->time = time; 26 | cur->to[0] = to[0]; 27 | cur->to[1] = to[1]; 28 | } 29 | return cur; 30 | } 31 | }; 32 | 33 | pnode last; 34 | pnode version[N]; 35 | 36 | void insert(int a, int time) { 37 | pnode v = version[time] = last = last->clone(); 38 | for (int i = K - 1; i >= 0; --i) { 39 | int bit = (a >> i) & 1; 40 | pnode &child = v->to[bit]; 41 | child = child->clone(); 42 | v = child; 43 | v->time = time; 44 | } 45 | } 46 | 47 | int query(pnode v, int x, int l) { 48 | int ans = 0; 49 | for (int i = K - 1; i >= 0; --i) { 50 | int bit = (x >> i) & 1; 51 | if (v->to[bit]->go(l)) { // checking if this bit was inserted before the range 52 | ans |= 1 << i; 53 | v = v->to[bit]; 54 | } else { 55 | v = v->to[bit ^ 1]; 56 | } 57 | } 58 | return ans; 59 | } 60 | 61 | void solve() { 62 | int n, q; 63 | scanf("%d %d", &n, &q); 64 | last = 0; 65 | for (int i = 0; i < n; ++i) { 66 | int a; 67 | scanf("%d", &a); 68 | insert(a, i); 69 | } 70 | while (q--) { 71 | int x, l, r; 72 | scanf("%d %d %d", &x, &l, &r); 73 | --l, --r; 74 | printf("%d\n", query(version[r], ~x, l)); 75 | // Trie version[r] contains the trie for [0...r] elements 76 | } 77 | } 78 | // credit: mochow13 79 | -------------------------------------------------------------------------------- /Graph Theory/HopCroft Karp Algorithm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9; 5 | 6 | struct HopcroftKarp { 7 | static const int inf = 1e9; 8 | int n; 9 | vector l, r, d; 10 | vector> g; 11 | HopcroftKarp(int _n, int _m) { 12 | n = _n; 13 | int p = _n + _m + 1; 14 | g.resize(p); 15 | l.resize(p, 0); 16 | r.resize(p, 0); 17 | d.resize(p, 0); 18 | } 19 | void add_edge(int u, int v) { 20 | g[u].push_back(v + n); //right id is increased by n, so is l[u] 21 | } 22 | bool bfs() { 23 | queue q; 24 | for (int u = 1; u <= n; u++) { 25 | if (!l[u]) d[u] = 0, q.push(u); 26 | else d[u] = inf; 27 | } 28 | d[0] = inf; 29 | while (!q.empty()) { 30 | int u = q.front(); 31 | q.pop(); 32 | for (auto v : g[u]) { 33 | if (d[r[v]] == inf) { 34 | d[r[v]] = d[u] + 1; 35 | q.push(r[v]); 36 | } 37 | } 38 | } 39 | return d[0] != inf; 40 | } 41 | bool dfs(int u) { 42 | if (!u) return true; 43 | for (auto v : g[u]) { 44 | if(d[r[v]] == d[u] + 1 && dfs(r[v])) { 45 | l[u] = v; 46 | r[v] = u; 47 | return true; 48 | } 49 | } 50 | d[u] = inf; 51 | return false; 52 | } 53 | int maximum_matching() { 54 | int ans = 0; 55 | while (bfs()) { 56 | for(int u = 1; u <= n; u++) if (!l[u] && dfs(u)) ans++; 57 | } 58 | return ans; 59 | } 60 | }; 61 | int32_t main() { 62 | ios_base::sync_with_stdio(0); 63 | cin.tie(0); 64 | int n, m, q; 65 | cin >> n >> m >> q; 66 | HopcroftKarp M(n, m); 67 | while (q--) { 68 | int u, v; 69 | cin >> u >> v; 70 | M.add_edge(u, v); 71 | } 72 | cout << M.maximum_matching() << '\n'; 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /Math/Gaussian Elimination.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9; 5 | 6 | const double eps = 1e-9; 7 | int Gauss(vector> a, vector &ans) { 8 | int n = (int)a.size(), m = (int)a[0].size() - 1; 9 | vector pos(m, -1); 10 | double det = 1; int rank = 0; 11 | for(int col = 0, row = 0; col < m && row < n; ++col) { 12 | int mx = row; 13 | for(int i = row; i < n; i++) if(fabs(a[i][col]) > fabs(a[mx][col])) mx = i; 14 | if(fabs(a[mx][col]) < eps) {det = 0; continue;} 15 | for(int i = col; i <= m; i++) swap(a[row][i], a[mx][i]); 16 | if (row != mx) det = -det; 17 | det *= a[row][col]; 18 | pos[col] = row; 19 | for(int i = 0; i < n; i++) { 20 | if(i != row && fabs(a[i][col]) > eps) { 21 | double c = a[i][col] / a[row][col]; 22 | for(int j = col; j <= m; j++) a[i][j] -= a[row][j] * c; 23 | } 24 | } 25 | ++row; ++rank; 26 | } 27 | ans.assign(m, 0); 28 | for(int i = 0; i < m; i++) { 29 | if(pos[i] != -1) ans[i] = a[pos[i]][m] / a[pos[i]][i]; 30 | } 31 | for(int i = 0; i < n; i++) { 32 | double sum = 0; 33 | for(int j = 0; j < m; j++) sum += ans[j] * a[i][j]; 34 | if(fabs(sum - a[i][m]) > eps) return -1; //no solution 35 | } 36 | for(int i = 0; i < m; i++) if(pos[i] == -1) return 2; //infinte solutions 37 | return 1; //unique solution 38 | } 39 | int main() { 40 | int n, m; cin >> n >> m; 41 | vector< vector > v(n); 42 | for(int i = 0; i < n; i++) { 43 | for(int j = 0; j <= m; j++) { 44 | double x; cin >> x; v[i].push_back(x); 45 | } 46 | } 47 | vector ans; 48 | int k = Gauss(v, ans); 49 | if(k) for(int i = 0; i < n; i++) cout << fixed << setprecision(5) << ans[i] << ' '; 50 | else cout << "no solution\n"; 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /Graph Theory/Dijkstra.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9, mod = 998244353; 5 | 6 | int n, m; 7 | vector> g[N], r[N]; 8 | vector dijkstra(int s, int t, vector &cnt) { 9 | const long long inf = 1e18; 10 | priority_queue, vector>, greater>> q; 11 | vector d(n + 1, inf); 12 | vector vis(n + 1, 0); 13 | q.push({0, s}); 14 | d[s] = 0; 15 | cnt.resize(n + 1, 0); // number of shortest paths 16 | cnt[s] = 1; 17 | while(!q.empty()) { 18 | auto x = q.top(); 19 | q.pop(); 20 | int u = x.second; 21 | if(vis[u]) continue; 22 | vis[u] = 1; 23 | for(auto y: g[u]) { 24 | int v = y.first; 25 | long long w = y.second; 26 | if(d[u] + w < d[v]) { 27 | d[v] = d[u] + w; 28 | q.push({d[v], v}); 29 | cnt[v] = cnt[u]; 30 | } else if(d[u] + w == d[v]) cnt[v] = (cnt[v] + cnt[u]) % mod; 31 | } 32 | } 33 | return d; 34 | } 35 | 36 | int u[N], v[N], w[N]; 37 | int32_t main() { 38 | ios_base::sync_with_stdio(0); 39 | cin.tie(0); 40 | 41 | int s, t; 42 | cin >> n >> m >> s >> t; 43 | for(int i = 1; i <= m; i++) { 44 | cin >> u[i] >> v[i] >> w[i]; 45 | g[u[i]].push_back({v[i], w[i]}); 46 | r[v[i]].push_back({u[i], w[i]}); 47 | } 48 | vector cnt1, cnt2; 49 | auto d1 = dijkstra(s, t, cnt1); 50 | auto d2 = dijkstra(t, s, cnt2); 51 | 52 | long long ans = d1[t]; 53 | for(int i = 1; i <= m; i++) { 54 | int x = u[i], y = v[i]; 55 | long long nw = d1[x] + w[i] + d2[y]; 56 | if(nw == ans && 1LL * cnt1[x] * cnt2[y] % mod == cnt1[t]) cout << "YES\n"; 57 | else if(nw - ans + 1 < w[i]) cout << "CAN " << nw - ans + 1 << '\n'; 58 | else cout << "NO\n"; 59 | } 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /Graph Theory/Minimum Mean Weight Cycle.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 26 * 27; 5 | 6 | vector> g[N]; 7 | bool vis[N]; 8 | double d[N]; 9 | bool spfa(int u, double x) { 10 | vis[u] = 1; 11 | for(auto e : g[u]) { 12 | double w = -x + e.second; 13 | int v = e.first; 14 | if(d[u] + w > d[v]) { // d[u] + w < d[v] for minimum mean weight 15 | if(vis[v]) return 0; 16 | d[v] = d[u] + w; 17 | if(!spfa(v, x)) return 0; 18 | } 19 | } 20 | vis[u] = 0; 21 | return 1; 22 | } 23 | 24 | bool ok(int n, double x) { 25 | for(int i = 1; i <= n; i++) d[i] = 0, vis[i] = 0; 26 | for(int s = 1; s <= n; s++) { 27 | if(!spfa(s, x)) return 1; 28 | } 29 | return 0; 30 | } 31 | void add_edge(char a, char b, char c, char d, int w) { 32 | int u = (a - 'a') * 26 + (b - 'a' + 1); 33 | int v = (c - 'a') * 26 + (d - 'a' + 1); 34 | g[u].push_back({v, w}); 35 | } 36 | //this code is for MAXIMUM mean weight cycle 37 | int32_t main() { 38 | ios_base::sync_with_stdio(0); 39 | cin.tie(0); 40 | 41 | int n, m; 42 | while(cin >> n && n) { 43 | for(int i = 1; i <= n; i++) { 44 | string s; 45 | cin >> s; 46 | int len = s.size(); 47 | if(len < 2) continue; 48 | add_edge(s[0], s[1], s[len - 2], s[len - 1], len); 49 | } 50 | int n = 26 * 26; 51 | double l = 0, r = 1010; 52 | int it = 200; 53 | while(it--) { 54 | double mid = (l + r) * 0.5; 55 | if(ok(n, mid)) l = mid; //r = mid for minimum 56 | else r = mid; // l = mid = for minimum 57 | } 58 | if(l == 0.0) cout << "No solution.\n"; //l = 1010.0 for mimimum 59 | else cout << fixed << setprecision(2) << l << '\n'; 60 | for(int i = 0; i < N; i++) g[i].clear(); 61 | } 62 | return 0; 63 | } 64 | //https://www.spoj.com/problems/WORDRING/ 65 | -------------------------------------------------------------------------------- /Number Theory/Number of ax%p in a Range.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | using ll = long long; 5 | 6 | // number of integer solutions to ax + by <= c s.t. x, y >= 0 7 | ll lattice_cnt(ll a, ll b, ll c) { 8 | assert(a >= 0 && b >= 0); 9 | if (c < 0) return 0; 10 | if (a == 0 or b == 0) { 11 | // infinite solutions 12 | assert(0); 13 | return -1; 14 | } 15 | assert(a > 0 && b > 0); 16 | if (a > b) swap(a, b); 17 | ll ans = 0; 18 | while (c >= 0) { 19 | ll k = b / a; 20 | ll l = b % a; 21 | ll f = c / b; 22 | ll e = c % b / a; 23 | ll g = c % b % a; 24 | ans += (f + 1) * (e + 1) + (f + 1) * f / 2 * k; 25 | c = f * l - a + g; 26 | b = a; 27 | a = l; 28 | } 29 | return ans; 30 | } 31 | // returns the number of 0 <= (a * x % m) <= c s.t. 0 <= x <= n 32 | ll mod_count(ll a, ll m, ll c, ll n) { 33 | ++c; ++n; 34 | assert(m > 0); 35 | if (n == 0) return 0; 36 | a %= m; if (a < 0) a += m; 37 | ll extra_c = c / m; c %= m; 38 | if (c < 0) extra_c--, c += m; 39 | assert(0 <= c && c < m); 40 | ll ans = extra_c * n; 41 | ll extra_n = n / m; n %= m; 42 | if (n < 0) extra_n--, n += m; 43 | assert(0 <= n && n < m); 44 | if (extra_n) { 45 | ans += extra_n * (lattice_cnt(m, a + m, (a + m) * (m - 1)) - lattice_cnt(m, a + m, (a + m) * (m - 1) - c)); 46 | } 47 | if (n) { 48 | ans += lattice_cnt(m, a + m, (a + m) * (n - 1)) - lattice_cnt(m, a + m, (a + m) * (n - 1) - c); 49 | } 50 | return ans; 51 | } 52 | // returns the count of nlo <= x <= nhi s.t. clo <= (a * x % m) <= chi 53 | ll mod_count_range(ll a, ll m, ll clo, ll chi, ll nlo, ll nhi) { 54 | return mod_count(a, m, chi, nhi) - mod_count(a, m, chi, nlo - 1) - mod_count(a, m, clo - 1, nhi) + mod_count(a, m, clo - 1, nlo - 1); 55 | } 56 | int32_t main() { 57 | ios_base::sync_with_stdio(0); 58 | cin.tie(0); 59 | 60 | return 0; 61 | } -------------------------------------------------------------------------------- /Graph Theory/Randomized Matching Unweighted.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 510; 5 | 6 | //maximum matching on a general graph 7 | //O(n * m * it) but faster 8 | mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count()); 9 | struct RandomizedMatching { 10 | vector g[N]; 11 | int n, match[N], vis[N], T = 0; 12 | RandomizedMatching() {} 13 | RandomizedMatching(int _n) { 14 | n = _n; 15 | T = 0; 16 | for (int i = 0; i <= n; i++) { 17 | match[i] = vis[i] = 0; 18 | g[i].clear(); 19 | } 20 | } 21 | void add_edge(int u, int v) { 22 | g[u].push_back(v); 23 | g[v].push_back(u); 24 | } 25 | bool dfs(int x) { 26 | if(x == 0) return true; 27 | vis[x] = T; 28 | auto it = g[x].begin(); 29 | shuffle(g[x].begin(), g[x].end(), rnd); 30 | for(; it != g[x].end(); it++) { 31 | int u = *it, v = match[u]; 32 | if (vis[v] < T) { 33 | match[x] = u, match[u] = x, match[v] = 0; 34 | if (dfs(v)) return true; 35 | match[u] = v, match[v] = u, match[x] = 0; 36 | } 37 | } 38 | return false; 39 | } 40 | int maximum_matching() { 41 | memset(match, 0, sizeof match); 42 | int ans = 0; 43 | for(int it = 5; it; it--) { //increase the iteration value for higher probability 44 | for(int i = 1; i <= n; i++) { 45 | if(!match[i]) { 46 | T++, ans += dfs(i); 47 | } 48 | } 49 | } 50 | return ans; 51 | } 52 | }; 53 | int32_t main() { 54 | ios_base::sync_with_stdio(0); 55 | cin.tie(0); 56 | int n, m; 57 | cin >> n >> m; 58 | RandomizedMatching M(n); 59 | while (m--) { 60 | int u, v; 61 | cin >> u >> v; 62 | M.add_edge(u, v); 63 | } 64 | cout << M.maximum_matching() << '\n'; 65 | for (int i = 1; i <= n; i++) cout << M.match[i] << ' '; 66 | cout << '\n'; 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /Number Theory/Linear Diophantine Equation with Nonnegative Solutions.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | using ll = long long; 5 | const ll inf = 1e18; 6 | 7 | struct LDE { // sum(a[i] * x[i]) = k, x[i] >= 0 8 | int n, x; 9 | vector d; 10 | LDE() {} 11 | LDE(vector a) { // O(min(a[i]) * n * log(min(a[i]))) 12 | n = a.size(); 13 | priority_queue, vector>, greater>> q; 14 | x = *min_element(a.begin(), a.end()); 15 | assert(x > 0); 16 | d.resize(x); 17 | fill(d.begin(), d.end(), inf); 18 | d[0] = 0; q.push(pair(0, 0)); 19 | while (!q.empty()) { 20 | pair nw = q.top(); q.pop(); 21 | int u = nw.second; 22 | ll val = nw.first; 23 | if (d[u] != val) continue; 24 | for (int i = 0; i < n; ++ i) { 25 | ll tmp = val + a[i]; 26 | int v = tmp % x; 27 | if (d[v] > tmp) { 28 | d[v] = tmp; 29 | q.push(pair(tmp, v)); 30 | } 31 | } 32 | } 33 | } 34 | bool can(ll k) { // if a solution exists 35 | return d[k % x] <= k; 36 | } 37 | ll count(ll l, ll r) { // count of l <= k <= r s.t. solution for k exists 38 | ll ans = 0; 39 | for (int i = 0; i < x; i++) { // d[i], d[i] + x, d[i] + 2 * x, ... are achievable 40 | ans += d[i] <= r ? (r - d[i]) / x + 1 : 0; 41 | ans -= d[i] <= l - 1 ? (l - 1 - d[i]) / x + 1: 0; 42 | } 43 | return ans; 44 | } 45 | }; 46 | int32_t main() { 47 | ios_base::sync_with_stdio(0); 48 | cin.tie(0); 49 | int n; ll l, r; cin >> n >> l >> r; 50 | vector a(n); 51 | for (int i = 0; i < n; i++) { 52 | cin >> a[i]; 53 | } 54 | LDE t(a); 55 | cout << t.count(l, r) << '\n'; 56 | return 0; 57 | } 58 | // https://www.lydsy.com/JudgeOnline/problem.php?id=2118 59 | // https://codeforces.com/blog/entry/71230?#comment-556761 60 | -------------------------------------------------------------------------------- /Graph Theory/LCA in O(1).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | template 5 | struct RMQ { // 0-based 6 | vector> rmq; 7 | T kInf = numeric_limits::max(); 8 | void build(const vector& V) { 9 | int n = V.size(), on = 1, dep = 1; 10 | while (on < n) on *= 2, ++dep; 11 | rmq.assign(dep, V); 12 | 13 | for (int i = 0; i < dep - 1; ++i) 14 | for (int j = 0; j < n; ++j) { 15 | rmq[i + 1][j] = min(rmq[i][j], rmq[i][min(n - 1, j + (1 << i))]); 16 | } 17 | } 18 | T query(int a, int b) { // [a, b) 19 | if (b <= a) return kInf; 20 | int dep = 31 - __builtin_clz(b - a); // log(b - a) 21 | return min(rmq[dep][a], rmq[dep][b - (1 << dep)]); 22 | } 23 | }; 24 | 25 | struct LCA { // 0-based 26 | vector enter, depth, exxit; 27 | vector> G; 28 | vector> linear; 29 | RMQ> rmq; 30 | int timer = 0; 31 | LCA() {} 32 | LCA(int n) : enter(n, -1), exxit(n, -1), depth(n), G(n), linear(2 * n) {} 33 | void dfs(int node, int dep) { 34 | linear[timer] = {dep, node}; 35 | enter[node] = timer++; 36 | depth[node] = dep; 37 | for (auto vec : G[node]) 38 | if (enter[vec] == -1) { 39 | dfs(vec, dep + 1); 40 | linear[timer++] = {dep, node}; 41 | } 42 | exxit[node] = timer; 43 | } 44 | void add_edge(int a, int b) { 45 | G[a].push_back(b); 46 | G[b].push_back(a); 47 | } 48 | void build(int root) { 49 | dfs(root, 0); 50 | rmq.build(linear); 51 | } 52 | int query(int a, int b) { 53 | a = enter[a], b = enter[b]; 54 | return rmq.query(min(a, b), max(a, b) + 1).second; 55 | } 56 | int dist(int a, int b) { 57 | return depth[a] + depth[b] - 2 * depth[query(a, b)]; 58 | } 59 | }; 60 | 61 | LCA lca; 62 | 63 | int32_t main() { 64 | ios_base::sync_with_stdio(0); 65 | cin.tie(0); 66 | 67 | return 0; 68 | } -------------------------------------------------------------------------------- /Strings/Prefix Automaton.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define pii pair 5 | #define pll pair 6 | #define eb emplace_back 7 | #define ll long long 8 | #define nl '\n' 9 | #define deb(x) cerr<<#x" = "< prefix_function(string &s) { 16 | int n = (int)s.size(); 17 | vector pi(n, 0); 18 | for (int i = 1; i < n; i++) { 19 | int j = pi[i-1]; 20 | while (j > 0 && s[i] != s[j]) j = pi[j-1]; 21 | if (s[i] == s[j]) j++; 22 | pi[i] = j; 23 | } 24 | return pi; 25 | } 26 | int aut[N][26]; 27 | void compute_automaton(string s) 28 | { 29 | s += '#'; 30 | int n = (int)s.size(); 31 | vector pi = prefix_function(s); 32 | for (int i = 0; i < n; i++) { 33 | for (int c = 0; c < 26; c++) { 34 | if (i > 0 && 'a' + c != s[i]) aut[i][c] = aut[pi[i-1]][c]; 35 | else aut[i][c] = i + ('a' + c == s[i]); 36 | } 37 | } 38 | } 39 | vector< vector > dp; 40 | int n, m; 41 | string s, p; 42 | int yo(int i, int j) 43 | { 44 | if(i == n) return (j == m); 45 | int &ret = dp[i][j]; 46 | if(ret != -1) return ret; 47 | ret = 0; 48 | if(s[i] == '?'){ 49 | for(int c=0; c<26; c++){ 50 | ret = max(ret, yo(i+1, aut[j][c])); 51 | } 52 | } 53 | else ret = yo(i+1, aut[j][s[i]-'a']); 54 | ret += j == m; 55 | return ret; 56 | } 57 | ///change '?'s in string s so that the number of occurrences of p is maximized 58 | int32_t main() 59 | { 60 | char ch[N]; scanf("%s", ch); s = ch; 61 | scanf("%s", ch); p = ch; 62 | compute_automaton(p); 63 | n = s.size(); m = p.size(); 64 | dp.resize(n, vector(m+1, -1)); 65 | cout< 2 | using namespace std; 3 | 4 | const int mod = 1e9 + 7; 5 | //for Q assign operation it takes Qlogn time in total 6 | template 7 | struct interval_set { 8 | map, T> value;//{r,l}=val 9 | 10 | void init(int n) { 11 | value[ {n, 1}] = (T)0; //initial value 12 | } 13 | //assign a[i]=val for l<=i<=r 14 | //returns affected ranges before performing this assign operation 15 | vector, T> > assign(int l, int r, T val) { 16 | auto bg = value.lower_bound({l, 0})->first; 17 | if(bg.second != l) { 18 | T val = value[bg]; 19 | value.erase(bg); 20 | value[ {l - 1, bg.second}] = val; 21 | value[ {bg.first, l}] = val; 22 | } 23 | 24 | auto en = value.lower_bound({r, 0})->first; 25 | if(en.first != r) { 26 | T val = value[en]; 27 | value.erase(en); 28 | value[ {en.first, r + 1}] = val; 29 | value[ {r, en.second}] = val; 30 | } 31 | 32 | vector, T> > ret; 33 | auto itt = value.lower_bound({l, 0}); 34 | while(true) { 35 | if(itt == value.end() || itt->first.first > r) break; 36 | ret.push_back({{itt->first.second, itt->first.first}, itt->second}); 37 | ++itt; 38 | } 39 | 40 | for(auto it : ret) 41 | value.erase({it.first.second, it.first.first}); 42 | 43 | value[ {r, l}] = val; 44 | return ret; 45 | } 46 | }; 47 | interval_setse; 48 | //assign a value in range in each query 49 | //in the end print the sum of the array elements 50 | int32_t main() { 51 | int i, j, k, n, m, q, l, r, v; 52 | cin >> n >> q; 53 | se.init(n); 54 | while(q--) { 55 | cin >> l >> r >> v; 56 | se.assign(l, r, v); 57 | } 58 | int ans = 0; 59 | for(auto x : se.value) { 60 | ans += 1LL * ((x.first.first - x.first.second + 1) % mod) * (x.second % mod) % mod; 61 | ans %= mod; 62 | } 63 | cout << ans << endl; 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /Strings/Cyclic LCS.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 2010; 5 | /*Cyclic Longest Common Subsequence 6 | maximum of lcs(any cyclic shift of s, any cyclic shift of t) 7 | O(nm)*/ 8 | int dp[N * 2][N], from[N * 2][N]; 9 | int yo(string s, string t) { 10 | int n = s.size(), m = t.size(); 11 | auto eq = [&](int a, int b) { 12 | return s[(a - 1) % n] == t[(b - 1) % m]; 13 | }; 14 | dp[0][0] = from[0][0] = 0; 15 | for (int i = 0; i <= n * 2; ++i) { 16 | for (int j = 0; j <= m; ++j) { 17 | dp[i][j] = 0; 18 | if (j && dp[i][j - 1] > dp[i][j]) { 19 | dp[i][j] = dp[i][j - 1]; 20 | from[i][j] = 0; 21 | } 22 | if (i && j && eq(i, j) && dp[i - 1][j - 1] + 1 > dp[i][j]) { 23 | dp[i][j] = dp[i - 1][j - 1] + 1; 24 | from[i][j] = 1; 25 | } 26 | if (i && dp[i - 1][j] > dp[i][j]) { 27 | dp[i][j] = dp[i - 1][j]; 28 | from[i][j] = 2; 29 | } 30 | } 31 | } 32 | int ret = 0; 33 | for (int i = 0; i < n; ++i) { 34 | ret = max(ret, dp[i + n][m]); 35 | // re-root 36 | int x = i + 1, y = 0; 37 | while (y <= m && from[x][y] == 0) ++y; 38 | for (; y <= m && x <= n * 2; ++x) { 39 | from[x][y] = 0, --dp[x][m]; 40 | if (x == n * 2) break; 41 | for (; y <= m; ++y) { 42 | if (from[x + 1][y] == 2) break; 43 | if (y + 1 <= m && from[x + 1][y + 1] == 1) { 44 | ++y; 45 | break; 46 | } 47 | } 48 | } 49 | } 50 | return ret; 51 | } 52 | int32_t main() { 53 | ios_base::sync_with_stdio(0); 54 | cin.tie(0); 55 | string s, t; 56 | cin >> s >> t; 57 | cout << yo(s, t) << '\n'; 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /Dynamic Programming Optimizations/Knuth Optimization.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1010; 5 | using ll = long long; 6 | /* 7 | Knuths optimization works for optimization over sub arrays 8 | for which optimal middle point depends monotonously on the end points. 9 | Let mid[l,r] be the first middle point for (l,r) sub array which gives optimal result. 10 | It can be proven that mid[l,r-1] <= mid[l,r] <= mid[l+1,r] 11 | - this means monotonicity of mid by l and r. 12 | Applying this optimization reduces time complexity from O(k^3) to O(k^2) 13 | because with fixed s (sub array length) we have m_right(l) = mid[l+1][r] = m_left(l+1). 14 | That's why nested l and m loops require not more than 2k iterations overall. 15 | */ 16 | 17 | int n, k; 18 | int a[N], mid[N][N]; 19 | ll res[N][N]; 20 | ll solve() { 21 | for (int s = 0; s <= k; s++) { // s - length of the subarray 22 | for (int l = 0; l + s <= k; l++) { // l - left point 23 | int r = l + s; // r - right point 24 | if (s < 2) { 25 | res[l][r] = 0; // base case- nothing to break 26 | mid[l][r] = l; // mid is equal to left border 27 | continue; 28 | } 29 | int mleft = mid[l][r - 1]; 30 | int mright = mid[l + 1][r]; 31 | res[l][r] = 2e18; 32 | for (int m = mleft; m <= mright; m++) { // iterating for m in the bounds only 33 | ll tmp = res[l][m] + res[m][r] + (a[r] - a[l]); 34 | if (res[l][r] > tmp) { // relax current solution 35 | res[l][r] = tmp; 36 | mid[l][r] = m; 37 | } 38 | } 39 | } 40 | } 41 | ll ans = res[0][k]; 42 | return ans; 43 | } 44 | int main() { 45 | int i, j, m; 46 | while(cin >> n >> k) { 47 | for(i = 1; i <= k; i++) cin >> a[i]; 48 | a[0] = 0; 49 | a[k + 1] = n; 50 | k++; 51 | cout << solve() << endl; 52 | } 53 | return 0; 54 | } 55 | // https://vjudge.net/problem/ZOJ-2860 56 | -------------------------------------------------------------------------------- /Graph Theory/Maximum Clique.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 42; 5 | 6 | int g[N][N]; 7 | int res; 8 | long long edges[N]; 9 | //3 ^ (n / 3) 10 | void BronKerbosch(int n, long long R, long long P, long long X) { 11 | if (P == 0LL && X == 0LL) { //here we will find all possible maximal cliques (not maximum) i.e. there is no node which can be included in this set 12 | int t = __builtin_popcountll(R); 13 | res = max(res, t); 14 | return; 15 | } 16 | int u = 0; 17 | while (!((1LL << u) & (P | X))) u ++; 18 | for (int v = 0; v < n; v++) { 19 | if (((1LL << v) & P) && !((1LL << v) & edges[u])) { 20 | BronKerbosch(n, R | (1LL << v), P & edges[v], X & edges[v]); 21 | P -= (1LL << v); 22 | X |= (1LL << v); 23 | } 24 | } 25 | } 26 | 27 | int max_clique (int n) { 28 | res = 0; 29 | for (int i = 1; i <= n; i++) { 30 | edges[i - 1] = 0; 31 | for (int j = 1; j <= n; j++) if (g[i][j]) edges[i - 1] |= ( 1LL << (j - 1) ); 32 | } 33 | BronKerbosch(n, 0, (1LL << n) - 1, 0); 34 | return res; 35 | } 36 | int32_t main() { 37 | ios_base::sync_with_stdio(0); 38 | cin.tie(0); 39 | 40 | map mp; 41 | setse; 42 | int n, m; 43 | cin >> n >> m; 44 | for (int i = 1; i <= n + 1; i++) { 45 | int ty; 46 | if (i <= n) cin >> ty; 47 | if (ty == 1 || i > n) { 48 | for (auto x : se) for (auto y : se) g[x][y] = 1, g[y][x] = 1; 49 | se.clear(); 50 | } else { 51 | string s; 52 | cin >> s; 53 | if (mp.find(s) == mp.end()) { 54 | mp[s]; 55 | mp[s] = mp.size(); 56 | } 57 | int p = mp[s]; 58 | se.insert(p); 59 | } 60 | } 61 | for (int i = 1; i <= m; i++) for (int j = 1; j <= m; j++) g[i][j] = !g[i][j]; 62 | for (int i = 1; i <= m; i++) g[i][i] = 0; 63 | cout << max_clique(m) << '\n'; 64 | return 0; 65 | } 66 | // https://codeforces.com/contest/1105/problem/E 67 | -------------------------------------------------------------------------------- /Data Structures/Segment Tree Persistent.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1e5 + 9; 5 | 6 | struct PST { 7 | #define lc t[cur].l 8 | #define rc t[cur].r 9 | struct node { 10 | int l = 0, r = 0, val = 0; 11 | } t[20 * N]; 12 | int T = 0; 13 | int build(int b, int e) { 14 | int cur = ++T; 15 | if(b == e) return cur; 16 | int mid = b + e >> 1; 17 | lc = build(b, mid); 18 | rc = build(mid + 1, e); 19 | t[cur].val = t[lc].val + t[rc].val; 20 | return cur; 21 | } 22 | int upd(int pre, int b, int e, int i, int v) { 23 | int cur = ++T; 24 | t[cur] = t[pre]; 25 | if(b == e) { 26 | t[cur].val += v; 27 | return cur; 28 | } 29 | int mid = b + e >> 1; 30 | if(i <= mid) { 31 | rc = t[pre].r; 32 | lc = upd(t[pre].l, b, mid, i, v); 33 | } else { 34 | lc = t[pre].l; 35 | rc = upd(t[pre].r, mid + 1, e, i, v); 36 | } 37 | t[cur].val = t[lc].val + t[rc].val; 38 | return cur; 39 | } 40 | int query(int pre, int cur, int b, int e, int k) { 41 | if(b == e) return b; 42 | int cnt = t[lc].val - t[t[pre].l].val; 43 | int mid = b + e >> 1; 44 | if(cnt >= k) return query(t[pre].l, lc, b, mid, k); 45 | else return query(t[pre].r, rc, mid + 1, e, k - cnt); 46 | } 47 | } t; 48 | 49 | //the code returns k-th number in a range l to r if the range were sorted 50 | int V[N], root[N], a[N]; 51 | int32_t main() { 52 | mapmp; 53 | int n, q; 54 | cin >> n >> q; 55 | for(int i = 1; i <= n; i++) cin >> a[i], mp[a[i]]; 56 | int c = 0; 57 | for(auto x : mp) mp[x.first] = ++c, V[c] = x.first; 58 | root[0] = t.build(1, n); 59 | for(int i = 1; i <= n; i++) { 60 | root[i] = t.upd(root[i - 1], 1, n, mp[a[i]], 1); 61 | } 62 | while(q--) { 63 | int l, r, k; 64 | cin >> l >> r >> k; 65 | cout << V[t.query(root[l - 1], root[r], 1, n, k)] << '\n'; 66 | } 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /Number Theory/Fermats Theorem on Sum of Two Squares.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define FR FermatRepresent 5 | namespace FermatRepresent { 6 | template 7 | inline num_t mult(num_t a, num_t b, num_t p) { 8 | num_t q = (num_t) ((long double) a * b / p); 9 | num_t r = a * b - q * p; 10 | while (r < 0) r += p; 11 | while (r >= p) r -= p; 12 | return r; 13 | } 14 | template 15 | inline num_t fpow(num_t n, num_t k, num_t p) { 16 | num_t r = 1; 17 | for (; k; k >>= 1) { 18 | if (k & 1) r = mult(r, n, p); 19 | n = mult(n, n, p); 20 | } 21 | return r; 22 | } 23 | template 24 | inline num_t isqrt(num_t k) { 25 | num_t r = sqrt(k) + 1; 26 | while (r * r > k) r--; 27 | return r; 28 | } 29 | long long func(long long p) { 30 | srand(2311); 31 | while (1) { 32 | long long u = (long long) rand() * rand() % p; 33 | if (fpow(u, (p - 1) / 2, p) == p - 1) { 34 | long long res = fpow(u, (p - 1) / 4, p); 35 | return max(res, p - res); 36 | } 37 | } 38 | } 39 | // given an odd prime p 40 | // returns (a, b) s.t. a^2 + b^2 = p 41 | // p % 4 = 1, otherwise no solution exists 42 | pair calc(long long p) { 43 | long long a = p, b = func(p); 44 | long long ip = isqrt(p); 45 | while (b > ip) { 46 | a %= b; 47 | swap(a, b); 48 | } 49 | return make_pair(b, isqrt(p - b * b)); 50 | } 51 | } 52 | 53 | int main() { 54 | pair res = FR::calc(613); 55 | cerr << res.first << " " << res.second << "\n"; 56 | cerr << res.first * res.first + res.second * res.second << "\n"; 57 | cerr << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n"; 58 | return 0; 59 | } -------------------------------------------------------------------------------- /Data Structures/DSU Partially Persistent.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9; 5 | 6 | struct DSU { 7 | vector>> par; 8 | int time = 0; //initial time 9 | DSU(int n) : par(n + 1, {{-1, 0}}) {} 10 | bool merge(int u, int v) { 11 | ++time; 12 | if ((u = root(u, time)) == (v = root(v, time))) return 0; 13 | if (par[u].back().first > par[v].back().first) swap(u, v); 14 | par[u].push_back({par[u].back().first + par[v].back().first, time}); 15 | par[v].push_back({u, time}); //par[v] = u 16 | return 1; 17 | } 18 | bool same(int u, int v, int t) { 19 | return root(u, t) == root(v, t); 20 | } 21 | int root(int u, int t) { //root of u at time t 22 | if (par[u].back().first >= 0 && par[u].back().second <= t) return root(par[u].back().first, t); 23 | return u; 24 | } 25 | int size(int u, int t) { //size of the component of u at time t 26 | u = root(u, t); 27 | int l = 0, r = (int) par[u].size() - 1, ans = 0; 28 | while (l <= r) { 29 | int mid = l + r >> 1; 30 | if (par[u][mid].second <= t) ans = mid, l = mid + 1; 31 | else r = mid - 1; 32 | } 33 | return -par[u][ans].first; 34 | } 35 | }; 36 | 37 | int a[N]; 38 | int32_t main() { 39 | ios_base::sync_with_stdio(0); 40 | cin.tie(0); 41 | 42 | int t; 43 | cin >> t; 44 | while(t--) { 45 | int n, m; 46 | cin >> n >> m; 47 | DSU d(n); 48 | for(int i = 1; i <= m; i++) { 49 | int ty, u, v; 50 | cin >> ty >> u >> v; 51 | if(ty == 1) { 52 | d.merge(u, v); 53 | a[d.time] = i; 54 | } else { 55 | int ans = -1, l = 0, r = d.time; 56 | while(l <= r) { 57 | int mid = l + r >> 1; 58 | if(d.same(u, v, mid)) ans = a[mid], r = mid - 1; 59 | else l = mid + 1; 60 | } 61 | cout << ans << '\n'; 62 | } 63 | } 64 | } 65 | return 0; 66 | } 67 | //https://codeforces.com/gym/100814/problem/C 68 | -------------------------------------------------------------------------------- /Number Theory/LCM of Fibonacci Numbers.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9, mod= 1e9 + 7; 5 | 6 | int power(long long n, long long k) { 7 | int ans = 1 % mod; n %= mod; if (n < 0) n += mod; 8 | while (k) { 9 | if (k & 1) ans = (long long) ans * n % mod; 10 | n = (long long) n * n % mod; 11 | k >>= 1; 12 | } 13 | return ans; 14 | } 15 | int fib(long long n) { 16 | assert (n >= 0); 17 | if (n <= 1) return n; 18 | int a = 0; 19 | int b = 1; 20 | long long i = 1ll << (63 - __builtin_clzll(n) - 1); 21 | for (; i; i >>= 1) { 22 | int na = (a *(long long) a + b *(long long) b) % mod; 23 | int nb = (2ll * a + b) * b % mod; 24 | a = na; 25 | b = nb; 26 | if (n & i) { 27 | int c = a + b; if (c >= mod) c -= mod; 28 | a = b; 29 | b = c; 30 | } 31 | } 32 | return b; 33 | } 34 | map, int> dp; 35 | /** 36 | O((max number of divisors of a[i]) * n * log(max a[i])) but faster in practice 37 | lcm(a1, a2, ... an) 38 | = lcm(lcm(a1, ..., a[n-1]), an) 39 | = lcm(a1, ..., a[n-1]) * an / gcd(lcm(a1, ..., a[n-1]), an) 40 | = lcm(a1, ..., a[n-1]) * an / lcm(gcd(a1, an), ... gcd(a[n-1], an)) 41 | **/ 42 | int yo(vector a) { 43 | sort(a.rbegin(), a.rend()); 44 | while (!a.empty() && a.back() <= 2) a.pop_back(); 45 | a.resize(unique(a.begin(), a.end()) - a.begin()); 46 | if (a.empty()) return 1; 47 | if (a.size() == 1) return fib(a[0]); 48 | if (dp.count(a)) return dp[a]; 49 | vector b(a.begin(), a.end() - 1); 50 | long long res = yo(b); 51 | for (int i = 0; i < b.size(); ++i) b[i] = __gcd(b[i], a.back()); 52 | res = res * fib(a.back()) % mod * power(yo(b), mod - 2) % mod; 53 | dp[a] = res; 54 | return res; 55 | } 56 | int32_t main() { 57 | ios_base::sync_with_stdio(0); 58 | cin.tie(0); 59 | int n; cin >> n; 60 | vector a(n); 61 | for (auto &x: a) cin >> x; 62 | cout << yo(a) << '\n'; 63 | return 0; 64 | } 65 | //https://www.hackerrank.com/contests/infinitum10/challenges/fibonacci-lcm/problem 66 | -------------------------------------------------------------------------------- /Graph Theory/Stable Marriage Problem.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1010; 5 | 6 | /*Given n men and n women, where each person has ranked all members of the opposite sex 7 | in order of preference, marry the men and women together such that 8 | there are no two people of opposite sex who would both rather have 9 | each other than their current partners. When there are no such pairs of people, 10 | the set of marriages is deemed stable. There is always a solution 11 | m[][],w[][] lists partners in order of their preferences 12 | it always yields the one that is best for all men among all stable matchings, and worst for all women. complexity O(n^2)*/ 13 | 14 | int m[N][N], w[N][N], id[N], marry[N], ans[N], pref[N][N]; 15 | void SM(int n) { 16 | queueq; 17 | for(int i = 1; i <= n; i++) { 18 | q.push(i); 19 | id[i] = 1; 20 | } 21 | memset(marry, -1, sizeof marry); 22 | for(int i = 1; i <= n; i++) { 23 | for(int j = 1; j <= n; j++) pref[i][m[i][j]] = j; 24 | } 25 | while(!q.empty()) { 26 | int cw = q.front(); 27 | q.pop(); 28 | int cm = w[cw][id[cw]]; 29 | if(marry[cm] != -1) { 30 | if(pref[cm][marry[cm]] > pref[cm][cw]) { 31 | id[marry[cm]]++; 32 | q.push(marry[cm]); 33 | marry[cm] = cw; 34 | } else { 35 | id[cw]++; 36 | q.push(cw); 37 | } 38 | } else marry[cm] = cw; 39 | } 40 | for(int i = 1; i <= n; i++) ans[i] = marry[i]; 41 | } 42 | 43 | int32_t main() { 44 | ios_base::sync_with_stdio(0); 45 | cin.tie(0); 46 | 47 | int t; 48 | cin >> t; 49 | while(t--) { 50 | int n; 51 | cin >> n; 52 | for(int i = 1; i <= n; i++) { 53 | int k; 54 | cin >> k; 55 | for(int j = 1; j <= n; j++) cin >> w[i][j]; 56 | } 57 | for(int i = 1; i <= n; i++) { 58 | int k; 59 | cin >> k; 60 | for(int j = 1; j <= n; j++) cin >> m[i][j]; 61 | } 62 | SM(n); 63 | for(int i = 1; i <= n; i++) cout << i << ' ' << ans[i] << '\n'; 64 | } 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /Graph Theory/Euler Path Directed.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 4e5 + 9; 5 | 6 | /* 7 | all the edges should be in the same connected component 8 | #directed graph: euler path: for all -> indeg = outdeg or nodes having indeg > outdeg = outdeg > indeg = 1 and for others in = out 9 | #directed graph: euler circuit: for all -> indeg = outdeg 10 | */ 11 | 12 | //euler path in a directed graph 13 | //it also finds circuit if it exists 14 | vector g[N], ans; 15 | int done[N]; 16 | void dfs(int u) { 17 | while (done[u] < g[u].size()) dfs(g[u][done[u]++]); 18 | ans.push_back(u); 19 | } 20 | int solve(int n) { 21 | int edges = 0; 22 | vector in(n + 1, 0), out(n + 1, 0); 23 | for (int u = 1; u <= n; u++) { 24 | for (auto v : g[u]) in[v]++, out[u]++, edges++; 25 | } 26 | int ok = 1, cnt1 = 0, cnt2 = 0, root = 0; 27 | for (int i = 1; i <= n; i++) { 28 | if (in[i] - out[i] == 1) cnt1++; 29 | if (out[i] - in[i] == 1) cnt2++, root = i; 30 | if (abs(in[i] - out[i]) > 1) ok = 0; 31 | } 32 | if (cnt1 > 1 || cnt2 > 1) ok = 0; 33 | if (!ok) return 0; 34 | if (root == 0) { 35 | for (int i = 1; i <= n; i++) if (out[i]) root = i; 36 | } 37 | if (root == 0) return 1; //empty graph 38 | dfs(root); 39 | if (ans.size() != edges + 1) return 0; //connectivity 40 | reverse(ans.begin(), ans.end()); 41 | return 1; 42 | } 43 | map mp; 44 | string id[N]; 45 | int T = 0; 46 | int32_t main() { 47 | int n; 48 | cin >> n; 49 | for (int i = 1; i <= n; i++) { 50 | string s; 51 | cin >> s; 52 | string a = s.substr(0, 2); 53 | string b = s.substr(1); 54 | if (!mp.count(a)) mp[a] = ++T, id[T] = a; 55 | if (!mp.count(b)) mp[b] = ++T, id[T] = b; 56 | g[mp[a]].push_back(mp[b]); 57 | } 58 | int ok = solve(T); 59 | if (!ok) return cout << "NO\n", 0; 60 | cout << "YES\n"; 61 | string res = id[ans.front()]; 62 | for (int i = 1; i < ans.size(); i++) res += id[ans[i]][1]; 63 | cout << res << '\n'; 64 | return 0; 65 | } 66 | // https://codeforces.com/contest/508/problem/D 67 | -------------------------------------------------------------------------------- /Number Theory/Multiplicative Order.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | using ll = long long; 5 | ll power(ll n, ll k, const ll mod) { 6 | ll res = 1; 7 | while (k) { 8 | if (k & 1) res = __int128(res) * n % mod; 9 | n = __int128(n) * n % mod; 10 | k >>= 1; 11 | } 12 | return res; 13 | } 14 | ll totient(ll n) { 15 | ll ans = n; 16 | for (ll i = 2; i * i <= n; i++) { 17 | if (n % i == 0) { 18 | while (n % i == 0) n /= i; 19 | ans = ans / i * (i - 1); 20 | } 21 | } 22 | if (n > 1) ans = ans / n * (n - 1); 23 | return ans; 24 | } 25 | // returns the minimum positive k s.t. a^ k = 1 modulo mod. On failure, returns -1 26 | // we just have to check the divisors of phi(mod) as candidates of k (Lagranges Theorem) 27 | // which can still be optimized further. Check: https://cp-algorithms.com/algebra/primitive-root.html#toc-tgt-3 28 | // it always exists if a and mod are coprime 29 | // O((log(mod)^2)) + sqrt(mod) for calculating totient 30 | // it can still be optimized. Check: https://brilliant.org/wiki/carmichaels-lambda-function/ 31 | ll multiplicative_order(ll a, ll mod) { 32 | if (__gcd(a, mod) != 1) return -1; 33 | ll m = totient(mod), p = m; 34 | ll ans = 2e18; 35 | if (power(a, p, mod) == 1) ans = p; 36 | vector fac; 37 | for (ll i = 2 ; i * i <= m; i++) { 38 | if (m % i == 0) { 39 | while(m % i == 0) m /= i, fac.push_back(i); 40 | } 41 | } 42 | if (m > 1) fac.push_back(m); 43 | for (auto x: fac) { 44 | if (power(a, p / x, mod) == 1) p /= x, ans = p; 45 | } 46 | assert(ans != 2e18); 47 | return ans; 48 | } 49 | 50 | int32_t main() { 51 | ios_base::sync_with_stdio(0); 52 | cin.tie(0); 53 | int t; cin >> t; 54 | while (t--) { 55 | ll x, m; cin >> x >> m; 56 | ll nw = x, st = x; 57 | ll mul = 1; 58 | while (x > 0){ 59 | x /= 10; 60 | mul *= 10; 61 | } 62 | m *= mul - 1; 63 | m /= __gcd(m, st); 64 | ll ans = multiplicative_order(mul, m); 65 | cout << ans << '\n'; 66 | } 67 | return 0; 68 | } 69 | // https://toph.co/p/i-am-good 70 | -------------------------------------------------------------------------------- /Graph Theory/Tuttes Theorem.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 105; 5 | const double eps = 1e-9; 6 | 7 | double determinant(vector>a) { 8 | int n = a.size(); 9 | double det = 1; 10 | for (int i = 0; i < n; ++i) { 11 | int k = i; 12 | for (int j = i + 1; j < n; ++j) 13 | if (abs (a[j][i]) > abs (a[k][i])) 14 | k = j; 15 | if (abs (a[k][i]) < eps) { 16 | det = 0; 17 | break; 18 | } 19 | swap (a[i], a[k]); 20 | if (i != k) 21 | det = -det; 22 | det *= a[i][i]; 23 | for (int j = i + 1; j < n; ++j) 24 | a[i][j] /= a[i][i]; 25 | for (int j = 0; j < n; ++j) 26 | if (j != i && abs (a[j][i]) > eps) 27 | for (int k = i + 1; k < n; ++k) 28 | a[j][k] -= a[i][k] * a[j][i]; 29 | } 30 | 31 | return det; 32 | } 33 | //count number of arborescences i.e. directed rooted trees in the graph 34 | int g[N][N], in[N]; 35 | int32_t main() { 36 | int n; 37 | while(cin >> n && n) { 38 | memset(g, 0, sizeof g); 39 | memset(in, 0, sizeof in); 40 | for(int i = 0; i < n; i++) { 41 | string s; 42 | cin >> s; 43 | for(int j = 0; j < n; j++) if(s[j] == '1') g[i][j]++, in[j]++; 44 | } 45 | for(int i = 0; i < n; i++) { 46 | for(int j = 0; j < n; j++) { 47 | if(i == j) g[i][j] = in[i]; 48 | else g[i][j] *= -1; 49 | } 50 | } 51 | int ans = 0; 52 | for(int r = 0; r < n; r++) { 53 | //number of arborescences with root r is the determinant of the matrix produced by deleting the r-th row and column from g. 54 | vector< vector > mat; 55 | for(int i = 0; i < n; i++) { 56 | if(i == r) continue; 57 | vector v; 58 | for(int j = 0; j < n; j++) { 59 | if(j != r) v.push_back(g[i][j]); 60 | } 61 | mat.push_back(v); 62 | } 63 | double nw = determinant(mat); 64 | ans += (int) round(nw); 65 | } 66 | cout << ans << '\n'; 67 | } 68 | return 0; 69 | } 70 | //https://www.spoj.com/problems/DAGCNT/ 71 | 72 | -------------------------------------------------------------------------------- /Graph Theory/Articulation Bridges.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | struct TECC { // 0 indexed 5 | int n, k; 6 | vector> g, t; 7 | vector used; 8 | vector comp, ord, low; 9 | using edge = pair; 10 | vector br; 11 | void dfs(int x, int prv, int &c) { 12 | used[x] = 1; ord[x] = c++; low[x] = n; 13 | bool mul = 0; 14 | for (auto y:g[x]) { 15 | if (used[y]) { 16 | if (y != prv || mul) low[x] = min(low[x], ord[y]); 17 | else mul = 1; 18 | continue; 19 | } 20 | dfs(y, x, c); 21 | low[x] = min(low[x], low[y]); 22 | } 23 | } 24 | void dfs2(int x, int num) { 25 | comp[x] = num; 26 | for (auto y: g[x]) { 27 | if (comp[y] != -1) continue; 28 | if (ord[x] < low[y]) { 29 | br.push_back({x, y}); 30 | k++; 31 | dfs2(y, k); 32 | } else dfs2(y, num); 33 | } 34 | } 35 | TECC(const vector> &g): g(g), n(g.size()), used(n), comp(n, -1), ord(n), low(n), k(0) { 36 | int c = 0; 37 | for (int i = 0; i < n; i++) { 38 | if (used[i]) continue; 39 | dfs(i, -1, c); 40 | dfs2(i, k); 41 | k++; 42 | } 43 | } 44 | void build_tree() { 45 | t.resize(k); 46 | for (auto e: br) { 47 | int x = comp[e.first], y = comp[e.second]; 48 | t[x].push_back(y); 49 | t[y].push_back(x); 50 | } 51 | } 52 | }; 53 | int32_t main() { 54 | ios_base::sync_with_stdio(0); 55 | cin.tie(0); 56 | int n, m; cin >> n >> m; 57 | vector> g(n); 58 | for (int i = 0; i < m; i++) { 59 | int a, b; cin >> a >> b; 60 | g[a].push_back(b); 61 | g[b].push_back(a); 62 | } 63 | TECC t(g); 64 | vector> ans(t.k); 65 | for (int i = 0; i < n; i++) { 66 | ans[t.comp[i]].push_back(i); 67 | } 68 | cout << ans.size() << '\n'; 69 | for (auto x: ans) { 70 | cout << x.size(); 71 | for (auto y: x) cout << ' ' << y; 72 | cout << '\n'; 73 | } 74 | return 0; 75 | } 76 | // https://judge.yosupo.jp/problem/two_edge_connected_components 77 | -------------------------------------------------------------------------------- /Dynamic Programming Optimizations/Divide and Conquer Optimization.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define ll long long 5 | const int N = 4010; 6 | 7 | int sc() { 8 | int c = getchar(); 9 | int x = 0; 10 | int neg = 0; 11 | for(; ((c < 48 || c > 57) && c != '-'); c = getchar()); 12 | if(c == '-') { 13 | neg = 1; 14 | c = getchar(); 15 | } 16 | for(; c > 47 && c < 58; c = getchar()) { 17 | x = (x << 1) + (x << 3) + c - 48; 18 | } 19 | if(neg) x = -x; 20 | return x; 21 | } 22 | 23 | // Divide 1,2,3...n people in k consecutive parts so that sum of cost of each individual part is minimum 24 | int a[N][N], c[N][N], dp[810][N]; // dp[i][j]=minimum cost for dividing [1...j] into i parts 25 | int cost(int i, int j) { 26 | if(i > j) return 0; 27 | return c[j][j] - c[i - 1][j] - c[j][i - 1] + c[i - 1][i - 1]; 28 | } 29 | void yo(int i, int l, int r, int optl, int optr) { 30 | if(l > r) return; 31 | int mid = (l + r) / 2; 32 | dp[i][mid] = 2e9; // for maximum cost change it to 0 33 | int opt = -1; 34 | for(int k = optl; k <= min(mid, optr); k++) { 35 | int c = dp[i - 1][k] + cost(k + 1, mid); 36 | if(c < dp[i][mid]) { // for maximum cost just change < to > only and rest of the algo should not be changed 37 | dp[i][mid] = c; 38 | opt = k; 39 | } 40 | } 41 | // for opt[1..j]<=opt[1...j+1] i.e. cost(1,j)<=cost(1,j+1) 42 | yo(i, l, mid - 1, optl, opt); 43 | yo(i, mid + 1, r, opt, optr); 44 | // for opt[1...j]>=opt[1...j+1] i.e. cost(1,j)>=cost(1,j+1) 45 | // yo(i,l,mid-1,opt,optr); 46 | // yo(i,mid+1,r,optl,opt); 47 | 48 | } 49 | int main() { 50 | ios_base::sync_with_stdio(0); 51 | cin.tie(0); 52 | 53 | int i, j, k, n, m; 54 | n = sc(); 55 | k = sc(); 56 | for(i = 1; i <= n; i++) for(j = 1; j <= n; j++) a[i][j] = sc(); 57 | for(i = 1; i <= n; i++) { 58 | for(j = 1; j <= n; j++) { 59 | c[i][j] = a[i][j] + c[i - 1][j] + c[i][j - 1] - c[i - 1][j - 1]; 60 | } 61 | } 62 | for(i = 1; i <= n; i++) dp[1][i] = cost(1, i); 63 | for(i = 2; i <= k; i++) yo(i, 1, n, 1, n); 64 | cout << dp[k][n] / 2 << endl; 65 | return 0; 66 | } 67 | // https://codeforces.com/contest/321/problem/E 68 | -------------------------------------------------------------------------------- /Number Theory/Discrete Log.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace __gnu_pbds; 5 | using namespace std; 6 | 7 | // baby step - giant step 8 | // returns minimum integer x such that a^x = b (mod m) 9 | // a and m are co-prime 10 | int discrete_log(int a, int b, int m) { 11 | static const int inf = 2e9; 12 | int n = (int) sqrt (m + .0) + 1; 13 | int pw = 1; 14 | for (int i = 0; i < n; ++i) pw = 1LL * pw * a % m; 15 | gp_hash_table vals; 16 | for (int p = 1, cur = pw; p <= n; ++p) { 17 | if (!vals[cur]) vals[cur] = p; 18 | cur = 1LL * cur * pw % m; 19 | } 20 | int ans = inf; 21 | for (int q = 0, cur = b; q <= n; ++q) { 22 | if (vals.find(cur) != vals.end()) { 23 | long long nw = 1LL * vals[cur] * n - q; 24 | if (nw < ans) ans = nw; 25 | } 26 | cur = (1LL * cur * a) % m; 27 | } 28 | if (ans == inf) ans = -1; 29 | return ans; 30 | } 31 | using ll = long long; 32 | ll extended_euclid(ll a, ll b, ll &x, ll &y) { 33 | if (b == 0) { 34 | x = 1; y = 0; 35 | return a; 36 | } 37 | ll x1, y1; 38 | ll d = extended_euclid(b, a % b, x1, y1); 39 | x = y1; 40 | y = x1 - y1 * (a / b); 41 | return d; 42 | } 43 | ll inverse(ll a, ll m) { 44 | ll x, y; 45 | ll g = extended_euclid(a, m, x, y); 46 | if (g != 1) return -1; 47 | return (x % m + m) % m; 48 | } 49 | // discrete log but a and m may not be co-prime 50 | int discrete_log_noncoprime(int a, int b, int m) { 51 | if (m == 1) return 0; 52 | if (b == 1) return 0; 53 | if (__gcd(a, m) == 1) return discrete_log(a, b, m); 54 | int g = __gcd(a, m); 55 | if (b % g != 0) return -1; 56 | int p = inverse(a / g, m / g); 57 | int nw = discrete_log_noncoprime(a, 1LL * b / g * p % (m / g), m / g); 58 | if (nw == -1) return -1; 59 | return nw + 1; 60 | } 61 | int32_t main() { 62 | ios_base::sync_with_stdio(0); 63 | cin.tie(0); 64 | int t = 1000; 65 | while (t--) { 66 | int m = rand() % 100000 + 2, a = rand() % m + 1, b = rand() % m; 67 | cout << discrete_log_noncoprime(a, b, m) << '\n'; 68 | } 69 | return 0; 70 | } -------------------------------------------------------------------------------- /Number Theory/Sum of The Number of Divisors in cbrt(n).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | using uint32 = unsigned int; 5 | using uint64 = unsigned long long; 6 | using uint128 = __uint128_t; 7 | 8 | // credit: zimpha 9 | // compute \sum_{i=1}^{n} sigma0(i) in ~O(n^{1/3}) time. 10 | // it is also equal to \sum_{i=1}^{n} floor(n / i) 11 | // takes ~100 ms for n = 1e18 12 | uint128 sum_sigma0(uint64 n) { 13 | auto out = [n] (uint64 x, uint32 y) { 14 | return x * y > n; 15 | }; 16 | auto cut = [n] (uint64 x, uint32 dx, uint32 dy) { 17 | return uint128(x) * x * dy >= uint128(n) * dx; 18 | }; 19 | const uint64 sn = sqrtl(n); 20 | const uint64 cn = pow(n, 0.34); //cbrtl(n); 21 | uint64 x = n / sn; 22 | uint32 y = n / x + 1; 23 | uint128 ret = 0; 24 | stack> st; 25 | st.emplace(1, 0); 26 | st.emplace(1, 1); 27 | while (true) { 28 | uint32 lx, ly; 29 | tie(lx, ly) = st.top(); 30 | st.pop(); 31 | while (out(x + lx, y - ly)) { 32 | ret += x * ly + uint64(ly + 1) * (lx - 1) / 2; 33 | x += lx, y -= ly; 34 | } 35 | if (y <= cn) break; 36 | uint32 rx = lx, ry = ly; 37 | while (true) { 38 | tie(lx, ly) = st.top(); 39 | if (out(x + lx, y - ly)) break; 40 | rx = lx, ry = ly; 41 | st.pop(); 42 | } 43 | while (true) { 44 | uint32 mx = lx + rx, my = ly + ry; 45 | if (out(x + mx, y - my)) { 46 | st.emplace(lx = mx, ly = my); 47 | } 48 | else { 49 | if (cut(x + mx, lx, ly)) break; 50 | rx = mx, ry = my; 51 | } 52 | } 53 | } 54 | for (--y; y > 0; --y) ret += n / y; 55 | return ret * 2 - sn * sn; 56 | } 57 | 58 | int32_t main() { 59 | ios_base::sync_with_stdio(0); 60 | cin.tie(0); 61 | int t; cin >> t; 62 | while (t--) { 63 | long long n; cin >> n; 64 | auto ans = sum_sigma0(n); 65 | string s = ""; 66 | while (ans > 0) { 67 | s += char('0' + ans % 10); 68 | ans /= 10; 69 | } 70 | reverse(s.begin(), s.end()); 71 | cout << s << '\n'; 72 | } 73 | return 0; 74 | } 75 | // https://www.spoj.com/problems/DIVCNT1/en/ -------------------------------------------------------------------------------- /Dynamic Programming Optimizations/Convex Hull Trick.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define ll long long 5 | #define eb emplace_back 6 | #define nl '\n' 7 | #define deb(x) cerr << #x" = " << x << nl 8 | #define in() ( { int a ; scanf("%d", &a); a; } ) 9 | 10 | const int N = 3e5 + 9; 11 | const int mod = 1e9 + 7; 12 | 13 | struct CHT { 14 | vector m, b; 15 | int ptr = 0; 16 | 17 | bool bad(int l1, int l2, int l3) { 18 | return 1.0 * (b[l3] - b[l1]) * (m[l1] - m[l2]) <= 1.0 * (b[l2] - b[l1]) * (m[l1] - m[l3]); //(slope dec+query min),(slope inc+query max) 19 | return 1.0 * (b[l3] - b[l1]) * (m[l1] - m[l2]) > 1.0 * (b[l2] - b[l1]) * (m[l1] - m[l3]); //(slope dec+query max), (slope inc+query min) 20 | } 21 | 22 | void add(ll _m, ll _b) { 23 | m.push_back(_m); 24 | b.push_back(_b); 25 | int s = m.size(); 26 | while(s >= 3 && bad(s - 3, s - 2, s - 1)) { 27 | s--; 28 | m.erase(m.end() - 2); 29 | b.erase(b.end() - 2); 30 | } 31 | } 32 | 33 | ll f(int i, ll x) { 34 | return m[i] * x + b[i]; 35 | } 36 | 37 | //(slope dec+query min), (slope inc+query max) -> x increasing 38 | //(slope dec+query max), (slope inc+query min) -> x decreasing 39 | ll query(ll x) { 40 | if(ptr >= m.size()) ptr = m.size() - 1; 41 | while(ptr < m.size() - 1 && f(ptr + 1, x) < f(ptr, x)) ptr++; 42 | return f(ptr, x); 43 | } 44 | 45 | ll bs(int l, int r, ll x) { 46 | int mid = (l + r) / 2; 47 | if(mid + 1 < m.size() && f(mid + 1, x) < f(mid, x)) return bs(mid + 1, r, x); // > for max 48 | if(mid - 1 >= 0 && f(mid - 1, x) < f(mid, x)) return bs(l, mid - 1, x); // > for max 49 | return f(mid, x); 50 | } 51 | }; 52 | 53 | ll a[N], b[N]; 54 | CHT cht; 55 | int32_t main() { 56 | ios_base::sync_with_stdio(0); 57 | cin.tie(0); 58 | 59 | int n; 60 | cin >> n; 61 | for(int i = 0; i < n; i++) cin >> a[i]; 62 | for(int i = 0; i < n; i++) cin >> b[i]; 63 | cht.add(b[0], 0); 64 | ll ans = 0; 65 | for(int i = 1; i < n; i++) { 66 | ans = cht.query(a[i]); 67 | cht.add(b[i], ans); 68 | } 69 | cout << ans << nl; 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /Number Theory/Smallest Nonnegative Integer x s.t. l <= ax % p <= r.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1e9, mod = 1e9 + 7; 5 | 6 | using T = __int128; 7 | // ax + by = __gcd(a, b) 8 | // returns __gcd(a, b) 9 | T extended_euclid(T a, T b, T &x, T &y) { 10 | T xx = y = 0; 11 | T yy = x = 1; 12 | while (b) { 13 | T q = a / b; 14 | T t = b; b = a % b; a = t; 15 | t = xx; xx = x - q * xx; x = t; 16 | t = yy; yy = y - q * yy; y = t; 17 | } 18 | return a; 19 | } 20 | 21 | // find z such that z % x = a, z % y = b. 22 | // here, z is unique modulo M = lcm(x,y). 23 | // returns (z, M). on failure, M = -1. 24 | pair CRT(T x, T a, T y, T b) { 25 | T s, t; 26 | T d = extended_euclid(x, y, s, t); 27 | if (a % d != b % d) return make_pair(0, -1); 28 | T m = x * y; 29 | s %= m; s = (s + m) % m; 30 | t %= m; t = (t + m) % m; 31 | return make_pair((s * b % m * x % m + t * a % m * y % m) % m / d, m / d); 32 | } 33 | 34 | T cdiv(T x, T y) { return (x + y - 1) / y; } 35 | // returns the smallest non-negative integer x s.t l <= a * x mod p <= r 36 | // IMPORTANT : 0 <= a < p, 0 <= l <= r < p, p is not necessarily prime 37 | // Complexity: O(log (p)) 38 | long long f(long long p, long long a, long long l, long long r) { 39 | if (a == 0) return l == 0 ? 0 : -1; 40 | long long c = cdiv((T)l, (T)a); 41 | if (a * c <= r) return c; 42 | long long b = p % a; // p = k * a + b, l <= a(x - k * y) - b * y <= r 43 | // => -r <= b * y % a <= -l 44 | auto y = f(a, b, a - r % a, a - l % a); 45 | return y == -1 ? y : cdiv(l + (T)b * y, a) + p / a * y; 46 | } 47 | 48 | const long long M = 1LL * mod * (mod + 2); 49 | int32_t main() { 50 | ios_base::sync_with_stdio(0); 51 | cin.tie(0); 52 | int t; cin >> t; 53 | while (t--) { 54 | cout << "? " << mod << endl; 55 | int r1; cin >> r1; 56 | cout << "? " << mod + 2 << endl; 57 | int r2; cin >> r2; 58 | T x = CRT(mod, r1, mod + 2, r2).first; 59 | long long q = f(M, x, 1, N); 60 | long long p = x * q % M; 61 | cout << "! " << p << ' ' << q << endl; 62 | } 63 | return 0; 64 | } 65 | // https://codeforces.com/gym/102354/problem/I 66 | -------------------------------------------------------------------------------- /Graph Theory/Prufer Code.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9; 5 | 6 | /* 7 | prufer code is a sequence of length n-2 to uniquely determine a labeled tree with n vertices 8 | Each time take the leaf with the lowest number and add the node number the leaf is connected to 9 | the sequence and remove the leaf. Then break the algo after n-2 iterations 10 | */ 11 | //0-indexed 12 | int n; 13 | vector g[N]; 14 | int parent[N], degree[N]; 15 | 16 | void dfs (int v) { 17 | for (size_t i = 0; i < g[v].size(); ++i) { 18 | int to = g[v][i]; 19 | if (to != parent[v]) { 20 | parent[to] = v; 21 | dfs (to); 22 | } 23 | } 24 | } 25 | 26 | vector prufer_code() { 27 | parent[n - 1] = -1; 28 | dfs (n - 1); 29 | int ptr = -1; 30 | for (int i = 0; i < n; ++i) { 31 | degree[i] = (int) g[i].size(); 32 | if (degree[i] == 1 && ptr == -1) ptr = i; 33 | } 34 | vector result; 35 | int leaf = ptr; 36 | for (int iter = 0; iter < n - 2; ++iter) { 37 | int next = parent[leaf]; 38 | result.push_back (next); 39 | --degree[next]; 40 | if (degree[next] == 1 && next < ptr) leaf = next; 41 | else { 42 | ++ptr; 43 | while (ptr < n && degree[ptr] != 1) ++ptr; 44 | leaf = ptr; 45 | } 46 | } 47 | return result; 48 | } 49 | vector < pair > prufer_to_tree(const vector & prufer_code) { 50 | int n = (int) prufer_code.size() + 2; 51 | vector degree (n, 1); 52 | for (int i = 0; i < n - 2; ++i) ++degree[prufer_code[i]]; 53 | 54 | int ptr = 0; 55 | while (ptr < n && degree[ptr] != 1) ++ptr; 56 | int leaf = ptr; 57 | vector < pair > result; 58 | for (int i = 0; i < n - 2; ++i) { 59 | int v = prufer_code[i]; 60 | result.push_back (make_pair (leaf, v)); 61 | --degree[leaf]; 62 | if (--degree[v] == 1 && v < ptr) leaf = v; 63 | else { 64 | ++ptr; 65 | while (ptr < n && degree[ptr] != 1) ++ptr; 66 | leaf = ptr; 67 | } 68 | } 69 | for (int v = 0; v < n - 1; ++v) if (degree[v] == 1) result.push_back (make_pair (v, n - 1)); 70 | return result; 71 | } 72 | 73 | int32_t main() { 74 | 75 | return 0; 76 | } 77 | 78 | -------------------------------------------------------------------------------- /Dynamic Programming Optimizations/Dynamic Convex Hull Trick.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define ll long long 5 | #define eb emplace_back 6 | #define nl '\n' 7 | #define deb(x) cerr << #x" = " << x << nl 8 | #define in() ( { int a ; scanf("%d", &a); a; } ) 9 | 10 | const int N = 3e5 + 9; 11 | const int mod = 1e9 + 7; 12 | 13 | //add lines with -m and -b and return -ans to 14 | //make this code work for minimums.(not -x) 15 | const ll inf = -(1LL << 62); 16 | struct line { 17 | ll m, b; 18 | mutable function succ; 19 | bool operator < (const line& rhs) const { 20 | if (rhs.b != inf) return m < rhs.m; 21 | const line* s = succ(); 22 | if (!s) return 0; 23 | ll x = rhs.m; 24 | return b - s->b < (s->m - m) * x; 25 | } 26 | }; 27 | struct CHT : public multiset { 28 | bool bad(iterator y) { 29 | auto z = next(y); 30 | if (y == begin()) { 31 | if (z == end()) return 0; 32 | return y -> m == z -> m && y -> b <= z -> b; 33 | } 34 | auto x = prev(y); 35 | if (z == end()) return y -> m == x -> m && y -> b <= x -> b; 36 | return 1.0 * (x -> b - y -> b) * (z -> m - y -> m) >= 1.0 * (y -> b - z -> b) * (y -> m - x -> m); 37 | } 38 | void add(ll m, ll b) { 39 | auto y = insert({ m, b }); 40 | y->succ = [ = ] { return next(y) == end() ? 0 : &*next(y); }; 41 | if (bad(y)) { 42 | erase(y); 43 | return; 44 | } 45 | while (next(y) != end() && bad(next(y))) erase(next(y)); 46 | while (y != begin() && bad(prev(y))) erase(prev(y)); 47 | } 48 | ll query(ll x) { 49 | assert(!empty()) 50 | auto l = *lower_bound((line) { 51 | x, inf 52 | }); 53 | return l.m * x + l.b; 54 | } 55 | }; 56 | CHT* cht; 57 | ll a[N], b[N]; 58 | int32_t main() { 59 | ios_base::sync_with_stdio(0); 60 | cin.tie(0); 61 | 62 | int n; 63 | cin >> n; 64 | for(int i = 0; i < n; i++) cin >> a[i]; 65 | for(int i = 0; i < n; i++) cin >> b[i]; 66 | cht = new CHT(); 67 | cht -> add(-b[0], 0); 68 | ll ans = 0; 69 | for(int i = 1; i < n; i++) { 70 | ans = -cht -> query(a[i]); 71 | cht -> add(-b[i], -ans); 72 | } 73 | cout << ans << nl; 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /Data Structures/Disjoint Sparse Table.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define pii pair 5 | #define pll pair 6 | #define eb emplace_back 7 | #define ll long long 8 | #define nl '\n' 9 | #define deb(x) cerr<<#x" = "<> left, right; 17 | int k, n; 18 | DST(vector & a) { 19 | n = (int)a.size(); 20 | k = log2(n) + 2; 21 | left.assign(k + 1, vector(n)); 22 | right.assign(k + 1, vector(n)); 23 | for(int j = 0; (1 << j) <= n; ++j) { 24 | int mask = (1 << j) - 1; 25 | int nw = 1; //neutral 26 | for(int i = 0; i < n; ++i) { 27 | nw = 1LL * nw * a[i] % mod;//prefix value 28 | left[j][i] = nw; 29 | if((i & mask) == mask) nw = 1; //neutral 30 | } 31 | nw = 1; //neutral 32 | for(int i = n - 1; i >= 0; --i) { 33 | nw = 1LL * nw * a[i] % mod;//prefix value 34 | right[j][i] = nw; 35 | if((i & mask) == 0) nw = 1; //neutral 36 | } 37 | } 38 | } 39 | int query(int l, int r) { 40 | if(l == r) return left[0][l]; 41 | int i = 31 - __builtin_clz(l ^ r); 42 | int uno = left[i][r]; 43 | int dos = right[i][l]; 44 | return 1LL * uno * dos % mod; 45 | } 46 | }; 47 | 48 | int32_t main() { 49 | int tc = in(); 50 | while(tc--) { 51 | int n = in(), p = in(), q = in(); 52 | mod = p; 53 | vector a(n); 54 | for(int i = 0; i < n; i++) a[i] = in(); 55 | DST t(a); 56 | vector b((q >> 6) + 2); 57 | for(int i = 0; i < (int)b.size(); i++) b[i] = in(); 58 | int x = 0, l = 1, r = 1; 59 | for(int i = 0; i < q; i++) { 60 | if(i % 64 == 0) { 61 | l = (b[i / 64] + x) % n; 62 | r = (b[(i / 64) + 1] + x) % n; 63 | } else { 64 | l = (l + x) % n; 65 | r = (r + x) % n; 66 | } 67 | if(l > r) swap(l, r); 68 | int ans = t.query(l, r); 69 | x = ans; 70 | x++; 71 | x %= mod; 72 | } 73 | printf("%d\n", x); 74 | } 75 | return 0; 76 | } 77 | // https://www.codechef.com/problems/SEGPROD 78 | -------------------------------------------------------------------------------- /Dynamic Programming Optimizations/1D1D DP.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1e4 + 9; 5 | 6 | /*Let w(i,j) be the cost function. 7 | The required condition is the quadrangle inequality: for all i<=j, w(i,j)+w(i+1,j+1)<=w(i+1,j)+w(i,j+1) 8 | From a practical point of view, we don't need to prove that w satisfies such an inequality, 9 | it's easier to just list out a few values of w and check. 10 | The normal form of DP is: dp[x]=min(dp[i]+w(i,x)) for all i from 0 to x-1. 11 | Let k(x) be the optimal index for dp(x) i.e. dp(x) is minimum for index k(x) i.e. dp(x)=dp(k(x))+w(k(x),x) 12 | Then for all i<=j, k(i)<=k(j) because of the quadrangle inequality 13 | If we can't use CHT for this kind of DP optimization, GENERALLY they are solvable using this trick. 14 | Complexity: O(nlogn)*/ 15 | 16 | int n, s, t[N], f[N]; 17 | ///the cost function, (i, x] 18 | int w(int i, int x) { 19 | if (i >= x) return 1e9; //inf > w(0, n) 20 | return s * (f[n] - f[i]) + t[x] * (f[x] - f[i]); 21 | } 22 | int dp[N]; 23 | int32_t main() { 24 | ios_base::sync_with_stdio(0); 25 | cin.tie(0); 26 | cin >> n >> s; 27 | t[0] = 0; 28 | f[0] = 0; 29 | for (int i = 1; i <= n; i++) { 30 | cin >> t[i] >> f[i]; 31 | t[i] += t[i - 1]; 32 | f[i] += f[i - 1]; 33 | } 34 | dp[0] = 0; 35 | vector > v; // (start pos, best k) 36 | v.push_back(make_pair(0, 0)); 37 | for (int x = 1; x <= n; x++) { 38 | int k = (--lower_bound(v.begin(), v.end(), make_pair(x + 1, 0)))->second; 39 | dp[x] = dp[k] + w(k, x); 40 | for (int i = (int)v.size() - 1; i >= 0; i--) { 41 | int y = v[i].first, oldk = v[i].second; 42 | if (y > x && dp[x] + w(x, y) < dp[oldk] + w(oldk, y)) v.pop_back(); 43 | else { 44 | int l = y + 1, r = n + 1; 45 | while (l < r) { 46 | int mid = (l + r) / 2; 47 | if (dp[x] + w(x, mid) < dp[oldk] + w(oldk, mid)) r = mid; 48 | else l = mid + 1; 49 | } 50 | if (r != n + 1) v.push_back(make_pair(r, x)); 51 | break; 52 | } 53 | } 54 | if (v.size() == 0) v.push_back(make_pair(0, x)); 55 | } 56 | cout << dp[n] << '\n'; 57 | return 0; 58 | } 59 | //https://vjudge.net/problem/OpenJ_Bailian-1180 60 | -------------------------------------------------------------------------------- /Math/Gaussian Elimination Modular.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 105, mod = 1e9 + 7; 5 | 6 | int power(long long n, long long k) { 7 | int ans = 1 % mod; n %= mod; if (n < 0) n += mod; 8 | while (k) { 9 | if (k & 1) ans = (long long) ans * n % mod; 10 | n = (long long) n * n % mod; 11 | k >>= 1; 12 | } 13 | return ans; 14 | } 15 | int Gauss(vector> a, vector &ans){ 16 | int n = a.size(), m = (int)a[0].size() - 1; 17 | vector pos(m, -1); 18 | int free_var = 0; 19 | const long long MODSQ = (long long)mod * mod; 20 | int det = 1, rank = 0; 21 | for (int col = 0, row = 0; col < m && row < n; col++) { 22 | int mx = row; 23 | for (int k = row; k < n; k++) if (a[k][col] > a[mx][col]) mx = k; 24 | if (a[mx][col] == 0) {det = 0; continue;} 25 | for (int j = col; j <= m; j++) swap(a[mx][j], a[row][j]); 26 | if (row != mx) det = det == 0 ? 0 : mod - det; 27 | det = 1LL * det * a[row][col] % mod; 28 | pos[col] = row; 29 | int inv = power(a[row][col], mod - 2); 30 | for (int i = 0; i < n && inv; i++){ 31 | if (i != row && a[i][col]) { 32 | int x = ((long long)a[i][col] * inv) % mod; 33 | for (int j = col; j <= m && x; j++){ 34 | if (a[row][j]) a[i][j] = (MODSQ + a[i][j] - ((long long)a[row][j] * x)) % mod; 35 | } 36 | } 37 | } 38 | row++; ++rank; 39 | } 40 | ans.assign(m, 0); 41 | for (int i = 0; i < m; i++){ 42 | if (pos[i] == -1) free_var++; 43 | else ans[i] = ((long long)a[pos[i]][m] * power(a[pos[i]][i], mod - 2)) % mod; 44 | } 45 | for (int i = 0; i < n; i++) { 46 | long long val = 0; 47 | for (int j = 0; j < m; j++) val = (val + ((long long)ans[j] * a[i][j])) % mod; 48 | if (val != a[i][m]) return -1; //no solution 49 | } 50 | return free_var; //has solution 51 | } 52 | 53 | int32_t main() { 54 | int n, m; cin >> n >> m; 55 | vector> a(n, vector(m + 1)); 56 | for(int i = 0; i < n; i++) for(int j = 0; j <= m; j++) cin >> a[i][j]; 57 | vector ans; 58 | int k = Gauss(a, ans); 59 | if(k == -1) cout << "no solution\n"; 60 | else { 61 | for (auto x: ans) cout << x << '\n'; 62 | } 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /Data Structures/MOs with Update.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 2e5 + 9; 5 | const int B = 2500; 6 | 7 | struct query { 8 | int l, r, t, id; 9 | bool operator < (const query &x) const { 10 | if(l / B == x.l / B) { 11 | if(r / B == x.r / B) return t < x.t; 12 | return r / B < x.r / B; 13 | } 14 | return l / B < x.l / B; 15 | } 16 | } Q[N]; 17 | struct upd { 18 | int pos, old, cur; 19 | } U[N]; 20 | 21 | int a[N]; 22 | int cnt[N], f[N], ans[N], l, r, t; 23 | inline void add(int x) { 24 | f[cnt[x]]--, ++cnt[x], f[cnt[x]]++; 25 | } 26 | inline void del(int x) { 27 | f[cnt[x]]--, --cnt[x], f[cnt[x]]++; 28 | } 29 | inline void update(int pos, int x) { 30 | if (l <= pos && pos <= r) { 31 | add(x); 32 | del(a[pos]); 33 | } 34 | a[pos] = x; 35 | } 36 | map mp; 37 | int nxt = 0; 38 | int get(int x) { 39 | return mp.count(x) ? mp[x] : mp[x] = ++nxt; 40 | } 41 | int main() { 42 | ios_base::sync_with_stdio(0); 43 | cin.tie(0); 44 | 45 | int n, q; 46 | cin >> n >> q; 47 | for (int i = 1; i <= n; i++) { 48 | cin >> a[i]; 49 | a[i] = get(a[i]); 50 | } 51 | int nq = 0, nu = 0; 52 | for (int i = 1; i <= q; i++) { 53 | int ty, l, r; 54 | cin >> ty >> l >> r; 55 | if (ty == 1) ++nq, Q[nq] = {l, r, nu, nq}; 56 | else ++nu, U[nu].pos = l, U[nu].old = a[l], a[l] = get(r), U[nu].cur = a[l]; 57 | } 58 | sort(Q + 1, Q + nq + 1); 59 | t = nu, l = 1, r = 0; 60 | for (int i = 1; i <= nq; i++) { 61 | int L = Q[i].l, R = Q[i].r, T = Q[i].t; 62 | while(t < T) t++, update(U[t].pos, U[t].cur); 63 | while(t > T) update(U[t].pos, U[t].old), t--; 64 | if(R < l) { 65 | while(l > L) add(a[--l]); 66 | while(l < L) del(a[l++]); 67 | while(r < R) add(a[++r]); 68 | while(r > R) del(a[r--]); 69 | } else { 70 | while(r < R) add(a[++r]); 71 | while(r > R) del(a[r--]); 72 | while(l > L) add(a[--l]); 73 | while(l < L) del(a[l++]); 74 | } 75 | int cur = 1; 76 | while(f[cur] > 0) cur++; 77 | ans[Q[i].id] = cur; 78 | } 79 | for (int i = 1; i <= nq; i++) cout << ans[i] << '\n'; 80 | return 0; 81 | } 82 | //https://codeforces.com/contest/940/problem/F 83 | -------------------------------------------------------------------------------- /Graph Theory/3 CYCLE and 4 CYCLE.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9; 5 | 6 | /*given a simple undirected graph with n nodes and m edges 7 | with no self loops or multiple edges 8 | find the number of 3 and 4 length cycles 9 | two cycles are different if their edge collections are different*/ 10 | vector g[N], G[N]; 11 | int val[N]; 12 | int deg[N];//degrees, precalc it 13 | //m.sqrt(m) 14 | long long cycle3(int n) { 15 | int i, x; 16 | long long w = 0; 17 | for(i = 1; i <= n; i++) G[i].clear(); 18 | for(i = 1; i <= n; i++) val[i] = 0; 19 | for(i = 1; i <= n; i++) { 20 | for(auto e : g[i]) { 21 | if(e < i) continue; 22 | if(deg[i] <= deg[e]) G[i].push_back(e); 23 | else G[e].push_back(i); 24 | } 25 | } 26 | for(i = 1; i <= n; i++) { 27 | for(auto u : G[i]) val[u] = i; 28 | for(auto e : g[i]) { 29 | if(e < i) continue; 30 | //x = deg[i] + deg[e] - 3; 31 | for(auto v : G[e]) { 32 | if(val[v] == i) { 33 | w++; 34 | //w+=x + deg[v] - 2;//for number of 3-cycles with or without an extra edge 35 | //connected to any node of the cycle 36 | } 37 | } 38 | } 39 | } 40 | return w; 41 | } 42 | //m.sqrt(m) 43 | long long cycle4(int n) { 44 | int i, x; 45 | long long w = 0; 46 | for(i = 1; i <= n; i++) G[i].clear(); 47 | for(i = 1; i <= n; i++) val[i] = 0; 48 | for(i = 1; i <= n; i++) { 49 | for(auto e : g[i]) { 50 | if(e < i) continue; 51 | if(deg[i] <= deg[e]) G[i].push_back(e); 52 | else G[e].push_back(i); 53 | } 54 | } 55 | for(i = 1; i <= n; i++) { 56 | for(auto u : g[i]) { 57 | for(auto v : G[u]) { 58 | if(deg[v] > deg[i] || (deg[v] == deg[i] && v > i)) w += val[v]++; 59 | } 60 | } 61 | for(auto u : g[i]) { 62 | for(auto v : G[u]) val[v] = 0; 63 | } 64 | } 65 | return w; 66 | } 67 | int32_t main() { 68 | int n, m; 69 | cin >> n >> m; 70 | for(int i = 0; i < m; i++) { 71 | int u, v; 72 | cin >> u >> v; 73 | g[u].push_back(v), g[v].push_back(u); 74 | } 75 | for(int i = 1; i <= n; i++) deg[i] = g[i].size(); 76 | cout << cycle3(n) << ' ' << cycle4(n) << '\n'; 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /Number Theory/Linear Diophantine With N Unknowns and Two Equations.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | using ll = long long; 5 | 6 | /** 7 | given are a[i], b[i], p and q: 8 | sum(x[i] * a[i]) = p --- (i) 9 | sum(x[i] * b[i]) = q --- (ii) 10 | x[i]s can only be integers. 11 | 12 | does a solution exist? 13 | **/ 14 | ll extended_euclid(ll a, ll b, ll& x, ll& y) { 15 | if (b == 0) { 16 | x = 1; y = 0; 17 | return a; 18 | } 19 | ll x1, y1; 20 | ll d = extended_euclid(b, a % b, x1, y1); 21 | x = y1; 22 | y = x1 - y1 * (a / b); 23 | return d; 24 | } 25 | ll a, b, coeff; // possible points that can be generated are of the form (a * m, b * m + k * coeff) 26 | // add (a[i], b[i]) 27 | void add(ll c, ll d) { 28 | if (c == 0 and d == 0) return; 29 | if (a == 0 and b == 0) { 30 | a = c; b = d; 31 | return; 32 | } 33 | ll x0, y0; 34 | // a * x0 + c * y0 = m * gcd(a, c) 35 | // all solutions are of the form (x0 + k * (c / g), y0 - k * (a / g)) 36 | ll g = extended_euclid(a, c, x0, y0); 37 | // replace (x, y) to the equation b * x + d * y = z 38 | ll tmp_m = b * x0 + d * y0; 39 | ll tmp_coeff = abs(b * (c / g) - d * (a / g)); 40 | coeff = __gcd(coeff, tmp_coeff); 41 | a = g; 42 | b = tmp_m % coeff; 43 | } 44 | // check if solution exists for some (p, q) 45 | bool can(ll x, ll y) { 46 | if (x == 0 and y == 0) return true; 47 | if (coeff == 0) { 48 | if (a == 0 or x % a) return false; 49 | if (b == 0 or y % b) return false; 50 | return x / a == y / b; 51 | } 52 | if (a == 0 or x % a) return false; 53 | return (y - (x / a) * b) % coeff == 0; 54 | } 55 | int32_t main() { 56 | ios_base::sync_with_stdio(0); 57 | cin.tie(0); 58 | int t, cs = 0; cin >> t; 59 | while (t--) { 60 | int q; cin >> q; 61 | a = b = coeff = 0; 62 | ll ans = 0; 63 | while (q--) { 64 | int ty; cin >> ty; 65 | if (ty == 1) { 66 | ll c, d; cin >> c >> d; 67 | add(c, d); 68 | } 69 | else { 70 | ll x, y, w; cin >> x >> y >> w; 71 | if (can(x, y)) { 72 | ans += w; 73 | } 74 | } 75 | } 76 | cout << "Case #" << ++cs << ": " << ans << '\n'; 77 | } 78 | return 0; 79 | } 80 | // https://codeforces.com/gym/102769/problem/I 81 | -------------------------------------------------------------------------------- /Data Structures/Trie.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9; 5 | 6 | struct Trie { 7 | static const int B = 31; 8 | struct node { 9 | node* nxt[2]; 10 | int sz; 11 | node() { 12 | nxt[0] = nxt[1] = NULL; 13 | sz = 0; 14 | } 15 | }*root; 16 | Trie() { 17 | root = new node(); 18 | } 19 | void insert(int val) { 20 | node* cur = root; 21 | cur -> sz++; 22 | for (int i = B - 1; i >= 0; i--) { 23 | int b = val >> i & 1; 24 | if (cur -> nxt[b] == NULL) cur -> nxt[b] = new node(); 25 | cur = cur -> nxt[b]; 26 | cur -> sz++; 27 | } 28 | } 29 | int query(int x, int k) { // number of values s.t. val ^ x < k 30 | node* cur = root; 31 | int ans = 0; 32 | for (int i = B - 1; i >= 0; i--) { 33 | if (cur == NULL) break; 34 | int b1 = x >> i & 1, b2 = k >> i & 1; 35 | if (b2 == 1) { 36 | if (cur -> nxt[b1]) ans += cur -> nxt[b1] -> sz; 37 | cur = cur -> nxt[!b1]; 38 | } else cur = cur -> nxt[b1]; 39 | } 40 | return ans; 41 | } 42 | int get_max(int x) { // returns maximum of val ^ x 43 | node* cur = root; 44 | int ans = 0; 45 | for (int i = B - 1; i >= 0; i--) { 46 | int k = x >> i & 1; 47 | if (cur -> nxt[!k]) cur = cur -> nxt[!k], ans <<= 1, ans++; 48 | else cur = cur -> nxt[k], ans <<= 1; 49 | } 50 | return ans; 51 | } 52 | int get_min(int x) { // returns minimum of val ^ x 53 | node* cur = root; 54 | int ans = 0; 55 | for (int i = B - 1; i >= 0; i--) { 56 | int k = x >> i & 1; 57 | if (cur -> nxt[k]) cur = cur -> nxt[k], ans <<= 1; 58 | else cur = cur -> nxt[!k], ans <<= 1, ans++; 59 | } 60 | return ans; 61 | } 62 | void del(node* cur) { 63 | for (int i = 0; i < 2; i++) if (cur -> nxt[i]) del(cur -> nxt[i]); 64 | delete(cur); 65 | } 66 | } t; 67 | int32_t main() { 68 | ios_base::sync_with_stdio(0); 69 | cin.tie(0); 70 | int n, k; 71 | cin >> n >> k; 72 | int cur = 0; 73 | long long ans = 1LL * n * (n + 1) / 2; 74 | t.insert(cur); 75 | for (int i = 0; i < n; i++) { 76 | int x; 77 | cin >> x; 78 | cur ^= x; 79 | ans -= t.query(cur, k); 80 | t.insert(cur); 81 | } 82 | cout << ans << '\n'; 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /Graph Theory/Tree Orientation.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | using namespace std; 4 | 5 | const int N = 3e5 + 9; 6 | 7 | vector g[N]; 8 | int sz[N]; 9 | int tot, done[N]; 10 | void calc_sz(int u, int p) { 11 | tot ++; sz[u] = 1; 12 | for (auto v: g[u]) { 13 | if(v == p || done[v]) continue; 14 | calc_sz(v, u); 15 | sz[u] += sz[v]; 16 | } 17 | } 18 | int find_cen(int u, int p) { 19 | for (auto v: g[u]) { 20 | if(v == p || done[v]) continue; 21 | else if(sz[v] > tot / 2) return find_cen(v, u); 22 | } 23 | return u; 24 | } 25 | 26 | // if sum of the array values = x, then complexity is O(x sqrt(x)) 27 | vector subset_sum(vector a) { 28 | int s = 0; 29 | for (auto x: a) { 30 | s += x; 31 | } 32 | vector cnt(s + 1, 0), dp(s + 1, 0); 33 | for (int i = 0; i < a.size(); i++) { 34 | cnt[a[i]]++; 35 | } 36 | dp[0] = 1; 37 | for (int i = 1; i <= s; i++) { 38 | if (!cnt[i]) { 39 | continue; 40 | } 41 | for (int j = 0; j < i; j++) { 42 | int c = 0; 43 | for (int k = j; k <= s; k += i) { 44 | if (dp[k]) { 45 | c = cnt[i]; 46 | } 47 | else if (c) { 48 | dp[k] = 1; 49 | c--; 50 | } 51 | } 52 | } 53 | } 54 | return dp; 55 | } 56 | 57 | long long cur; 58 | void dfs(int u, int p = 0) { 59 | sz[u] = 1; 60 | for (auto v: g[u]) { 61 | if (v ^ p) { 62 | dfs(v, u); 63 | sz[u] += sz[v]; 64 | } 65 | } 66 | cur += sz[u] - 1; 67 | } 68 | 69 | int32_t main() { 70 | ios_base::sync_with_stdio(0); 71 | cin.tie(0); 72 | int n; cin >> n; 73 | for (int i = 1; i < n; i++) { 74 | int u, v; cin >> u >> v; 75 | g[u].push_back(v); 76 | g[v].push_back(u); 77 | } 78 | calc_sz(1, 0); 79 | int r = find_cen(1, 0); 80 | dfs(r); 81 | vector v; 82 | long long ans = 0; 83 | for (auto u: g[r]) { 84 | v.push_back(sz[u]); 85 | } 86 | auto dp = subset_sum(v); 87 | for (int i = 1; i <= n - 1; i++) { 88 | if (dp[i]) { 89 | ans = max(ans, cur + 1LL * i * (n - 1 - i)); 90 | } 91 | } 92 | cout << n - 1 << ' ' << ans << '\n'; 93 | return 0; 94 | } 95 | // https://szkopul.edu.pl/problemset/problem/3bBT-3VuSu78UsxTQSwaJzVo/site/?key=statement 96 | // https://codeforces.com/blog/entry/89228 97 | -------------------------------------------------------------------------------- /Number Theory/Smallest Number Having Exactly K Divisors.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1e6 + 9, mod = 1e9 + 7; 5 | 6 | int power(long long n, long long k) { 7 | int ans = 1 % mod; n %= mod; if (n < 0) n += mod; 8 | while (k) { 9 | if (k & 1) ans = (long long) ans * n % mod; 10 | n = (long long) n * n % mod; 11 | k >>= 1; 12 | } 13 | return ans; 14 | } 15 | int spf[N]; 16 | vector primes; 17 | void sieve() { 18 | for(int i = 2; i < N; i++) { 19 | if (spf[i] == 0) spf[i] = i, primes.push_back(i); 20 | int sz = primes.size(); 21 | for (int j = 0; j < sz && i * primes[j] < N && primes[j] <= spf[i]; j++) { 22 | spf[i * primes[j]] = primes[j]; 23 | } 24 | } 25 | } 26 | double lgp[N]; 27 | vector v; 28 | unordered_map> dp[100]; 29 | pair yo(int i, long long n) { // it solves for odd divisors 30 | if (n == 1) { 31 | return {0, 1}; 32 | } 33 | if (dp[i].find(n) != dp[i].end()) { 34 | return dp[i][n]; 35 | } 36 | pair ans = {1e50, 0}; 37 | for (auto x: v) { 38 | if (x > n) break; 39 | if (n % x != 0) continue; 40 | auto z = lgp[i + 1] * (x - 1); // i for all divisors 41 | if (z > ans.first) { 42 | break; 43 | } 44 | auto cur = yo(i + 1, n / x); 45 | cur.first += z; 46 | cur.second = 1LL * cur.second * power(primes[i + 1], x - 1) % mod; // i for all divisors 47 | ans = min(ans, cur); 48 | } 49 | return dp[i][n] = ans; 50 | } 51 | int32_t main() { 52 | ios_base::sync_with_stdio(0); 53 | cin.tie(0); 54 | sieve(); 55 | for (int i = 0; i < 100; i++) { 56 | lgp[i] = log(primes[i]); 57 | } 58 | int t, cs = 0; cin >> t; 59 | while (t--) { 60 | long long n; cin >> n; 61 | ++n; 62 | if (n == 1) { 63 | cout << "Case " << ++cs << ": " << 1 << '\n'; 64 | continue; 65 | } 66 | v.clear(); 67 | for (int i = 1; 1LL * i * i <= n; i++) { 68 | if (n % i == 0) { 69 | if (i > 1) v.push_back(i); 70 | if (i != n / i) { 71 | v.push_back(n / i); 72 | } 73 | } 74 | } 75 | sort(v.begin(), v.end()); 76 | cout << "Case " << ++cs << ": " << yo(0, n).second << '\n'; 77 | } 78 | return 0; 79 | } 80 | // https://lightoj.com/problem/politeness 81 | -------------------------------------------------------------------------------- /Graph Theory/Dinics Algorithm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 5010; 5 | 6 | const long long inf = 1LL << 61; 7 | struct Dinic { 8 | struct edge { 9 | int to, rev; 10 | long long flow, w; 11 | int id; 12 | }; 13 | int n, s, t, mxid; 14 | vector d, flow_through; 15 | vector done; 16 | vector> g; 17 | Dinic() {} 18 | Dinic(int _n) { 19 | n = _n + 10; 20 | mxid = 0; 21 | g.resize(n); 22 | } 23 | void add_edge(int u, int v, long long w, int id = -1) { 24 | edge a = {v, (int)g[v].size(), 0, w, id}; 25 | edge b = {u, (int)g[u].size(), 0, 0, -2};//for bidirectional edges cap(b) = w 26 | g[u].emplace_back(a); 27 | g[v].emplace_back(b); 28 | mxid = max(mxid, id); 29 | } 30 | bool bfs() { 31 | d.assign(n, -1); 32 | d[s] = 0; 33 | queue q; 34 | q.push(s); 35 | while (!q.empty()) { 36 | int u = q.front(); 37 | q.pop(); 38 | for (auto &e : g[u]) { 39 | int v = e.to; 40 | if (d[v] == -1 && e.flow < e.w) d[v] = d[u] + 1, q.push(v); 41 | } 42 | } 43 | return d[t] != -1; 44 | } 45 | long long dfs(int u, long long flow) { 46 | if (u == t) return flow; 47 | for (int &i = done[u]; i < (int)g[u].size(); i++) { 48 | edge &e = g[u][i]; 49 | if (e.w <= e.flow) continue; 50 | int v = e.to; 51 | if (d[v] == d[u] + 1) { 52 | long long nw = dfs(v, min(flow, e.w - e.flow)); 53 | if (nw > 0) { 54 | e.flow += nw; 55 | g[v][e.rev].flow -= nw; 56 | return nw; 57 | } 58 | } 59 | } 60 | return 0; 61 | } 62 | long long max_flow(int _s, int _t) { 63 | s = _s; 64 | t = _t; 65 | long long flow = 0; 66 | while (bfs()) { 67 | done.assign(n, 0); 68 | while (long long nw = dfs(s, inf)) flow += nw; 69 | } 70 | flow_through.assign(mxid + 10, 0); 71 | for(int i = 0; i < n; i++) for(auto e : g[i]) if(e.id >= 0) flow_through[e.id] = e.flow; 72 | return flow; 73 | } 74 | }; 75 | int main() { 76 | int n, m; 77 | cin >> n >> m; 78 | Dinic F(n + 1); 79 | for (int i = 1; i <= m; i++) { 80 | int u, v, w; 81 | cin >> u >> v >> w; 82 | F.add_edge(u, v, w); 83 | } 84 | cout << F.max_flow(1, n) << '\n'; 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /Graph Theory/Stoer Wagner Algorithm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 155; 5 | 6 | //O(n^3) but faster, 1 indexed 7 | mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count()); 8 | struct StoerWagner { 9 | int n; 10 | long long G[N][N], dis[N]; 11 | int idx[N]; 12 | bool vis[N]; 13 | const long long inf = 1e18; 14 | StoerWagner() {} 15 | StoerWagner(int _n) { 16 | n = _n; 17 | memset(G, 0, sizeof G); 18 | } 19 | void add_edge(int u, int v, long long w) { //undirected edge, multiple edges are merged into one edge 20 | if (u != v) { 21 | G[u][v] += w; 22 | G[v][u] += w; 23 | } 24 | } 25 | long long solve() { 26 | long long ans = inf; 27 | for (int i = 0; i < n; ++ i) idx[i] = i + 1; 28 | shuffle(idx, idx + n, rnd); 29 | while (n > 1) { 30 | int t = 1, s = 0; 31 | for (int i = 1; i < n; ++ i) { 32 | dis[idx[i]] = G[idx[0]][idx[i]]; 33 | if (dis[idx[i]] > dis[idx[t]]) t = i; 34 | } 35 | memset(vis, 0, sizeof vis); 36 | vis[idx[0]] = true; 37 | for (int i = 1; i < n; ++ i) { 38 | if (i == n - 1) { 39 | if (ans > dis[idx[t]]) ans = dis[idx[t]]; //idx[s] - idx[t] is in two halves of the mincut 40 | if (ans == 0) return 0; 41 | for (int j = 0; j < n; ++ j) { 42 | G[idx[s]][idx[j]] += G[idx[j]][idx[t]]; 43 | G[idx[j]][idx[s]] += G[idx[j]][idx[t]]; 44 | } 45 | idx[t] = idx[-- n]; 46 | } 47 | vis[idx[t]] = true; 48 | s = t; 49 | t = -1; 50 | for (int j = 1; j < n; ++ j) { 51 | if (!vis[idx[j]]) { 52 | dis[idx[j]] += G[idx[s]][idx[j]]; 53 | if (t == -1 || dis[idx[t]] < dis[idx[j]]) t = j; 54 | } 55 | } 56 | } 57 | } 58 | return ans; 59 | } 60 | }; 61 | 62 | int32_t main() { 63 | ios_base::sync_with_stdio(0); 64 | cin.tie(0); 65 | int t, cs = 0; 66 | cin >> t; 67 | while (t--) { 68 | int n, m; 69 | cin >> n >> m; 70 | StoerWagner st(n); 71 | while (m--) { 72 | int u, v, w; 73 | cin >> u >> v >> w; 74 | st.add_edge(u, v, w); 75 | } 76 | cout << "Case #" << ++cs << ": " << st.solve() << '\n'; 77 | } 78 | return 0; 79 | } 80 | //https://vjudge.net/problem/UVA-10989 81 | -------------------------------------------------------------------------------- /Strings/Bit LCS.cpp: -------------------------------------------------------------------------------- 1 | #pragma GCC optimize("Ofast") 2 | #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,fma") 3 | #pragma GCC optimize("unroll-loops") 4 | 5 | #include 6 | using namespace std; 7 | /* Bit-String Longest Common Subsequence Algorithm 8 | O(nm/w)*/ 9 | const int N = 5e4 + 9, SIGMA = 26; 10 | const int W = 62; 11 | int M; 12 | struct Bitset { 13 | long long u[N / W + 5]; 14 | void clear() { 15 | memset(u, 0, sizeof(u)); 16 | } 17 | void set(int x) { 18 | u[x / W] |= 1ll << (x % W); 19 | } 20 | Bitset operator | (const Bitset &r) const { 21 | Bitset s; 22 | for (int i = 0; i < M; ++ i) { 23 | s.u[i] = u[i] | r.u[i]; 24 | } 25 | return s; 26 | } 27 | void yo(const Bitset &r) { 28 | for (int i = 0; i < M; ++ i) { 29 | u[i] = (u[i] ^ r.u[i]) & r.u[i]; 30 | } 31 | } 32 | void sub(const Bitset &r) { 33 | for (int i = 0; i < M; ++ i) u[i] = r.u[i] - u[i]; 34 | for (int i = 0; i < M; ++ i) if (u[i] < 0) { 35 | u[i] += 1ll << W; 36 | u[i + 1] --; 37 | } 38 | } 39 | void shl() { 40 | long long c = 1; 41 | for (long i = 0; i < M; ++ i) { 42 | u[i] <<= 1; 43 | u[i] |= c; 44 | c = u[i] >> W & 1; 45 | u[i] ^= c << W; 46 | } 47 | } 48 | int count() const { 49 | int c = 0; 50 | for (int i = 0; i < M; ++ i) { 51 | c += __builtin_popcountll(u[i]); 52 | } 53 | return c; 54 | } 55 | } row, bs[SIGMA], x; 56 | int main() { 57 | for (int i = 0; i < SIGMA; ++i) bs[i].clear(); 58 | string s, t; 59 | cin >> s >> t; 60 | int n = s.size(), m = t.size(); 61 | for (int i = 0; i < n; ++ i) { 62 | bs[s[i] - 'a'].set(i); 63 | } 64 | M = n / W + (n % W != 0); 65 | row.clear(); 66 | for (int i = 0; i < m; ++i) { 67 | for (int j = 0; j < M; ++j) { 68 | x.u[j] = row.u[j] | bs[t[i] - 'a'].u[j]; 69 | } 70 | row.shl(); 71 | row.sub(x); 72 | row.yo(x); 73 | //printf("%d\n", row.count()); //lcs of prefix of t and whole s 74 | } 75 | cout << row.count() << '\n'; 76 | return 0; 77 | } 78 | //https://www.spoj.com/problems/LCS0/ 79 | -------------------------------------------------------------------------------- /Data Structures/BIT 2D with Range Update and Range Query.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1010; 5 | 6 | struct BIT2D { 7 | long long M[N][N][2], A[N][N][2]; 8 | BIT2D() { 9 | memset(M, 0, sizeof M); 10 | memset(A, 0, sizeof A); 11 | } 12 | void upd2(long long t[N][N][2], int x, int y, long long mul, long long add) { 13 | for(int i = x; i < N; i += i & -i) { 14 | for(int j = y; j < N; j += j & -j) { 15 | t[i][j][0] += mul; 16 | t[i][j][1] += add; 17 | } 18 | } 19 | } 20 | void upd1(int x, int y1, int y2, long long mul, long long add) { 21 | upd2(M, x, y1, mul, -mul * (y1 - 1)); 22 | upd2(M, x, y2, -mul, mul * y2); 23 | upd2(A, x, y1, add, -add * (y1 - 1)); 24 | upd2(A, x, y2, -add, add * y2); 25 | } 26 | void upd(int x1, int y1, int x2, int y2, long long val) { 27 | upd1(x1, y1, y2, val, -val * (x1 - 1)); 28 | upd1(x2, y1, y2, -val, val * x2); 29 | } 30 | long long query2(long long t[N][N][2], int x, int y) { 31 | long long mul = 0, add = 0; 32 | for(int i = y; i > 0; i -= i & -i) { 33 | mul += t[x][i][0]; 34 | add += t[x][i][1]; 35 | } 36 | return mul * x + add; 37 | } 38 | long long query1(int x, int y) { 39 | long long mul = 0, add = 0; 40 | for(int i = x; i > 0; i -= i & -i) { 41 | mul += query2(M, i, y); 42 | add += query2(A, i, y); 43 | } 44 | return mul * x + add; 45 | } 46 | long long query(int x1, int y1, int x2, int y2) { 47 | return query1(x2, y2) - query1(x1 - 1, y2) - query1(x2, y1 - 1) + query1(x1 - 1, y1 - 1); 48 | } 49 | } t; 50 | int main() { 51 | int n, m; 52 | cin >> n >> m; 53 | for(int i = 1; i <= n; i++) { 54 | for(int j = 1; j <= m; j++) { 55 | int k; 56 | cin >> k; 57 | t.upd(i, j, i, j, k); 58 | } 59 | } 60 | int q; 61 | cin >> q; 62 | while(q--) { 63 | int ty, x1, y1, x2, y2; 64 | cin >> ty; 65 | if(ty == 1) { 66 | long long val; 67 | cin >> x1 >> y1 >> x2 >> y2 >> val; 68 | t.upd(x1, y1, x2, y2, val); // add val from top-left(x1, y1) to bottom-right (x2, y2); 69 | } else { 70 | cin >> x1 >> y1 >> x2 >> y2; 71 | cout << t.query(x1, y1, x2, y2) << '\n'; // output sum from top-left(x1, y1) to bottom-right (x2, y2); 72 | 73 | } 74 | } 75 | return 0; 76 | } 77 | -------------------------------------------------------------------------------- /Strings/String Hashing 2D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9; 5 | 6 | struct Hashing { 7 | vector> hs; 8 | vector PWX, PWY; 9 | int n, m; 10 | static const int PX = 3731, PY = 2999, mod = 998244353; 11 | Hashing() {} 12 | Hashing(vector& s) { 13 | n = (int)s.size(), m = (int)s[0].size(); 14 | hs.assign(n + 1, vector(m + 1, 0)); 15 | PWX.assign(n + 1, 1); 16 | PWY.assign(m + 1, 1); 17 | for (int i = 0; i < n; i++) PWX[i + 1] = 1LL * PWX[i] * PX % mod; 18 | for (int i = 0; i < m; i++) PWY[i + 1] = 1LL * PWY[i] * PY % mod; 19 | for (int i = 0; i < n; i++) { 20 | for (int j = 0; j < m; j++) { 21 | hs[i + 1][j + 1] = s[i][j] - 'a' + 1; 22 | } 23 | } 24 | for (int i = 0; i <= n; i++) { 25 | for (int j = 0; j < m; j++) { 26 | hs[i][j + 1] = (hs[i][j + 1] + 1LL * hs[i][j] * PY % mod) % mod; 27 | } 28 | } 29 | for (int i = 0; i < n; i++) { 30 | for (int j = 0; j <= m; j++) { 31 | hs[i + 1][j] = (hs[i + 1][j] + 1LL * hs[i][j] * PX % mod) % mod; 32 | } 33 | } 34 | } 35 | int get_hash(int x1, int y1, int x2, int y2) { // 1-indexed 36 | assert(1 <= x1 && x1 <= x2 && x2 <= n); 37 | assert(1 <= y1 && y1 <= y2 && y2 <= m); 38 | x1--; 39 | y1--; 40 | int dx = x2 - x1, dy = y2 - y1; 41 | return (1LL * (hs[x2][y2] - 1LL * hs[x2][y1] * PWY[dy] % mod + mod) % mod - 42 | 1LL * (hs[x1][y2] - 1LL * hs[x1][y1] * PWY[dy] % mod + mod) % mod * PWX[dx] % mod + mod) % mod; 43 | } 44 | int get_hash() { 45 | return get_hash(1, 1, n, m); 46 | } 47 | }; 48 | int32_t main() { 49 | ios_base::sync_with_stdio(0); 50 | cin.tie(0); 51 | int t; 52 | cin >> t; 53 | while (t--) { 54 | int n, m; 55 | cin >> n >> m; 56 | vector a(n); 57 | for (int i = 0; i < n; i++) cin >> a[i]; 58 | Hashing H(a); 59 | int x, y; 60 | cin >> x >> y; 61 | vector b(x); 62 | for (int i = 0; i < x; i++) cin >> b[i]; 63 | auto z = Hashing(b).get_hash(); 64 | int ans = 0; 65 | for (int i = 1; i <= n; i++) { 66 | for (int j = 1; j <= m; j++) { 67 | if (i + x - 1 <= n && j + y - 1 <= m && H.get_hash(i, j, i + x - 1, j + y - 1) == z) ans++; 68 | } 69 | } 70 | cout << ans << '\n'; 71 | } 72 | return 0; 73 | } 74 | // https://vjudge.net/problem/UVA-11019 75 | -------------------------------------------------------------------------------- /Strings/String Hashing.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1e6 + 9; 5 | 6 | int power(long long n, long long k, const int mod) { 7 | int ans = 1 % mod; 8 | n %= mod; 9 | if (n < 0) n += mod; 10 | while (k) { 11 | if (k & 1) ans = (long long) ans * n % mod; 12 | n = (long long) n * n % mod; 13 | k >>= 1; 14 | } 15 | return ans; 16 | } 17 | 18 | const int MOD1 = 127657753, MOD2 = 987654319; 19 | const int p1 = 137, p2 = 277; 20 | int ip1, ip2; 21 | pair pw[N], ipw[N]; 22 | void prec() { 23 | pw[0] = {1, 1}; 24 | for (int i = 1; i < N; i++) { 25 | pw[i].first = 1LL * pw[i - 1].first * p1 % MOD1; 26 | pw[i].second = 1LL * pw[i - 1].second * p2 % MOD2; 27 | } 28 | ip1 = power(p1, MOD1 - 2, MOD1); 29 | ip2 = power(p2, MOD2 - 2, MOD2); 30 | ipw[0] = {1, 1}; 31 | for (int i = 1; i < N; i++) { 32 | ipw[i].first = 1LL * ipw[i - 1].first * ip1 % MOD1; 33 | ipw[i].second = 1LL * ipw[i - 1].second * ip2 % MOD2; 34 | } 35 | 36 | } 37 | struct Hashing { 38 | int n; 39 | string s; // 0 - indexed 40 | vector> hs; // 1 - indexed 41 | Hashing() {} 42 | Hashing(string _s) { 43 | n = _s.size(); 44 | s = _s; 45 | hs.emplace_back(0, 0); 46 | for (int i = 0; i < n; i++) { 47 | pair p; 48 | p.first = (hs[i].first + 1LL * pw[i].first * s[i] % MOD1) % MOD1; 49 | p.second = (hs[i].second + 1LL * pw[i].second * s[i] % MOD2) % MOD2; 50 | hs.push_back(p); 51 | } 52 | } 53 | pair get_hash(int l, int r) { // 1 - indexed 54 | assert(1 <= l && l <= r && r <= n); 55 | pair ans; 56 | ans.first = (hs[r].first - hs[l - 1].first + MOD1) * 1LL * ipw[l - 1].first % MOD1; 57 | ans.second = (hs[r].second - hs[l - 1].second + MOD2) * 1LL * ipw[l - 1].second % MOD2; 58 | return ans; 59 | } 60 | pair get_hash() { 61 | return get_hash(1, n); 62 | } 63 | }; 64 | int32_t main() { 65 | ios_base::sync_with_stdio(0); 66 | cin.tie(0); 67 | prec(); 68 | int n; 69 | while (cin >> n) { 70 | string s, p; 71 | cin >> p >> s; 72 | Hashing h(s); 73 | auto hs = Hashing(p).get_hash(); 74 | for(int i = 1; i + n - 1 <= s.size(); i++) { 75 | if (h.get_hash(i, i + n - 1) == hs) cout << i - 1 << '\n'; 76 | } 77 | cout << '\n'; 78 | } 79 | return 0; 80 | } 81 | // https://www.spoj.com/problems/NHAY/ 82 | -------------------------------------------------------------------------------- /Graph Theory/Dijkstra on Segment Tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1e5 + 9; 5 | 6 | vector> g[N * 9]; 7 | inline void add_edge(int u, int v, int w) { 8 | g[u].push_back({v, w}); 9 | } 10 | int add; 11 | void build(int n, int b, int e) { 12 | if (b == e) { 13 | add_edge(b, n + add, 0); 14 | add_edge(n + add * 5, b, 0); 15 | return; 16 | } 17 | int mid = b + e >> 1; 18 | add_edge(2 * n + add, n + add, 0); 19 | add_edge(2 * n + 1 + add, n + add, 0); 20 | add_edge(n + 5 * add, 2 * n + 5 * add, 0); 21 | add_edge(n + 5 * add, 2 * n + 1 + 5 * add, 0); 22 | build(2 * n, b, mid); 23 | build(2 * n + 1, mid + 1, e); 24 | } 25 | void upd(int n, int b, int e, int i, int j, int dir, int u, int w) { 26 | if (j < b || e < i) return; 27 | if (i <= b && e <= j) { 28 | if (dir) add_edge(u, n + 5 * add, w); // from u to this range 29 | else add_edge(n + add, u, w); // from this range to u 30 | return; 31 | } 32 | int mid = (b + e) >> 1; 33 | upd(2 * n, b, mid, i, j, dir, u, w); 34 | upd(2 * n + 1, mid + 1, e, i, j, dir, u, w); 35 | } 36 | 37 | vector dijkstra(int s) { 38 | const long long inf = 1e18; 39 | priority_queue, vector>, greater>> q; 40 | vector d(9 * N + 1, inf); vector vis(9 * N + 1, 0); 41 | q.push({0, s}); 42 | d[s] = 0; 43 | while(!q.empty()){ 44 | auto x = q.top(); q.pop(); 45 | int u = x.second; 46 | if(vis[u]) continue; vis[u] = 1; 47 | for(auto y: g[u]){ 48 | int v = y.first; long long w = y.second; 49 | if(d[u] + w < d[v]){ 50 | d[v] = d[u] + w; q.push({d[v], v}); 51 | } 52 | } 53 | } 54 | return d; 55 | } 56 | long long ans[N]; 57 | int32_t main() { 58 | ios_base::sync_with_stdio(0); 59 | cin.tie(0); 60 | int n, q, s; cin >> n >> q >> s; 61 | add = n; 62 | build(1, 1, n); 63 | while (q--) { 64 | int ty; cin >> ty; 65 | int u, l, r, w; 66 | if (ty == 1) { 67 | cin >> u >> l >> w; 68 | r = l; 69 | } 70 | else { 71 | cin >> u >> l >> r >> w; 72 | } 73 | upd(1, 1, n, l, r, ty <= 2, u, w); 74 | } 75 | auto ans = dijkstra(s); 76 | for (int i = 1; i <= n; i++) { 77 | if (ans[i] == 1e18) ans[i] = -1; 78 | cout << ans[i] << ' '; 79 | } 80 | return 0; 81 | } 82 | // https://codeforces.com/contest/786/problem/B -------------------------------------------------------------------------------- /Graph Theory/Steiner Tree Problem.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1e5 + 9; 5 | 6 | /* 7 | Find the minimum cost connected tree where at least the important nodes are connected 8 | dp(x,i) = minimum cost of a tree rooted at i connecting the important node in bitmask x. 9 | Complexity: O(3^k * n + 2^k * m log m) 10 | */ 11 | 12 | int n, k, m; 13 | vector imp;//k important nodes 14 | vector> g[N]; 15 | long long d[32][N]; //[2^k][edge count] 16 | const long long inf = LLONG_MAX / 3; 17 | bool vis[N]; 18 | long long MST() { 19 | for(int i = 0; i < (1 << k); i++) fill(d[i], d[i] + N, inf); 20 | for(int i = 0; i < k; ++i) { 21 | d[1 << i][imp[i]] = 0; 22 | } 23 | priority_queue> q; 24 | for(int mask = 1; mask < (1 << k); ++mask) { 25 | for(int a = 0; a < mask; ++a) { //you can still fasten this loop to get exact 3^k complexity 26 | if((a | mask) != mask) continue; //we only need the subsets 27 | int b = mask ^ a; 28 | if(b > a) continue; 29 | for(int v = 0; v < n; ++v) { 30 | d[mask][v] = min(d[mask][v], d[a][v] + d[b][v]); 31 | } 32 | } 33 | memset(vis, 0, sizeof vis); 34 | for(int v = 0; v < n; ++v) { 35 | if(d[mask][v] == inf) continue; 36 | q.emplace(-d[mask][v], v); 37 | } 38 | 39 | while(!q.empty()) { 40 | long long cost = -q.top().first; 41 | int v = q.top().second; 42 | q.pop(); 43 | if(vis[v]) continue; 44 | vis[v] = true; 45 | for(auto edge : g[v]) { 46 | long long ec = cost + edge.second; 47 | if(ec < d[mask][edge.first]) { 48 | d[mask][edge.first] = ec; 49 | q.emplace(-ec, edge.first); 50 | } 51 | } 52 | } 53 | } 54 | 55 | long long res = inf; 56 | for(int v = 0; v < n; ++v) { 57 | res = min(res, d[(1 << k) - 1][v]); 58 | } 59 | return res; 60 | } 61 | int main() { 62 | ios_base::sync_with_stdio(0); 63 | cin.tie(0); 64 | 65 | cin >> n >> k >> m; 66 | imp.resize(k); 67 | for(int i = 0; i < k; ++i) { 68 | cin >> imp[i]; 69 | --imp[i]; 70 | } 71 | for(int i = 0; i < m; ++i) { 72 | int u, v; 73 | long long w; 74 | cin >> u >> v >> w; 75 | --u; 76 | --v; 77 | g[u].emplace_back(v, w); 78 | g[v].emplace_back(u, w); 79 | } 80 | cout << MST() << '\n'; 81 | return 0; 82 | } 83 | //https://www.youtube.com/watch?v=BG4vAoV5kWw 84 | --------------------------------------------------------------------------------