├── Basics ├── Binary Exponentiation.cpp ├── Binary Search.cpp ├── Binomial Coefficients.cpp ├── Bitmasks.cpp ├── Bitwise Operations.cpp ├── Bubble Sort.cpp ├── Counting Sort.cpp ├── Divisors.cpp ├── GCD and LCM.cpp ├── Harmonic Number Example.cpp ├── Insertion Sort.cpp ├── Merge Sort.cpp ├── Prefix Sum 2D.cpp ├── Prefix Sum.cpp ├── Prefix Xor.cpp ├── Selection Sort.cpp └── Two Pointers.cpp ├── Data Structures ├── .gitkeep ├── 4D MO.cpp ├── Augmented DSU.cpp ├── BIT 2D with Range Update and Range Query.cpp ├── BIT with Range Update and Range Query.cpp ├── BIT.cpp ├── BST using STL.cpp ├── BST.cpp ├── Balanced Bracket Tree.cpp ├── Binarizing a Tree.cpp ├── Cartesian Tree.cpp ├── Centroid Decomposition Persistent.cpp ├── Centroid Decomposition.cpp ├── DSU Partially Persistent.cpp ├── DSU on Tree.cpp ├── DSU with Rollbacks.cpp ├── DSU.cpp ├── Disjoint Sparse Table.cpp ├── Dynamic Connectivity Problem.cpp ├── Dynamic Diameter Online.cpp ├── GP Hash Table.cpp ├── HLD.cpp ├── Implicit Treap.cpp ├── Interval Set.cpp ├── KD Tree.cpp ├── LCA.cpp ├── Link Cut Tree.cpp ├── MOs Algorithm.cpp ├── MOs Online.cpp ├── MOs on tree.cpp ├── MOs with DSU.cpp ├── MOs with Update.cpp ├── Monotonous Queue.cpp ├── Ordered Set.cpp ├── Permutation Tree.cpp ├── Persistent Array.cpp ├── Persistent Meldable Heap.cpp ├── Persistent Queue.cpp ├── Persistent Trie.cpp ├── Persistent UnionFind.cpp ├── Queue Undo Trick.cpp ├── Reachability Tree.cpp ├── SQRT Tree.cpp ├── Segment Tree 2D Dynamic.cpp ├── Segment Tree Beats.cpp ├── Segment Tree Lazy.cpp ├── Segment Tree Merging.cpp ├── Segment Tree NonRecursive.cpp ├── Segment Tree Persistent Lazy.cpp ├── Segment Tree Persistent.cpp ├── Segment Tree with Arithmetic Progression.cpp ├── Segment Tree.cpp ├── Sparse Table 2D.cpp ├── Sparse Table.cpp ├── Square Root Decomposition With Reverse Update.cpp ├── Static to Dynamic Trick.cpp ├── Top Tree.cpp ├── Treap persistent.cpp ├── Treap.cpp ├── Trie.cpp ├── Venice Technique.cpp ├── Wavelet Tree.cpp └── XOR Segment Tree.cpp ├── Dynamic Programming Optimizations ├── .gitkeep ├── 1D1D DP.cpp ├── Bounded Knapsack.cpp ├── Connected Component DP.cpp ├── Convex Hull Trick.cpp ├── DP Over Divisors.cpp ├── DP on Convex Hulls.cpp ├── Digit DP.cpp ├── Divide and Conquer Optimization.cpp ├── Dynamic Convex Hull Trick.cpp ├── Dynamic Submask Count.cpp ├── Hirschbergs Algorithm.cpp ├── Knuth Optimization.cpp ├── Li Chao Tree.cpp ├── Number of Subsequences Having Product at least K.cpp ├── Persistent CHT.cpp ├── Persistent Li Chao Tree.cpp ├── SOS DP.cpp ├── SOS convolutions.cpp ├── Subset Sum in SQRT.cpp ├── Subset Union of Bitsets.cpp ├── XOR Equation.cpp └── x2 +1 trick.cpp ├── Game Theory ├── .gitkeep ├── Alpha Beta Pruning.cpp ├── Blue Red Hackenbush.cpp ├── Green Hackenbush.cpp └── Matching Game On A Graph.cpp ├── Geometry ├── .gitkeep] ├── All Pair Segment Intersection.cpp ├── Closest Pair of Points.cpp ├── Convex Hull Dynamic.cpp ├── Delaunay Triangulation.cpp ├── Geometry 2D.cpp ├── Geometry 3D.cpp ├── Half Plane Intersection Dynamic.cpp ├── Half Plane Intersection.cpp ├── Maximum Area of Triangle, Given are Lengths.cpp ├── Onion Decomposition.cpp ├── Point Location.cpp ├── Rectangle Union.cpp └── Voronoi Diagram.cpp ├── Graph Theory ├── .gitkeep ├── 2 SAT.cpp ├── 3 CYCLE and 4 CYCLE.cpp ├── 3 SAT.cpp ├── Articulation Bridges.cpp ├── Articulation Points.cpp ├── BFS.cpp ├── Bellman Ford.cpp ├── Block Cut Tree.cpp ├── Blossom Algorithm Weighted.cpp ├── Blossom Algorithm.cpp ├── Boruvka's Algorithm.cpp ├── Cactus Graph.cpp ├── Centroids.cpp ├── Chinese Postman Problem.cpp ├── Chordal Graph.cpp ├── Chromatic Number.cpp ├── Chromatic Polynoimial.cpp ├── Counting Labeled Graphs.cpp ├── Cycle Detection.cpp ├── DAG Reachability Dynamic.cpp ├── DFS.cpp ├── Dijkstra on Segment Tree.cpp ├── Dijkstra.cpp ├── Dinics Algorithm.cpp ├── Directed MST.cpp ├── Dominator Tree.cpp ├── Dynamic MST Offline.cpp ├── Edge Coloring Bipartite Graph Faster.cpp ├── Edge Coloring Bipartite Graph.cpp ├── Edge Coloring Simple Graph.cpp ├── Eppsteins Algorithm.cpp ├── Euler Path Directed.cpp ├── Euler Path Undirected.cpp ├── Floyd Warshall.cpp ├── Gomory Hu Tree of Planar Graph.cpp ├── Gomory Hu Tree.cpp ├── Hafnian of a Matrix.cpp ├── HopCroft Karp Algorithm.cpp ├── Hungarian Algorithm.cpp ├── Inverse Graph.cpp ├── Johnson's Algorithm.cpp ├── Kirchoffs Theorem.cpp ├── Krushkal's MST.cpp ├── Kuhns Algorithm.cpp ├── L R Flow with Dinic.cpp ├── L R Flow with MCMF.cpp ├── LCA in O(1).cpp ├── LCA.cpp ├── Long Path Decomposition.cpp ├── Manhattan MST.cpp ├── Maximum Clique and Maximum Independent Set Super Fast.cpp ├── Maximum Clique.cpp ├── Maximum Closure Problem.cpp ├── Maximum Density Subgraph.cpp ├── Min Cost Max Flow with Negative Cycles.cpp ├── Min Cost Max Flow.cpp ├── Min Cut in a Planar Graph.cpp ├── Minimum Cost Vertex Cover General Graph.cpp ├── Minimum Diameter Spanning Tree.cpp ├── Minimum Mean Weight Cycle.cpp ├── Minimum Weight Cycle For Each Edge.cpp ├── Minimum Weight Cycle For Each Vertex.cpp ├── Number of Arborescence.cpp ├── Number of DAG.cpp ├── Number of Different Cliques.cpp ├── Number of Paths of Each Length in a Tree.cpp ├── Online Articulation Bridges.cpp ├── Path Intersection.cpp ├── Path Union.cpp ├── Prim's MST.cpp ├── Prufer Code.cpp ├── Randomized Matching Unweighted.cpp ├── Randomized Matching Weighted.cpp ├── SCC.cpp ├── SPFA.cpp ├── ST Numbering.cpp ├── Shortest Path That Doesnt Pass Through Each Edge.cpp ├── Stable Marriage Problem.cpp ├── Steiner Tree Problem.cpp ├── Stoer Wagner Algorithm.cpp ├── System Of Difference Constraints.cpp ├── Three Edge Connectivity.cpp ├── Topological Sorting.cpp ├── Tree Diameter.cpp ├── Tree Isomorphism.cpp ├── Tree Orientation.cpp ├── Tree and Graph Counting.docx ├── Tuttes Theorem.cpp ├── Unique Min Cut.cpp └── Virtual Tree.cpp ├── Guidelines.md ├── LICENSE.txt ├── Math ├── .gitkeep ├── All Possible Perfect Matching XOR Values.cpp ├── Basis Vector Reduced Row Echelon Form.cpp ├── Basis Vector ft Weighted Linearly Independent Vectors.cpp ├── Basis Vector.cpp ├── BerleKamp Massey.cpp ├── Characteristic Polynomial Faster.cpp ├── Cyclic Convolution.cpp ├── Determinant of Cyclic Matrix.cpp ├── Determinant of Permutant Matrix.cpp ├── Determinant of Product Matrix.cpp ├── Determinant of Sparse Matrix.cpp ├── Determinant under Composite Modulo.cpp ├── Determinant under Prime Modulo.cpp ├── Determinant.cpp ├── FFT.cpp ├── FWHT in Any Base.cpp ├── FWHT in Ternary Base.cpp ├── FWHT.cpp ├── Faulhaber Formula Fastest.cpp ├── Finite Field Arithmetic Binary.cpp ├── Freivalds Algorithm.cpp ├── Gaussian Elimination Modular.cpp ├── Gaussian Elimination Modulo 2.cpp ├── Gaussian Elimination.cpp ├── Generating Function of a Linear Recurrence.cpp ├── Generating Functions and Polynomials.docx ├── Hafnian of a Matrix.cpp ├── Integration (Romberg).cpp ├── Integration (Simpsons).cpp ├── Inverse of A Matrix modulo 2.cpp ├── Inverse of A Matrix.cpp ├── Lagrange Interpolation Brute.cpp ├── Lagrange Interpolation with Polynomial Extraction.cpp ├── Lagrange Interpolation.cpp ├── Lagrange Multiplier.cpp ├── Linear Recurrence Fastest.cpp ├── Linear Recurrence With Polynomial Coefficients.cpp ├── Linear Recurrence.cpp ├── Matrix Exponentiation With Polynomial Coefficients.cpp ├── Matrix Exponentiation.cpp ├── Max Convolution between Convex Funtions.cpp ├── Modint.cpp ├── NTT 2D.cpp ├── NTT Online (D&C).cpp ├── NTT Online.cpp ├── NTT With Any Prime MOD.cpp ├── NTT.cpp ├── Number of Solutions of A Equation MITM.cpp ├── Permanent of a Matrix.cpp ├── Polynomial Factorization.cpp ├── Polynomial Sum.cpp ├── Polynomial with Binomial Coefficients.cpp ├── Polynomial.cpp ├── Reeds Sloane Algorithm.cpp ├── Simplex Algorithm.cpp ├── Subset Sum Problem.cpp ├── The Slime Trick.cpp ├── Thomas Algorithm.cpp ├── Vandermonde Matrix.cpp └── q Binomial.cpp ├── Miscellaneous ├── .gitkeep ├── BigInt.cpp ├── Bitset Custom.cpp ├── Dates.cpp ├── Expression Parsing.cpp ├── Fraction Binary Search.cpp ├── Gray Code.cpp ├── Inversions.cpp ├── Josephus Problem.cpp ├── K-th Root of a Permutation.cpp ├── Knight Moves in Infinity Grid.cpp ├── Logarithmic Subarray Aggregator.cpp ├── MEX of all Subarrays.cpp ├── Matroid Intersection Color Graphic Matroid.cpp ├── Matroid Intersection Color Linear Matroid.cpp ├── Maximum of Sum of All Pair Distances of K nodes in a Tree.cpp ├── Min Plus Convolution (Convex and Convex).cpp ├── Negative Base (Binary).cpp ├── Parallel Binary Search.cpp ├── Permutation Cycles.cpp ├── Schreier–Sims algorithm.cpp ├── Space Remover For Codebook.cpp ├── Stress Testing.cpp ├── Subset Union of Bitsets.cpp ├── Trygub Num.cpp └── XOR Equation Arbitrary Range.cpp ├── Number Theory ├── .gitkeep ├── Bell Number.cpp ├── CRT.cpp ├── Combinatorics Basics.cpp ├── Continued Fractions.cpp ├── Derangement.cpp ├── Dirichlet Convolution.cpp ├── Discrete Log.cpp ├── Discrete Root Faster.cpp ├── Discrete Root.cpp ├── Extended Euclid.cpp ├── Factoradic Number System.cpp ├── Fermats Theorem on Sum of Two Squares.cpp ├── Fibonacci Number Faster.cpp ├── Floor Sum of Arithmetic Progressions.cpp ├── Generalized Floor Sum of Arithmetic Progressions.cpp ├── Intersection of Arithmetic Progressions.cpp ├── K Divisors.cpp ├── LCM of Fibonacci Numbers.cpp ├── Linear Congruence Equation.cpp ├── Linear Diophantine Equation Three Variables with Nonnegative Solutions.cpp ├── Linear Diophantine Equation with N Variables.cpp ├── Linear Diophantine Equation with Nonnegative Solutions.cpp ├── Linear Diophantine Equation with Two Variables.cpp ├── Linear Diophantine With N Unknowns and Two Equations.cpp ├── Linear Sieve for Multiplicative Functions.cpp ├── Lucas Theorem.cpp ├── Maximum Coprime Product.cpp ├── Miller Rabin.cpp ├── Min_25 Sieve.cpp ├── Mobius Function.cpp ├── Multiplicative Order.cpp ├── Number of Distinct Kth Powers Modulo n.cpp ├── Number of Nonnegative Integer Solutions to ax+by less than or equal to c.cpp ├── Number of Solutions to a Basic Linear Algebraic Equation with Variable Upper Bound Constraints.cpp ├── Number of Solutions to a Basic Linear Algebraic Equation.cpp ├── Number of Solutions to x^2 = 1 mod m.cpp ├── Number of ax%p in a Range.cpp ├── Partition Function.cpp ├── Pells Equation.py ├── Phi Field.cpp ├── Phi Function.cpp ├── Pisano Period.cpp ├── Pollard Rho.cpp ├── Power Tower.cpp ├── Powerful Number Sieve.cpp ├── Prefix Sum Queries of nCi.cpp ├── Prime Basis.cpp ├── Prime Counting Function.cpp ├── Prime Factorization Fastest.cpp ├── Prime Number System.cpp ├── Primitive Root.cpp ├── Pythagorean Triplets.cpp ├── Rational Approximation.cpp ├── Rational Approximation.py ├── Sieve Linear.cpp ├── Sieve upto 1e9.cpp ├── Sieve.cpp ├── Smallest Nonnegative Integer x s.t. l <= ax % p <= r.cpp ├── Smallest Number Having Exactly K Divisors.cpp ├── Stirling Number of the First Kind for Fixed k.cpp ├── Stirling Number of the First Kind for Fixed n.cpp ├── Stirling Number of the Second Kind for Fixed k.cpp ├── Stirling Number of the Second Kind for Fixed n.cpp ├── Sum of Arithmetic Progression Modular and Divided.cpp ├── Sum of Arithmetic Progression Powers Divided.cpp ├── Sum of C(a(i), k) for each k from 1 to n.cpp ├── Sum of Floors.cpp ├── Sum of The Number of Divisors in cbrt(n).cpp ├── Sum of nCi for a Fixed Large n.cpp ├── Sum of nCi over a Fixed Congruence Class.cpp ├── Tonelli Shanks Algorithm.cpp └── nCr Modulo Any Mod.cpp ├── README.md └── Strings ├── .gitkeep ├── Aho Corasick All Pair Occurrence Relation.cpp ├── Aho Corasick Dynamic.cpp ├── Aho Corasick.cpp ├── All Substring Longest Common Subsequence.cpp ├── Bit LCS.cpp ├── Cyclic LCS.cpp ├── De Bruijn Sequence.cpp ├── KMP.cpp ├── Manachers.cpp ├── Minimum Palindrome Factorization.cpp ├── Number of Palindromes in Range.cpp ├── Palindromic Tree Persistent.cpp ├── Palindromic Tree.cpp ├── Prefix Automaton.cpp ├── String Hashing 2D.cpp ├── String Hashing With Updates and Reverse.cpp ├── String Hashing.cpp ├── String Matching With FFT.cpp ├── String Matching using Bitsets.cpp ├── Suffix Array Isomorphic.cpp ├── Suffix Array.cpp ├── Suffix Automaton Distinct Substring Queries in Range.cpp ├── Suffix Automaton.cpp └── Z Algorithm.cpp /Basics/Binary Exponentiation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int mod = 1e9 + 7; 5 | 6 | int power(int x, long long n) { // O(log n) 7 | int ans = 1 % mod; 8 | while (n > 0) { 9 | if (n & 1) { 10 | ans = 1LL * ans * x % mod; 11 | } 12 | x = 1LL * x * x % mod; 13 | n >>= 1; 14 | } 15 | return ans; 16 | } 17 | 18 | int32_t main() { 19 | ios_base::sync_with_stdio(0); 20 | cin.tie(0); 21 | cout << power(2, 1000000000) << '\n'; 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /Basics/Binary Search.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int32_t main() { 5 | ios_base::sync_with_stdio(0); 6 | cin.tie(0); 7 | int n, q; cin >> n >> q; 8 | int a[n + 1]; 9 | for (int i = 1; i <= n; i++) { 10 | cin >> a[i]; 11 | } 12 | // a is already sorted 13 | while (q--) { 14 | int x; cin >> x; 15 | int l = 1, r = n; 16 | bool found = false; 17 | while (l <= r) { 18 | int mid = (l + r) / 2; 19 | if (a[mid] == x) { 20 | found = true; 21 | break; 22 | } 23 | else if (a[mid] < x) { 24 | l = mid + 1; 25 | } 26 | else { 27 | r = mid - 1; 28 | } 29 | } 30 | if (found) { 31 | cout << "YES\n"; 32 | } 33 | else { 34 | cout << "NO\n"; 35 | } 36 | } 37 | return 0; 38 | } 39 | // https://codeforces.com/edu/course/2/lesson/6/1/practice/contest/283911/problem/A 40 | -------------------------------------------------------------------------------- /Basics/Binomial Coefficients.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1e6 + 9, mod = 1e9 + 7; 5 | 6 | int f[N], inv[N], finv[N]; 7 | void prec() { 8 | f[0] = 1; 9 | for (int i = 1; i < N; i++) f[i] = 1LL * i * f[i - 1] % mod; 10 | inv[1] = 1; 11 | for (int i = 2; i < N; i++ ) { 12 | inv[i] = (-(1LL * mod / i) * inv[mod % i] ) % mod; 13 | inv[i] = (inv[i] + mod) % mod; 14 | } 15 | finv[0] = 1; 16 | for (int i = 1; i < N; i++) finv[i] = 1LL * inv[i] * finv[i - 1] % mod; 17 | } 18 | int ncr(int n, int r) { 19 | if (n < r || n < 0 || r < 0) return 0; 20 | return 1LL * f[n] * finv[n - r] % mod * finv[r] % mod; 21 | } 22 | 23 | // void brute() { 24 | // for (int i = 0; i < N; i++) { 25 | // C[i][0] = 1; 26 | // } 27 | // for (int i = 1; i < N; i++) { 28 | // for (int j = 1; j <= i; j++) { 29 | // C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % mod; 30 | // } 31 | // } 32 | // } 33 | 34 | int32_t main() { 35 | ios_base::sync_with_stdio(0); 36 | cin.tie(0); 37 | prec(); 38 | int q; cin >> q; 39 | while (q--) { 40 | int n, r; cin >> n >> r; 41 | cout << ncr(n, r) << '\n'; 42 | } 43 | return 0; 44 | } 45 | // https://cses.fi/problemset/task/1079/ 46 | -------------------------------------------------------------------------------- /Basics/Bitmasks.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | int n, l, r, x; cin >> n >> l >> r >> x; 6 | int c[n]; 7 | for (int i = 0; i < n; i++) { 8 | cin >> c[i]; 9 | } 10 | int ans = 0; 11 | for (int mask = 0; mask < (1 << n); mask++) { 12 | // fix the subset as the elements under this bitmask 13 | int total_problems = 0, total_difficulty = 0; 14 | int min_difficulty = 1e6 + 9, max_difficulty = 0; 15 | for (int i = 0; i < n; i++) { 16 | if ((mask >> i) & 1) { 17 | total_problems++; 18 | total_difficulty += c[i]; 19 | min_difficulty = min(min_difficulty, c[i]); 20 | max_difficulty = max(max_difficulty, c[i]); 21 | } 22 | } 23 | if (total_problems >= 2 and total_difficulty >= l and total_difficulty <= r 24 | and abs(min_difficulty - max_difficulty) >= x) { 25 | ans++; 26 | } 27 | } 28 | cout << ans << '\n'; 29 | return 0; 30 | } 31 | // Time: O(n * 2^n) 32 | // Space: O(n) 33 | // https://codeforces.com/problemset/problem/550/B 34 | -------------------------------------------------------------------------------- /Basics/Bubble Sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int32_t main() { 5 | ios_base::sync_with_stdio(0); 6 | cin.tie(0); 7 | int n; cin >> n; 8 | int a[n + 1]; 9 | for (int i = 1; i <= n; i++) { 10 | cin >> a[i]; 11 | } 12 | int swaps = 0; 13 | for (int step = 1; step <= n - 1; step++) { 14 | for (int i = 1; i < n; i++) { 15 | if (a[i] > a[i + 1]) { 16 | swap(a[i], a[i + 1]); 17 | ++swaps; 18 | } 19 | } 20 | } 21 | cout << "Array is sorted in " << swaps << " swaps.\n"; 22 | cout << "First Element: " << a[1] << '\n'; 23 | cout << "Last Element: " << a[n] << '\n'; 24 | return 0; 25 | } 26 | // https://vjudge.net/problem/HackerRank-ctci-bubble-sort 27 | -------------------------------------------------------------------------------- /Basics/Counting Sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int MAX = 100; 5 | int32_t main() { 6 | ios_base::sync_with_stdio(0); 7 | cin.tie(0); 8 | int n; cin >> n; 9 | vector cnt(MAX + 1, 0); 10 | for (int i = 1; i <= n; i++) { 11 | int x; cin >> x; 12 | cnt[x]++; 13 | } 14 | for (int i = 0; i <= MAX; i++) { 15 | while (cnt[i] > 0) { 16 | cout << i << ' '; 17 | cnt[i]--; 18 | } 19 | } 20 | cout << '\n'; 21 | return 0; 22 | } 23 | // https://vjudge.net/problem/HackerRank-countingsort2 24 | -------------------------------------------------------------------------------- /Basics/Divisors.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | using ll = long long; 5 | 6 | vector get_divisors(ll n) { 7 | vector divs; 8 | for (int i = 1; 1LL * i * i <= n; i++) { 9 | if (n % i == 0) { 10 | divs.push_back(i); 11 | if (i != n / i) { 12 | divs.push_back(n / i); 13 | } 14 | } 15 | } 16 | sort(divs.begin(), divs.end()); 17 | return divs; 18 | } 19 | 20 | int32_t main() { 21 | ios_base::sync_with_stdio(0); 22 | cin.tie(0); 23 | ll n, k; cin >> n >> k; 24 | vector divs = get_divisors(n); 25 | if (k > divs.size()) { 26 | cout << -1 << '\n'; 27 | } else { 28 | cout << divs[k - 1] << '\n'; 29 | } 30 | return 0; 31 | } 32 | // https://codeforces.com/problemset/problem/762/A 33 | -------------------------------------------------------------------------------- /Basics/GCD and LCM.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int32_t main() { 5 | ios_base::sync_with_stdio(0); 6 | cin.tie(0); 7 | int t; cin >> t; 8 | while (t--) { 9 | int a, b; cin >> a >> b; 10 | int GCD = __gcd(a, b); 11 | long long LCM = 1LL * a * b / GCD; 12 | cout << LCM << ' ' << GCD << '\n'; 13 | } 14 | return 0; 15 | } 16 | // https://vjudge.net/problem/HackerRank-si-lcm-and-hcf 17 | -------------------------------------------------------------------------------- /Basics/Harmonic Number Example.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1e6 + 9; 5 | int d[N]; 6 | int32_t main() { 7 | ios_base::sync_with_stdio(0); 8 | cin.tie(0); 9 | 10 | // total complexity of the following two loops = O(n logn) 11 | // because the number of times the loops are running 12 | // = n / 1 + n / 2 + ... + n / n 13 | // = n * (1 / 1 + 1 / 2 + ... + 1 / n) 14 | // = n * H(n) [here H(n) is nth Harmonic number] 15 | // = O(n * log(n)) because H(n) is around O(log n) 16 | for (int i = 1; i < N; i++) { 17 | for (int j = i; j < N; j += i) { 18 | d[j]++; 19 | } 20 | } 21 | 22 | int t; cin >> t; 23 | while (t--) { 24 | int n; cin >> n; 25 | cout << d[n] << '\n'; 26 | } 27 | return 0; 28 | } 29 | // https://cses.fi/problemset/task/1713/ 30 | -------------------------------------------------------------------------------- /Basics/Insertion Sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int32_t main() { 5 | ios_base::sync_with_stdio(0); 6 | cin.tie(0); 7 | int n; cin >> n; 8 | int a[n + 1]; 9 | for (int i = 1; i <= n; i++) { 10 | cin >> a[i]; 11 | } 12 | for (int i = 1; i <= n; i++) { 13 | int j = i - 1, x = a[i]; 14 | while (j >= 1 and a[j] > x) { 15 | a[j + 1] = a[j]; 16 | j--; 17 | } 18 | a[j + 1] = x; 19 | } 20 | for (int i = 1; i <= n; i++) { 21 | cout << a[i] << ' '; 22 | } 23 | cout << '\n'; 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /Basics/Merge Sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | vector merge(vector &l, vector &r) { 5 | int n = l.size(), m = r.size(); 6 | vector ans; 7 | int i = 0, j = 0; 8 | while (i < n && j < m) { 9 | if (l[i] < r[j]) ans.push_back(l[i++]); 10 | else ans.push_back(r[j++]); 11 | } 12 | while (i < n) ans.push_back(l[i++]); 13 | while (j < m) ans.push_back(r[j++]); 14 | return ans; 15 | } 16 | vector a; 17 | vector merge_sort(int l, int r) { 18 | if (l == r) return {a[l]}; 19 | int mid = l + r >> 1; 20 | vector left = merge_sort(l, mid); 21 | vector right = merge_sort(mid + 1, r); 22 | return merge(left, right); 23 | } 24 | 25 | int32_t main() { 26 | ios_base::sync_with_stdio(0); 27 | cin.tie(0); 28 | int n; cin >> n; 29 | a.resize(n); 30 | for (int i = 0; i < n; i++) { 31 | cin >> a[i]; 32 | } 33 | vector ans = merge_sort(0, n - 1); 34 | for (int i = 0; i < n; i++) { 35 | cout << ans[i] << ' '; 36 | } 37 | return 0; 38 | } 39 | // https://vjudge.net/problem/Gym-324997D 40 | -------------------------------------------------------------------------------- /Basics/Prefix Sum 2D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1005; 5 | int a[N][N], pref[N][N]; 6 | int32_t main() { 7 | ios_base::sync_with_stdio(0); 8 | cin.tie(0); 9 | int n, m; cin >> n >> m; 10 | for (int i = 1; i <= n; i++) { 11 | for (int j = 1; j <= m; j++) { 12 | cin >> a[i][j]; 13 | } 14 | } 15 | for (int i = 1; i <= n; i++) { 16 | for (int j = 1; j <= m; j++) { 17 | pref[i][j] = pref[i - 1][j] + pref[i][j - 1] - pref[i - 1][j - 1] + a[i][j]; 18 | } 19 | } 20 | int q; cin >> q; 21 | while (q--) { 22 | int x1, y1, x2, y2; cin >> x1 >> y1 >> x2 >> y2; 23 | int ans = 0; 24 | // for (int i = x1; i <= x2; i++) { 25 | // for (int j = y1; j <= y2; j++) { 26 | // ans += a[i][j]; 27 | // } 28 | // } 29 | ans = pref[x2][y2] - pref[x1 - 1][y2] - pref[x2][y1 - 1] + pref[x1 - 1][y1 - 1]; 30 | cout << ans << '\n'; 31 | } 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /Basics/Prefix Sum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 2e5 + 9; 5 | long long pref_sum[N]; 6 | int a[N]; 7 | int32_t main() { 8 | ios_base::sync_with_stdio(0); 9 | cin.tie(0); 10 | int n, q; cin >> n >> q; 11 | for (int i = 1; i <= n; i++) { 12 | cin >> a[i]; 13 | } 14 | for (int i = 1; i <= n; i++) { 15 | pref_sum[i] = pref_sum[i - 1] + a[i]; 16 | } 17 | while (q--) { 18 | int l, r; cin >> l >> r; 19 | cout << pref_sum[r] - pref_sum[l - 1] << '\n'; 20 | } 21 | return 0; 22 | } 23 | // https://cses.fi/problemset/task/1646/ 24 | -------------------------------------------------------------------------------- /Basics/Prefix Xor.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 2e5 + 9; 5 | int pref_xor[N]; 6 | int a[N]; 7 | int32_t main() { 8 | ios_base::sync_with_stdio(0); 9 | cin.tie(0); 10 | int n, q; cin >> n >> q; 11 | for (int i = 1; i <= n; i++) { 12 | cin >> a[i]; 13 | } 14 | for (int i = 1; i <= n; i++) { 15 | pref_xor[i] = pref_xor[i - 1] ^ a[i]; 16 | } 17 | while (q--) { 18 | int l, r; cin >> l >> r; 19 | cout << (pref_xor[r] ^ pref_xor[l - 1]) << '\n'; 20 | } 21 | return 0; 22 | } 23 | // https://cses.fi/problemset/task/1646/ 24 | -------------------------------------------------------------------------------- /Basics/Selection Sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int32_t main() { 5 | ios_base::sync_with_stdio(0); 6 | cin.tie(0); 7 | int n; cin >> n; 8 | int a[n + 1]; 9 | for (int i = 1; i <= n; i++) { 10 | cin >> a[i]; 11 | } 12 | int swaps = 0; 13 | for (int i = 1; i <= n; i++) { 14 | int min_index = i; 15 | for (int j = i + 1; j <= n; j++) { 16 | if (a[j] < a[min_index]) { 17 | min_index = j; 18 | } 19 | } 20 | if (i != min_index) { 21 | swap(a[i], a[min_index]); 22 | ++swaps; 23 | } 24 | } 25 | for (int i = 1; i <= n; i++) { 26 | if (i > 1) cout << ' '; 27 | cout << a[i]; 28 | } 29 | cout << '\n'; 30 | cout << swaps << '\n'; 31 | return 0; 32 | } 33 | // https://vjudge.net/problem/Aizu-ALDS1_2_B 34 | -------------------------------------------------------------------------------- /Basics/Two Pointers.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | using ll = long long; 5 | const int N = 1e5 + 9; 6 | int a[N]; 7 | int32_t main() { 8 | ios_base::sync_with_stdio(0); 9 | cin.tie(0); 10 | int n; ll s; cin >> n >> s; 11 | for (int i = 1; i <= n; i++) { 12 | cin >> a[i]; 13 | } 14 | ll ans = 0; 15 | int r = 1; 16 | ll sum = 0; 17 | for (int l = 1; l <= n; l++) { 18 | while (r <= n and sum + a[r] <= s) { 19 | sum += a[r]; 20 | r++; 21 | } 22 | // r - 1 is the maximum index i such that sum of a[l...i] is <= s 23 | ans += r - l; 24 | sum -= a[l]; 25 | } 26 | cout << ans << '\n'; 27 | return 0; 28 | } 29 | // https://codeforces.com/edu/course/2/lesson/9/2/practice/contest/307093/problem/C 30 | -------------------------------------------------------------------------------- /Data Structures/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Data Structures/Balanced Bracket Tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 2e5 + 9; 5 | // there is a directed edge from bracket i to bracket j if j is directly inside i 6 | vector g[N]; 7 | int sz[N]; 8 | void dfs(int u) { 9 | sz[u] = 1; 10 | for (auto v: g[u]) { 11 | dfs(v); 12 | sz[u] += sz[v]; 13 | } 14 | } 15 | int32_t main() { 16 | ios_base::sync_with_stdio(0); 17 | cin.tie(0); 18 | int t; cin >> t; 19 | while (t--) { 20 | int k; cin >> k; 21 | string s; cin >> s; 22 | int bracket_id = 0; 23 | vector roots; 24 | vector st; 25 | for (auto c: s) { 26 | if (c == '(') { 27 | st.push_back(++bracket_id); 28 | } 29 | else { 30 | int cur_bracket_id = st.back(); 31 | st.pop_back(); 32 | if (!st.empty()) { 33 | int par_bracket_id = st.back(); 34 | g[par_bracket_id].push_back(cur_bracket_id); 35 | } 36 | else { 37 | roots.push_back(cur_bracket_id); 38 | } 39 | } 40 | } 41 | for (int r: roots) { 42 | dfs(r); 43 | } 44 | sort(sz + 1, sz + bracket_id + 1); 45 | long long ans = 0; 46 | for (int i = 1; i <= bracket_id - k; i++) { 47 | ans += sz[i] - 1; 48 | } 49 | cout << ans << '\n'; 50 | 51 | for (int i = 1; i <= bracket_id; i++) { 52 | g[i].clear(); 53 | } 54 | } 55 | return 0; 56 | } 57 | // https://codeforces.com/contest/1821/problem/E 58 | -------------------------------------------------------------------------------- /Data Structures/Centroid Decomposition.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1e5 + 9; 5 | 6 | vector g[N]; 7 | int sz[N]; 8 | int tot, done[N], cenpar[N]; 9 | void calc_sz(int u, int p) { 10 | tot ++; 11 | 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 | void decompose(int u, int pre) { 26 | tot = 0; 27 | calc_sz(u, pre); 28 | int cen = find_cen(u, pre); 29 | cenpar[cen] = pre; 30 | done[cen] = 1; 31 | for(auto v : g[cen]) { 32 | if(v == pre || done[v]) continue; 33 | decompose(v, cen); 34 | } 35 | } 36 | int dep[N]; 37 | void dfs(int u, int p = 0) { 38 | for(auto v : g[u]) { 39 | if(v == p) continue; 40 | dep[v] = dep[u] + 1; 41 | dfs(v, u); 42 | } 43 | } 44 | int main() { 45 | ios_base::sync_with_stdio(0); 46 | cin.tie(0); 47 | int n; 48 | cin >> n; 49 | for(int i = 1; i < n; i++) { 50 | int u, v; 51 | cin >> u >> v; 52 | g[u].push_back(v); 53 | g[v].push_back(u); 54 | } 55 | decompose(1, 0); 56 | 57 | 58 | for(int i = 1; i <= n; i++) g[i].clear(); 59 | int root; 60 | for(int i = 1; i <= n; i++) { 61 | g[cenpar[i]].push_back(i); 62 | g[i].push_back(cenpar[i]); 63 | if (cenpar[i] == 0) root = i; 64 | } 65 | dfs(root); 66 | for(int i = 1; i <= n; i++) cout << char(dep[i] + 'A') << ' '; 67 | return 0; 68 | } 69 | // https://codeforces.com/contest/321/problem/C 70 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/GP Hash Table.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #include 4 | #include 5 | using namespace __gnu_pbds; 6 | 7 | struct custom_hash { 8 | static uint64_t splitmix64(uint64_t x) { 9 | x += 0x9e3779b97f4a7c15; 10 | x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; 11 | x = (x ^ (x >> 27)) * 0x94d049bb133111eb; 12 | return x ^ (x >> 31); 13 | } 14 | size_t operator()(uint64_t x) const { 15 | static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); 16 | return splitmix64(x + FIXED_RANDOM); 17 | } 18 | }; 19 | 20 | gp_hash_table mp; 21 | 22 | int32_t main() { 23 | ios_base::sync_with_stdio(0); 24 | cin.tie(0); 25 | int n, x; cin >> n >> x; 26 | int a[n + 1]; 27 | for (int i = 1; i <= n; i++) { 28 | cin >> a[i]; 29 | } 30 | for (int i = 1; i <= n; i++) { 31 | if (mp[x - a[i]]) { 32 | cout << mp[x - a[i]] << ' ' << i << '\n'; 33 | return 0; 34 | } 35 | mp[a[i]] = i; 36 | } 37 | cout << "IMPOSSIBLE\n"; 38 | return 0; 39 | } 40 | // https://cses.fi/problemset/task/1640 41 | -------------------------------------------------------------------------------- /Data Structures/Interval Set.cpp: -------------------------------------------------------------------------------- 1 | #include 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 | -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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/Persistent Meldable Heap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | // https://en.wikipedia.org/wiki/Leftist_tree 4 | // Tested on: https://judge.yosupo.jp/problem/k_shortest_walk 5 | 6 | template 7 | struct heap { 8 | struct node{ 9 | node* ch[2] = {0, 0}; 10 | int sz; T val; 11 | node(T val): sz(1), val(val) {} 12 | 13 | }; 14 | node* root = 0; 15 | heap(node* t = 0): root(t) {} 16 | node* meld(node* a, node* b) { 17 | if (!b) return a ? new node(*a) : 0; 18 | if (!a) return b ? new node(*b) : 0; 19 | a = new node(*a); b = new node(*b); 20 | if (a -> val > b -> val) swap(a, b); 21 | a -> ch[1] = meld(a -> ch[1], b); 22 | if (!a -> ch[0] || a -> ch[0] -> sz < a -> ch[1] -> sz) swap(a -> ch[0], a -> ch[1]); 23 | a -> sz = (a -> ch[1] ? a -> ch[1] -> sz : 0) + 1; 24 | return a; 25 | } 26 | heap meld(heap b) { // merging two heaps 27 | return heap(meld(root, b.root)); 28 | } 29 | heap insert(T x) { // inserting and returing the new heap, the previous heap doesn't change 30 | return heap(meld(root, new node(x))); 31 | } 32 | heap pop() { // pops and returns the new heap without modifying the previous version 33 | return heap(meld(root -> ch[0], root -> ch[1])); 34 | } 35 | T top() { // returns the smallest value of the heap 36 | return root ? root -> val : T(-1); 37 | } 38 | bool empty() { 39 | return !root; 40 | } 41 | }; 42 | 43 | heap h[100]; 44 | int32_t main() { 45 | ios_base::sync_with_stdio(0); 46 | cin.tie(0); 47 | for (int i = 0; i < 100; i++) { 48 | h[i] = heap(); 49 | } 50 | h[1] = h[0].insert(20); 51 | h[2] = h[1].insert(10); 52 | h[3] = h[2].insert(30); 53 | 54 | h[4] = h[1].insert(5); 55 | h[4] = h[4].insert(15); 56 | h[5] = h[4].meld(h[3]); 57 | for (int i = 1; i <= 5; i++) { 58 | cout << h[i].top() << '\n'; 59 | } 60 | cout << "h[5]:\n"; 61 | while (h[5].top() != -1) { 62 | cout << h[5].top() << '\n'; 63 | h[5] = h[5].pop(); 64 | } 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 Node { 8 | int sum; 9 | 10 | Node() { sum = 0; } 11 | Node(int val) { sum = val; } 12 | }; 13 | 14 | struct ST { 15 | int n; 16 | Node *t; 17 | ST(int _n) { n = _n; t = new Node[2 * n]; } 18 | 19 | inline Node combine(Node l, Node r) { 20 | Node res; 21 | res.sum = l.sum + r.sum; 22 | return res; 23 | } 24 | 25 | void build() { 26 | for(int i = 0; i < n; i++) t[i + n] = Node(a[i+1]); 27 | for(int i = n - 1; i > 0; --i) t[i] = combine(t[i << 1], t[i << 1 | 1]); 28 | } 29 | 30 | void upd(int p, int v) { 31 | p--; 32 | for (t[p += n] = Node(v); p >>= 1; ) t[p] = combine(t[p << 1], t[p << 1 | 1]); 33 | } 34 | 35 | Node query(int l, int r) { 36 | --l; 37 | bool f1 = 1, f2 = 1; 38 | Node resl, resr; 39 | for(l += n, r += n; l < r; l >>= 1, r >>= 1) { 40 | if(l & 1) resl = f1 ? t[l++] : combine(resl, t[l++]), f1 = 0; 41 | if(r & 1) resr = f2 ? t[--r] : combine(t[--r], resr), f2 = 0; 42 | } 43 | if(f2) return resl; 44 | if(f1) return resr; 45 | return combine(resl, resr); 46 | } 47 | }; 48 | 49 | int32_t main() { 50 | n = 3; 51 | a[1] = 1; 52 | a[2] = 2; 53 | a[3] = 3; 54 | ST t = ST(n); 55 | t.build(); 56 | cout << t.query(1, 2).sum << '\n'; 57 | t.upd(2, 10); 58 | cout << t.query(1, 3).sum << '\n'; 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/Static to Dynamic Trick.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int LG = 20; 5 | // an example static DS which takes multiples integers 6 | // and in the end it processes those data once in >= O(n) 7 | // then it can query each time fast enough 8 | struct ds_static { 9 | ds_static() {} 10 | vector v; 11 | void insert(int x) { 12 | v.push_back(x); 13 | } 14 | 15 | void process() { 16 | sort(v.begin(), v.end()); 17 | } 18 | 19 | // how many numbers <= x 20 | int query(int x) { 21 | return upper_bound(v.begin(), v.end(), x) - v.begin(); 22 | } 23 | 24 | void clear() { 25 | v.clear(); 26 | } 27 | }; 28 | 29 | // now we can make this static ds into a dynamic ds 30 | // means, it can query anytime (not necessarily only at the end) 31 | // we can do it by only adding another log factor 32 | struct ds_dynamic { 33 | vector li[LG]; 34 | ds_static ds[LG]; 35 | 36 | void clear() { 37 | for(int i = 0; i < LG; i++) { 38 | li[i].clear(); 39 | ds[i].clear(); 40 | } 41 | } 42 | 43 | ds_dynamic() { 44 | clear(); 45 | } 46 | 47 | void insert(int x) { 48 | int pos = 0; 49 | for(int l = 0; l < LG; l++) { 50 | if(li[l].empty()) { 51 | pos = l; 52 | break; 53 | } 54 | } 55 | 56 | li[pos].push_back(x); 57 | ds[pos].insert(x); 58 | 59 | for(int bef = 0; bef < pos; bef++) { 60 | ds[bef].clear(); 61 | for(int x2 : li[bef]) { 62 | li[pos].push_back(x2); 63 | ds[pos].insert(x2); 64 | } 65 | 66 | li[bef].clear(); 67 | } 68 | 69 | ds[pos].process(); 70 | } 71 | 72 | // how many numbers <= x 73 | int query(int x) { 74 | int ans = 0; 75 | for(int l = 0; l < LG; l++) { 76 | ans += ds[l].query(x); 77 | } 78 | return ans; 79 | } 80 | }; 81 | 82 | ds_dynamic ds; 83 | 84 | int main() { 85 | ios_base::sync_with_stdio(0); 86 | cin.tie(0); 87 | int n = 100000; 88 | long long res_sum = 0; 89 | for (int i = 1; i <= n; i++) { 90 | int x = rand(); 91 | ds.insert(x); 92 | res_sum += ds.query(rand()); 93 | } 94 | cout << res_sum << '\n'; 95 | return 0; 96 | } 97 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Dynamic Programming Optimizations/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Dynamic Programming Optimizations/SOS DP.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int B = 20; 5 | int a[1 << B], f[1 << B], g[1 << B]; 6 | int32_t main() { 7 | ios_base::sync_with_stdio(0); 8 | cin.tie(0); 9 | int n; cin >> n; 10 | for (int i = 1; i <= n; i++) { 11 | cin >> a[i]; 12 | f[a[i]]++; 13 | g[a[i]]++; 14 | } 15 | 16 | // sum over subsets 17 | for (int i = 0; i < B; i++) { 18 | for (int mask = 0; mask < (1 << B); mask++) { 19 | if ((mask & (1 << i)) != 0) { 20 | f[mask] += f[mask ^ (1 << i)]; 21 | } 22 | } 23 | } 24 | 25 | // sum over supersets 26 | for (int i = 0; i < B; i++) { 27 | for (int mask = (1 << B) - 1 ; mask >= 0 ; mask--) { 28 | if ((mask & (1 << i)) == 0) g[mask] += g[mask ^ (1 << i)] ; 29 | } 30 | } 31 | 32 | for (int i = 1; i <= n; i++) { 33 | cout << f[a[i]] << ' ' << g[a[i]] << ' ' << n - f[(1 << B) - 1 - a[i]] << '\n'; 34 | } 35 | return 0; 36 | } 37 | // https://cses.fi/problemset/task/1654 38 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Game Theory/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Geometry/.gitkeep]: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /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 = {p[0].y, p[1].y}; 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 | -------------------------------------------------------------------------------- /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 > d 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 | -------------------------------------------------------------------------------- /Geometry/Rectangle Union.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1e5 + 9; 5 | 6 | struct Line { 7 | int x, ymin, ymax, ty ; 8 | Line() {} 9 | Line(int _x, int _ym, int _ymx, int _ty) { x = _x ; ymin = _ym ; ymax = _ymx ; ty = _ty ; } 10 | bool operator < (const Line &e) const { return x < e.x ; } 11 | }; 12 | Line all[N * 2]; 13 | long long t[N * 16], mp[N * 2], lazy[N * 16]; 14 | inline void push(int n, int b, int e) { 15 | if (!lazy[n]) return; 16 | t[n] = mp[e] - mp[b] - t[n]; 17 | if (b != e) { 18 | lazy[n << 1] ^= lazy[n]; 19 | lazy[n << 1 | 1] ^= lazy[n]; 20 | } 21 | lazy[n] = 0; 22 | } 23 | void upd(int n, int b, int e, int i, int j, int ty) { 24 | push(n, b, e); 25 | if (mp[e] < i || mp[b] > j) return; 26 | if (mp[b] >= i && mp[e] <= j) { 27 | lazy[n] ^= ty; 28 | push(n, b, e); 29 | return; 30 | } 31 | if (b + 1 >= e) return; 32 | int mid = b + e >> 1, l = n << 1, r = l | 1; 33 | upd(l, b, mid, i, j, ty); 34 | upd(r, mid, e, i, j, ty); 35 | t[n] = t[l] + t[r]; 36 | } 37 | int main() { 38 | int n; cin >> n; 39 | int id = 0, m = 0 ; 40 | for (int i = 0; i < n; i++) { 41 | int x1, y1, x2, y2; scanf("%d %d %d %d", &x1, &y1, &x2, &y2); 42 | assert(x1 < x2); assert(y1 < y2); 43 | all[id++] = Line(x1, y1, y2, 1); 44 | all[id++] = Line(x2, y1, y2, 1); 45 | mp[++m] = y1 ; mp[++m] = y2 ; 46 | } 47 | n = id; 48 | sort(all, all + n); 49 | sort(mp + 1, mp + m + 1); 50 | m = unique(mp + 1, mp + m + 1) - mp - 1; 51 | upd(1, 1, m, all[0].ymin, all[0].ymax, all[0].ty); 52 | long long ans = 0 ; // sum of area covered by odd number of rectangles 53 | for (int i = 1; i < n; i++) { 54 | ans += 1LL * t[1] * (all[i].x - all[i - 1].x); 55 | upd(1, 1, m, all[i].ymin, all[i].ymax, all[i].ty); 56 | } 57 | cout << ans << '\n'; 58 | return 0; 59 | } 60 | // https://vjudge.net/problem/Gym-101982F 61 | -------------------------------------------------------------------------------- /Graph Theory/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Graph Theory/BFS.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int inf = 1e9; 5 | const int N = 1e5 + 9; 6 | vector g[N]; 7 | int32_t main() { 8 | ios_base::sync_with_stdio(0); 9 | cin.tie(0); 10 | int n, m; cin >> n >> m; 11 | for (int i = 1; i <= m; i++) { 12 | int u, v; cin >> u >> v; 13 | g[u].push_back(v); 14 | g[v].push_back(u); 15 | } 16 | queue q; 17 | vector d(n + 1, inf), par(n + 1, -1); 18 | q.push(1); 19 | d[1] = 0; 20 | while (!q.empty()) { 21 | int u = q.front(); 22 | q.pop(); 23 | for (auto v: g[u]) { 24 | if (d[u] + 1 < d[v]) { 25 | d[v] = d[u] + 1; 26 | par[v] = u; 27 | q.push(v); 28 | } 29 | } 30 | } 31 | if (d[n] == inf) { 32 | cout << "IMPOSSIBLE\n"; 33 | return 0; 34 | } 35 | cout << d[n] + 1 << '\n'; 36 | int cur = n; 37 | vector path; 38 | while (cur != -1) { 39 | path.push_back(cur); 40 | cur = par[cur]; 41 | } 42 | reverse(path.begin(), path.end()); 43 | for (auto u: path) { 44 | cout << u << ' '; 45 | } 46 | cout << '\n'; 47 | return 0; 48 | } 49 | // https://cses.fi/problemset/task/1667 50 | -------------------------------------------------------------------------------- /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 = 1e5 + 9; 5 | vector g[N]; 6 | int sz[N]; 7 | void dfs(int u, int p = 0) { 8 | sz[u] = 1; 9 | for (auto v: g[u]) { 10 | if (v ^ p) { 11 | dfs(v, u); 12 | sz[u] += sz[v]; 13 | } 14 | } 15 | } 16 | vector get_centroids(int n) { 17 | int u = 1; 18 | dfs(u); 19 | while (1) { 20 | int tmp = -1; 21 | for (auto v: g[u]) { 22 | if (sz[v] > sz[u]) continue; 23 | if (2 * sz[v] >= n) tmp = v; 24 | } 25 | if (tmp == -1) break; 26 | u = tmp; 27 | } 28 | dfs(u); 29 | for (auto v: g[u]) { 30 | if (2 * sz[v] == n) { 31 | return {u, v}; 32 | } 33 | } 34 | return {u}; 35 | } 36 | int32_t main() { 37 | ios_base::sync_with_stdio(0); 38 | cin.tie(0); 39 | int t; cin >> t; 40 | while (t--) { 41 | int n; cin >> n; 42 | for (int i = 1; i < n; i++) { 43 | int u, v; cin >> u >> v; 44 | g[u].push_back(v); 45 | g[v].push_back(u); 46 | } 47 | auto v = get_centroids(n); 48 | for (auto i: v) cout << i << ' '; cout << '\n'; 49 | for (int i = 1; i <= n; i++) g[i].clear(); 50 | } 51 | return 0; 52 | } 53 | // similar problem: https://cses.fi/problemset/task/2079 54 | -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Graph Theory/DFS.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1e5 + 9; 5 | vector g[N]; 6 | bool vis[N]; 7 | void dfs(int u) { 8 | vis[u] = true; 9 | for (auto v: g[u]) { 10 | if (!vis[v]) { 11 | dfs(v); 12 | } 13 | } 14 | } 15 | int32_t main() { 16 | ios_base::sync_with_stdio(0); 17 | cin.tie(0); 18 | int n, m; cin >> n >> m; 19 | while (m--) { 20 | int u, v; cin >> u >> v; 21 | g[u].push_back(v); 22 | g[v].push_back(u); 23 | } 24 | vector components; 25 | for (int u = 1; u <= n; u++) { 26 | if (!vis[u]) { 27 | components.push_back(u); 28 | dfs(u); 29 | } 30 | } 31 | cout << (int)components.size() - 1 << '\n'; 32 | for (int i = 0; i + 1 < (int)components.size(); i++) { 33 | cout << components[i] << ' ' << components[i + 1] << '\n'; 34 | } 35 | return 0; 36 | } 37 | // https://cses.fi/problemset/task/1666 38 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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 | } -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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 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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/Topological Sorting.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1e5 + 9; 5 | vector g[N]; 6 | bool vis[N]; 7 | vector ord; 8 | void dfs(int u) { 9 | vis[u] = true; 10 | for (auto v: g[u]) { 11 | if (!vis[v]) { 12 | dfs(v); 13 | } 14 | } 15 | ord.push_back(u); 16 | } 17 | int32_t main() { 18 | ios_base::sync_with_stdio(0); 19 | cin.tie(0); 20 | int n, m; cin >> n >> m; 21 | while (m--) { 22 | int u, v; cin >> u >> v; 23 | g[u].push_back(v); 24 | } 25 | for (int i = 1; i <= n; i++) { 26 | if (!vis[i]) { 27 | dfs(i); 28 | } 29 | } 30 | reverse(ord.begin(), ord.end()); 31 | 32 | // check is feasible 33 | vector pos(n + 1); 34 | for (int i = 0; i < (int) ord.size(); i++) { 35 | pos[ord[i]] = i; 36 | } 37 | for (int u = 1; u <= n; u++) { 38 | for (auto v: g[u]) { 39 | if (pos[u] > pos[v]) { 40 | cout << "IMPOSSIBLE\n"; 41 | return 0; 42 | } 43 | } 44 | } 45 | 46 | // print the order 47 | for (auto u: ord) cout << u << ' '; 48 | cout << '\n'; 49 | return 0; 50 | } 51 | // https://cses.fi/problemset/task/1679 52 | -------------------------------------------------------------------------------- /Graph Theory/Tree Diameter.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 2e5 + 9; 5 | 6 | vector g[N]; 7 | int farthest(int s, int n, vector &d) { 8 | static const int inf = N; 9 | d.assign(n + 1, inf); d[s] = 0; 10 | vector vis(n + 1); 11 | queue q; q.push(s); 12 | vis[s] = 1; int last = s; 13 | while (!q.empty()) { 14 | int u = q.front(); q.pop(); 15 | for (int v: g[u]) { 16 | if (vis[v]) continue; 17 | d[v] = d[u] + 1; 18 | q.push(v); vis[v] = 1; 19 | } 20 | last = u; 21 | } 22 | return last; 23 | } 24 | int32_t main() { 25 | ios_base::sync_with_stdio(0); 26 | cin.tie(0); 27 | int n; cin >> n; 28 | for (int i = 1; i < n; i++) { 29 | int u, v; cin >> u >> v; 30 | g[u].push_back(v); 31 | g[v].push_back(u); 32 | } 33 | vector dx, dy; 34 | int x = farthest(1, n, dx); 35 | int y = farthest(x, n, dx); 36 | farthest(y, n, dy); 37 | for (int i = 1; i <= n; i++) { 38 | cout << max(dx[i], dy[i]) << ' '; 39 | } 40 | cout << '\n'; 41 | return 0; 42 | } 43 | // https://cses.fi/problemset/task/1132 44 | -------------------------------------------------------------------------------- /Graph Theory/Tree and Graph Counting.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShahjalalShohag/code-library/13841f310f311b69bf5d68bb611251cb027d14f1/Graph Theory/Tree and Graph Counting.docx -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Math/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /Math/Basis Vector.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | template 5 | struct Basis { 6 | T a[B]; 7 | Basis() { 8 | memset(a, 0, sizeof a); 9 | } 10 | void insert(T x){ 11 | for (int i = B - 1; i >= 0; i--) { 12 | if (x >> i & 1) { 13 | if (a[i]) x ^= a[i]; 14 | else { 15 | a[i] = x; 16 | break; 17 | } 18 | } 19 | } 20 | } 21 | bool can(T x) { 22 | for(int i = B - 1; i >= 0; i--) { 23 | x = min(x, x ^ a[i]); 24 | } 25 | return x == 0; 26 | } 27 | T max_xor(T ans = 0) { 28 | for(int i = B - 1; i >= 0; i--) { 29 | ans = max(ans, ans ^ a[i]); 30 | } 31 | return ans; 32 | } 33 | }; 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 n; cin >> n; 41 | Basis B; 42 | for (int i = 1; i <= n; i++) { 43 | long long x; cin >> x; 44 | B.insert(x); 45 | } 46 | cout << "Case " << ++cs << ": " << B.max_xor() << '\n'; 47 | } 48 | return 0; 49 | } 50 | // https://lightoj.com/problem/maximum-subset-sum 51 | -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Math/Generating Functions and Polynomials.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShahjalalShohag/code-library/13841f310f311b69bf5d68bb611251cb027d14f1/Math/Generating Functions and Polynomials.docx -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /Math/Inverse of A Matrix modulo 2.cpp: -------------------------------------------------------------------------------- 1 | #include 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 | -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Miscellaneous/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /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/Inversions.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 | 9 | int32_t main() { 10 | ios_base::sync_with_stdio(0); 11 | cin.tie(0); 12 | int t; cin >> t; 13 | while (t--) { 14 | int n; cin >> n; 15 | int a[n + 1]; 16 | for (int i = 1; i <= n; i++) { 17 | cin >> a[i]; 18 | } 19 | o_set se; 20 | long long ans = 0; 21 | for (int i = n; i >= 1; i--) { 22 | ans += se.order_of_key(a[i]); 23 | se.insert(a[i]); 24 | } 25 | cout << ans << '\n'; 26 | } 27 | return 0; 28 | } 29 | // https://vjudge.net/problem/SPOJ-INVCNT 30 | -------------------------------------------------------------------------------- /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 | // O(k log n) 5 | ll josephus(ll n, ll k, ll m) { 6 | m = n - m; 7 | if (k <= 1)return n - m; 8 | ll i = m; 9 | while (i < n) { 10 | ll r = (i - m + k - 2) / (k - 1); 11 | if ((i + r) > n) r = n - i; 12 | else if (!r) r = 1; 13 | i += r; 14 | m = (m + (r * k)) % i; 15 | } return m + 1; 16 | } 17 | -------------------------------------------------------------------------------- /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/Logarithmic Subarray Aggregator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1e5 + 9; 5 | int a[N]; 6 | int32_t main() { 7 | ios_base::sync_with_stdio(0); 8 | cin.tie(0); 9 | int n; cin >> n; 10 | for (int i = 1; i <= n; i++) { 11 | cin >> a[i]; 12 | } 13 | 14 | vector> v; // stores the number of times a subarray gcd occurs ending at each index 15 | map ans; 16 | for (int i = 1; i <= n; i++) { 17 | vector> u; 18 | u.push_back({a[i], 1}); 19 | for (auto [x, c]: v) { 20 | int g = __gcd(x, a[i]); 21 | if (g == u.back().first) { 22 | u.back().second += c; 23 | } else { 24 | u.push_back({g, c}); 25 | } 26 | } 27 | v = u; 28 | for (auto [x, c]: v) { 29 | ans[x] += c; 30 | } 31 | } 32 | 33 | int q; cin >> q; 34 | while (q--) { 35 | int x; cin >> x; 36 | cout << ans[x] << '\n'; 37 | } 38 | return 0; 39 | } 40 | // https://codeforces.com/contest/475/problem/D 41 | -------------------------------------------------------------------------------- /Miscellaneous/Min Plus Convolution (Convex and Convex).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) = min(a(i) + b(j)) 7 | vector min_plus_convolution(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 | int n, m; cin >> n >> m; 30 | vector a(n); 31 | for (int i = 0; i < n; i++) { 32 | cin >> a[i]; 33 | } 34 | vector b(m); 35 | for (int i = 0; i < m; i++) { 36 | cin >> b[i]; 37 | } 38 | auto ans = min_plus_convolution(a, b); 39 | for (int i = 0; i < ans.size(); i++) { 40 | cout << ans[i] << ' '; 41 | } 42 | return 0; 43 | } 44 | // https://judge.yosupo.jp/problem/min_plus_convolution_convex_convex 45 | -------------------------------------------------------------------------------- /Miscellaneous/Permutation Cycles.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9; 5 | 6 | // 0-indexed, values are also from 0 to n-1 7 | 8 | // decompose into cycles 9 | vector> decompose(vector &p) { 10 | int n = p.size(); 11 | vector> cycles; 12 | vector vis(n, 0); 13 | for (int i = 0; i < n; i++) { 14 | if (!vis[i]) { 15 | vector v; 16 | while (!vis[i]) { 17 | v.push_back(i); 18 | vis[i] = 1; 19 | i = p[i]; 20 | } 21 | cycles.push_back(v); 22 | } 23 | } 24 | return cycles; 25 | } 26 | 27 | // restore the permutation from the cycles 28 | vector restore(int n, vector> &cycles) { 29 | vector p(n); 30 | for (auto v : cycles) { 31 | int m = v.size(); 32 | for (int i = 0; i < m; i++) p[v[i]] = v[(i + 1) % m]; 33 | } 34 | return p; 35 | } 36 | 37 | //cycle decomposition of the k-th power of p 38 | vector> power(vector &p, int k) { 39 | int n = p.size(); 40 | auto cycles = decompose(p); 41 | vector> ans; 42 | for (auto v : cycles) { 43 | int len = v.size(), g = __gcd(k, len); // g cycles of len / g length 44 | for (int i = 0; i < g; i++) { 45 | vector w; 46 | for (int j = i, cnt = 0; cnt < len / g; cnt++, j = (j + k) % len) { 47 | w.push_back(v[j]); 48 | } 49 | ans.push_back(w); 50 | } 51 | } 52 | return ans; 53 | } 54 | 55 | int32_t main() { 56 | ios_base::sync_with_stdio(0); 57 | cin.tie(0); 58 | int n; cin >> n; 59 | vector p(n); 60 | for (int i = 0; i < n; i++) { 61 | cin >> p[i]; --p[i]; 62 | } 63 | auto cycles = decompose(p); 64 | int ans = 1; 65 | for (auto v: cycles) { 66 | int sz = v.size(); 67 | ans = 1LL * ans * sz / __gcd(ans, sz); 68 | } 69 | cout << ans << '\n'; 70 | return 0; 71 | } 72 | // https://acm.timus.ru/problem.aspx?space=1&num=1024 73 | -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /Miscellaneous/Trygub Num.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | struct trygub_num { 5 | // maintains a big number in the given base b 6 | const int K = 30; 7 | const int b = 2; 8 | const int base = 1 << K; // for base b use b^K base to make the computation faster 9 | map digs; // tracks digits in (-base, base) 10 | void clear() { 11 | digs.clear(); 12 | } 13 | // add x * b^e to this number: x, e both can be negative 14 | // O(log_b(n)^2 / K) amortized 15 | void add(long long x, int e) { 16 | if (e >= 0) { 17 | x = x * (1 << (e % K)); // x * b ^ (e % K) 18 | e /= K; 19 | } 20 | else { 21 | int k = (e % K + K) % K; 22 | x = x * (1 << k); 23 | e = e / K - (e % K != 0); 24 | } 25 | digs[e] += x; 26 | long long t; 27 | do { 28 | t = digs[e] / base; 29 | digs[e + 1] += t; 30 | digs[e] -= t * base; 31 | if (digs[e] == 0) { 32 | digs.erase(e); 33 | } 34 | e++; 35 | } while(t); 36 | 37 | if(digs[e] == 0) { 38 | digs.erase(e); 39 | } 40 | } 41 | 42 | // assuming this number is >= 0, find the kth digit in the base b 43 | int kth_digit(int k) { 44 | int cur_k = k / K; 45 | auto it = digs.lower_bound(cur_k); 46 | int ans = it == digs.end() || it->first > cur_k ? 0 : it->second; 47 | if(it != digs.begin() && prev(it)->second < 0) { 48 | ans--; 49 | } 50 | ans = (ans + base) % base; 51 | return (ans >> (k % K)) & 1; // (k % K) th digit of ans in base b 52 | } 53 | 54 | int sign() { // if the number is >= 0 55 | if (digs.empty()) return 1; // number = 0 56 | auto it = prev(digs.end()); 57 | return it -> second > 0; 58 | } 59 | 60 | } big_num; 61 | int32_t main() { 62 | ios_base::sync_with_stdio(0); 63 | cin.tie(0); 64 | int q, t; cin >> q >> t >> t >> t; 65 | while (q--) { 66 | int ty; cin >> ty; 67 | if (ty == 1) { 68 | int x, e; cin >> x >> e; 69 | big_num.add(x, e); 70 | } 71 | else { 72 | int k; cin >> k; 73 | cout << big_num.kth_digit(k) << '\n'; 74 | } 75 | } 76 | return 0; 77 | } 78 | // https://codeforces.com/blog/entry/115626 79 | // https://loj.ac/p/2302 80 | -------------------------------------------------------------------------------- /Number Theory/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /Number Theory/Derangement.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1e6 + 9, mod = 1e9 + 7; 5 | 6 | int d[N]; 7 | int32_t main() { 8 | ios_base::sync_with_stdio(0); 9 | cin.tie(0); 10 | d[0] = 1; d[1] = 0; 11 | for (int i = 1; i < N; i++) { 12 | d[i] = 1LL * (i - 1) * (d[i - 1] + d[i - 2]) % mod; 13 | } 14 | int n; cin >> n; 15 | cout << d[n] << '\n'; 16 | return 0; 17 | } 18 | // https://cses.fi/problemset/task/1717 19 | -------------------------------------------------------------------------------- /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/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/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 | } -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /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/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 = a < st ? a + ((st - a + d - 1) / d) : a; // while (a < st) a += d; 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 | } 46 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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) * b; 30 | for (int k = 0; k < g; ++k) { // exactly g solutions 31 | ret.push_back((x + m / g * k) % m); 32 | } 33 | // minimum solution = (m / g - (m - x) % (m / g)) % (m / g) 34 | return ret; 35 | } 36 | int32_t main() { 37 | ios_base::sync_with_stdio(0); 38 | cin.tie(0); 39 | auto ret = congruence_equation(4, 0, 12); 40 | for (auto x: ret) { 41 | cout << x << ' '; 42 | } 43 | return 0; 44 | } 45 | // https://cp-algorithms.com/algebra/linear_congruence_equation.html 46 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /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/Miller Rabin.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | using ll = long long; 5 | namespace MillerRabin { 6 | mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count()); 7 | const int P = 1e6 + 9; 8 | int primes[P], spf[P]; 9 | inline ll mul_mod(ll x, ll y, ll m) { 10 | ll res = __int128(x) * y % m; 11 | return res; 12 | // ll res = x * y - (ll)((long double)x * y / m + 0.5) * m; 13 | // return res < 0 ? res + m : res; 14 | } 15 | inline ll pow_mod(ll x, ll n, ll m) { 16 | ll res = 1 % m; 17 | for (; n; n >>= 1) { 18 | if (n & 1) res = mul_mod(res, x, m); 19 | x = mul_mod(x, x, m); 20 | } 21 | return res; 22 | } 23 | // O(it * (logn)^3), it = number of rounds performed (but faster in practice) 24 | inline bool miller_rabin(ll n) { 25 | if (n <= 2 || (n & 1 ^ 1)) return (n == 2); 26 | if (n < P) return spf[n] == n; 27 | ll c, d, s = 0, r = n - 1; 28 | for (; !(r & 1); r >>= 1, s++) {} 29 | // each iteration is a round 30 | for (int i = 0; primes[i] < n && primes[i] < 32; i++) { 31 | c = pow_mod(primes[i], r, n); 32 | for (int j = 0; j < s; j++) { 33 | d = mul_mod(c, c, n); 34 | if (d == 1 && c != 1 && c != (n - 1)) return false; 35 | c = d; 36 | } 37 | if (c != 1) return false; 38 | } 39 | return true; 40 | } 41 | void init() { 42 | int cnt = 0; 43 | for (int i = 2; i < P; i++) { 44 | if (!spf[i]) primes[cnt++] = spf[i] = i; 45 | for (int j = 0, k; (k = i * primes[j]) < P; j++) { 46 | spf[k] = primes[j]; 47 | if (spf[i] == spf[k]) break; 48 | } 49 | } 50 | } 51 | } 52 | int32_t main() { 53 | ios_base::sync_with_stdio(0); 54 | cin.tie(0); 55 | MillerRabin::init(); 56 | int t; cin >> t; 57 | while (t--) { 58 | ll n; cin >> n; 59 | if (MillerRabin::miller_rabin(n)) { 60 | cout << "Yes\n"; 61 | } else { 62 | cout << "No\n"; 63 | } 64 | } 65 | return 0; 66 | } 67 | // https://judge.yosupo.jp/problem/primality_test 68 | -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /Number Theory/Number of Nonnegative Integer Solutions to ax+by less than or equal to 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 | -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /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/ -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Number Theory/Pythagorean Triplets.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1e6 + 9; 5 | 6 | vector> ans[N]; //ans[c] = {{a, b}}, s.t. a^2 + b^2 = c^2 7 | int32_t main() { 8 | vector> v; 9 | int cnt = 0, p = 0; 10 | for (int m = 1; m * m < N; m++) { 11 | for (int n = 1; n < m; n++) { 12 | if ((n & 1) == (m & 1)) continue; 13 | int a = m * m - n * n, b = 2 * m * n, c = m * m + n * n; 14 | if (__gcd(a, b) > 1) continue; 15 | for (int k = 1; k * c < N && k <= 1 ; k++) { 16 | ans[c * k].emplace_back(a * k, b * k); 17 | cnt++; 18 | } 19 | } 20 | } 21 | int sz = 0; 22 | // for (int i = 1; i < N; i++) sz = max(sz, (int)ans[i].size()); 23 | // cout << cnt << ' ' << sz << '\n'; 24 | for (int i = 1; i <= 1000; i++) { 25 | for (auto x : ans[i]) cout << x.first << ' ' << x.second << ' ' << i << '\n'; 26 | } 27 | return 0; 28 | } 29 | // https://en.wikipedia.org/wiki/Pythagorean_triple#Generating_a_triple 30 | -------------------------------------------------------------------------------- /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?lang=en 44 | -------------------------------------------------------------------------------- /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) -------------------------------------------------------------------------------- /Number Theory/Sieve Linear.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 | sieve(); 22 | cout << primes.back() << '\n'; 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /Number Theory/Sieve.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1e6 + 9; 5 | 6 | vector primes; 7 | bool is_prime[N]; 8 | // use bitset is_prime; to have O(N/64) memory complexity 9 | // using bitset you can solve upto around N = 10^8 in 1s 10 | void sieve_v0() { 11 | for (int i = 2; i < N; i++) { 12 | is_prime[i] = true; 13 | } 14 | for (int i = 2; i * i < N; i++) { 15 | if (is_prime[i]) { 16 | for (int j = i * i; j < N; j += i) { 17 | is_prime[j] = false; 18 | } 19 | } 20 | } 21 | for (int i = 2; i < N; i++) { 22 | if (is_prime[i]) { 23 | primes.push_back(i); 24 | } 25 | } 26 | } 27 | 28 | // sieve with smallest prime factors (spf) 29 | int spf[N]; 30 | void sieve() { 31 | for (int i = 2; i < N; i++) { 32 | spf[i] = i; 33 | } 34 | for (int i = 2; i * i < N; i++) { 35 | if (spf[i] == i) { 36 | for (int j = i * i; j < N; j += i) { 37 | spf[j] = min(spf[j], i); 38 | } 39 | } 40 | } 41 | for (int i = 2; i < N; i++) { 42 | if (spf[i] == i) { 43 | primes.push_back(i); 44 | } 45 | } 46 | } 47 | 48 | int32_t main() { 49 | ios_base::sync_with_stdio(0); 50 | cin.tie(0); 51 | sieve_v0(); 52 | cout << primes.size() << '\n'; 53 | primes.clear(); 54 | sieve(); 55 | cout << primes.size() << '\n'; 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /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/ -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /Strings/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Strings/Manachers.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | struct Manacher { 5 | vector p[2]; 6 | // p[1][i] = (max odd length palindrome centered at i) / 2 [floor division] 7 | // p[0][i] = same for even, it considers the right center 8 | // e.g. for s = "abbabba", p[1][3] = 3, p[0][2] = 2 9 | Manacher(string s) { 10 | int n = s.size(); 11 | p[0].resize(n + 1); 12 | p[1].resize(n); 13 | for (int z = 0; z < 2; z++) { 14 | for (int i = 0, l = 0, r = 0; i < n; i++) { 15 | int t = r - i + !z; 16 | if (i < r) p[z][i] = min(t, p[z][l + t]); 17 | int L = i - p[z][i], R = i + p[z][i] - !z; 18 | while (L >= 1 && R + 1 < n && s[L - 1] == s[R + 1]) 19 | p[z][i]++, L--, R++; 20 | if (R > r) l = L, r = R; 21 | } 22 | } 23 | } 24 | bool is_palindrome(int l, int r) { 25 | int mid = (l + r + 1) / 2, len = r - l + 1; 26 | return 2 * p[len % 2][mid] + len % 2 >= len; 27 | } 28 | }; 29 | 30 | int32_t main() { 31 | ios_base::sync_with_stdio(0); 32 | cin.tie(0); 33 | string s; cin >> s; 34 | Manacher M(s); 35 | int n = s.size(); 36 | for (int i = 0; i < n; i++) { 37 | cout << 2 * M.p[1][i] + 1 << ' '; 38 | if (i + 1 < n) cout << 2 * M.p[0][i + 1] << ' '; 39 | } 40 | cout << '\n'; 41 | return 0; 42 | } 43 | // https://judge.yosupo.jp/problem/enumerate_palindromes 44 | -------------------------------------------------------------------------------- /Strings/Palindromic Tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 3e5 + 9; 5 | 6 | /* 7 | -> cnt contains the number of palindromic suffixes of the node 8 | */ 9 | struct PalindromicTree { 10 | struct node { 11 | int nxt[26], len, st, en, link, cnt, oc; 12 | }; 13 | string s; 14 | vector t; 15 | int sz, last; 16 | PalindromicTree() {} 17 | PalindromicTree(string _s) { 18 | s = _s; 19 | int n = s.size(); 20 | t.clear(); 21 | t.resize(n + 9); 22 | sz = 2, last = 2; 23 | t[1].len = -1, t[1].link = 1; 24 | t[2].len = 0, t[2].link = 1; 25 | } 26 | int extend(int pos) { // returns 1 if it creates a new palindrome 27 | int cur = last, curlen = 0; 28 | int ch = s[pos] - 'a'; 29 | while (1) { 30 | curlen = t[cur].len; 31 | if (pos - 1 - curlen >= 0 && s[pos - 1 - curlen] == s[pos]) break; 32 | cur = t[cur].link; 33 | } 34 | if (t[cur].nxt[ch]) { 35 | last = t[cur].nxt[ch]; 36 | t[last].oc++; 37 | return 0; 38 | } 39 | sz++; 40 | last = sz; 41 | t[sz].oc = 1; 42 | t[sz].len = t[cur].len + 2; 43 | t[cur].nxt[ch] = sz; 44 | t[sz].en = pos; 45 | t[sz].st = pos - t[sz].len + 1; 46 | if (t[sz].len == 1) { 47 | t[sz].link = 2; 48 | t[sz].cnt = 1; 49 | return 1; 50 | } 51 | while (1) { 52 | cur = t[cur].link; 53 | curlen = t[cur].len; 54 | if (pos - 1 - curlen >= 0 && s[pos - 1 - curlen] == s[pos]) { 55 | t[sz].link = t[cur].nxt[ch]; 56 | break; 57 | } 58 | } 59 | t[sz].cnt = 1 + t[t[sz].link].cnt; 60 | return 1; 61 | } 62 | void calc_occurrences() { 63 | for (int i = sz; i >= 3; i--) t[t[i].link].oc += t[i].oc; 64 | } 65 | } t; 66 | 67 | int32_t main() { 68 | ios_base::sync_with_stdio(0); 69 | cin.tie(0); 70 | string s; 71 | cin >> s; 72 | PalindromicTree t(s); 73 | for (int i = 0; i < s.size(); i++) t.extend(i); 74 | t.calc_occurrences(); 75 | long long ans = 0; // number of palindromes 76 | for (int i = 3; i <= t.sz; i++) ans += t.t[i].oc; 77 | cout << ans << '\n'; 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /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 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 | -------------------------------------------------------------------------------- /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 | --------------------------------------------------------------------------------