├── Data Structure ├── Matrix and Matrix Power.cpp ├── Mo Algorithm.cpp ├── Mo Complexity Improve.cpp ├── Ordered Set.cpp ├── Persistent segment tree.cpp └── heavy light decomposition.cpp ├── Dynamic Programming ├── Convex Trick.cpp ├── D&Q Optimization.cpp └── Knuth Optimization.cpp ├── Geometry ├── 3D Rotation.cpp ├── Angle Bisector.cpp ├── Circle Circle Intersection.cpp ├── Circle Line Intersection.cpp ├── Circle from Three Points.cpp ├── Closest Pair of Points.cpp ├── Closest Point on Line.cpp ├── Convexhull.cpp ├── Delaunay Triangulation.cpp ├── Latitude and Longitude.cpp ├── Line Intersection.cpp ├── Point in Polygon.cpp ├── Polygon Centroid.cpp ├── Rotation Around Origin by t.cpp ├── Segment Circle Distance.cpp ├── Two Point and Radius Circle.cpp └── geometry algorithms.cpp ├── Graph ├── Bipartite Matching and Vertex Cover.cpp ├── Count Triangles.cpp ├── DFS on Complement Graph.cpp ├── DSU on Tree.cpp ├── Euler Tour.cpp ├── Flow With Demands.tex ├── Min Cost Bipartite Matching.cpp ├── Weighted Min Cut.cpp ├── assignment Problem.cpp ├── bipartie mcmf.cpp ├── flow.cpp └── hungarian.cpp ├── Math ├── Binary Gaussian Elimination.cpp ├── Discrete Logarithm Solver.cpp ├── Euler Totient Function.cpp ├── Extended GCD.cpp ├── Fibonacci Numbers Properties.tex ├── Linear Diophantine Equation Solver.cpp ├── Maximum XOR (SGU 275).cpp ├── Modular Linear Equation Solver.cpp ├── Number of Divisors.cpp ├── Prime Factors in n Factorial.cpp ├── Reduced Row Echelon Form.cpp └── Solving Recursive Functions.cpp ├── Other ├── FFT and Multiplication.cpp ├── Grundy.cpp ├── Miller-Rabin primality test.cpp └── faster FFT.cpp ├── README.md ├── String ├── Aho-Corasick.cpp ├── Kmp.cpp ├── Manacher Longest Palindrome.cpp ├── Non Cyclic Suffix Array.cpp ├── Suffix-Array.cpp ├── SuffixTree.cpp ├── Z Algorithm.cpp ├── hash.cpp └── rope.cpp ├── Tips, Tricks and Theorems ├── Bitset.cpp ├── Burnside's lemma.tex ├── C++ Tricks.cpp ├── Contest Tips.cpp ├── Dilworth Theorem.cpp ├── Gallai Theorem.cpp ├── Konig Theorem.cpp ├── Lucas Theorem.tex ├── Minimum Path Cover in DAG.tex ├── Planar Graph (Euler).tex ├── Triangles.tex └── Uniform Random Number Generator.cpp └── notebook.pdf /Data Structure/Matrix and Matrix Power.cpp: -------------------------------------------------------------------------------- 1 | const int MN = 111; 2 | const int mod = 10000; 3 | 4 | struct matrix { 5 | int r, c; 6 | int m[MN][MN]; 7 | 8 | matrix (int _r, int _c) : r (_r), c (_c) { 9 | memset(m, 0, sizeof m); 10 | } 11 | 12 | void print() { 13 | for (int i = 0; i < r; ++i) { 14 | for (int j = 0; j < c; ++j) 15 | cout << m[i][j] << " "; 16 | cout << endl; 17 | } 18 | } 19 | 20 | int x[MN][MN]; 21 | matrix & operator *= (const matrix &o) { 22 | memset(x, 0, sizeof x); 23 | for (int i = 0; i < r; ++i) 24 | for (int k = 0; k < c; ++k) 25 | if (m[i][k] != 0) 26 | for (int j = 0; j < c; ++j) { 27 | x[i][j] = (x[i][j] + ((m[i][k] * o.m[k][j]) % mod) ) % mod; 28 | } 29 | memcpy(m, x, sizeof(m)); 30 | return *this; 31 | } 32 | }; 33 | 34 | void matrix_pow(matrix b, long long e, matrix &res) { 35 | memset(res.m, 0, sizeof res.m); 36 | for (int i = 0; i < b.r; ++i) 37 | res.m[i][i] = 1; 38 | 39 | if (e == 0) return; 40 | while (true) { 41 | if (e & 1) res *= b; 42 | if ((e >>= 1) == 0) break; 43 | b *= b; 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /Data Structure/Mo Algorithm.cpp: -------------------------------------------------------------------------------- 1 | void remove(idx); // TODO: remove value at idx from data structure 2 | void add(idx); // TODO: add value at idx from data structure 3 | int get_answer(); // TODO: extract the current answer of the data structure 4 | 5 | int block_size; 6 | 7 | struct Query { 8 | int l, r, idx; 9 | bool operator<(Query other) const 10 | { 11 | return make_pair(l / block_size, r) < 12 | make_pair(other.l / block_size, other.r); 13 | } 14 | }; 15 | 16 | vector mo_s_algorithm(vector queries) { 17 | vector answers(queries.size()); 18 | sort(queries.begin(), queries.end()); 19 | 20 | // TODO: initialize data structure 21 | 22 | int cur_l = 0; 23 | int cur_r = -1; 24 | // invariant: data structure will always reflect the range [cur_l, cur_r] 25 | for (Query q : queries) { 26 | while (cur_l > q.l) { 27 | cur_l--; 28 | add(cur_l); 29 | } 30 | while (cur_r < q.r) { 31 | cur_r++; 32 | add(cur_r); 33 | } 34 | while (cur_l < q.l) { 35 | remove(cur_l); 36 | cur_l++; 37 | } 38 | while (cur_r > q.r) { 39 | remove(cur_r); 40 | cur_r--; 41 | } 42 | answers[q.idx] = get_answer(); 43 | } 44 | return answers; 45 | } -------------------------------------------------------------------------------- /Data Structure/Mo Complexity Improve.cpp: -------------------------------------------------------------------------------- 1 | // Complexity 2 | // Sorting all queries will take O(QlogQ). 3 | 4 | // How about the other operations? How many times will the add and remove be called? 5 | 6 | // Let's say the block size is S. 7 | 8 | // If we only look at all queries having the left index in the same block, 9 | // the queries are sorted by the right index. 10 | // Therefore we will call add(cur_r) and remove(cur_r) only O(N) times for all these queries combined. 11 | // This gives O((N/S)*N) calls for all blocks. 12 | 13 | // The value of cur_l can change by at most O(S) during between two queries. 14 | // Therefore we have an additional O(SQ) calls of add(cur_l) and remove(cur_l). 15 | 16 | // For S≈√N this gives O((N+Q)√N) operations in total. 17 | // Thus the complexity is O((N+Q)F√N) where O(F) is the complexity of add and remove function. 18 | 19 | // Tips for improving runtime 20 | // Block size of precisely √N doesn't always offer the best runtime. 21 | // For example, if √N=750 then it may happen that block size of 700 or 800 may run better. 22 | // More importantly, don't compute the block size at runtime - make it const. 23 | // Division by constants is well optimized by compilers. 24 | // In odd blocks sort the right index in ascending order and in even blocks sort it in descending order. 25 | // This will minimize the movement of right pointer, 26 | // as the normal sorting will move the right pointer from the end back to the beginning at the start of every block. 27 | // With the improved version this resetting is no more necessary. 28 | 29 | bool cmp(pair p, pair q) { 30 | if (p.first / BLOCK_SIZE != q.first / BLOCK_SIZE) 31 | return p < q; 32 | return (p.first / BLOCK_SIZE & 1) ? (p.second < q.second) : (p.second > q.second); 33 | } -------------------------------------------------------------------------------- /Data Structure/Ordered Set.cpp: -------------------------------------------------------------------------------- 1 | // C++ program to demonstrate the 2 | // ordered set in GNU C++ 3 | #include 4 | using namespace std; 5 | // Header files, namespaces, 6 | // macros as defined above 7 | #include 8 | #include 9 | using namespace __gnu_pbds; 10 | #define ordered_set tree, rb_tree_tag,tree_order_statistics_node_update> 11 | int main(){ 12 | ordered_set o_set; 13 | // insert function to insert in 14 | // ordered set same as SET STL 15 | o_set.insert(5); 16 | o_set.insert(1); 17 | o_set.insert(2); 18 | 19 | // Finding the second smallest element 20 | // in the set using * because 21 | // find_by_order returns an iterator 22 | cout << *(o_set.find_by_order(1)) << endl; 23 | 24 | // Finding the number of elements 25 | // strictly less than k=4 26 | cout << o_set.order_of_key(4) << endl; 27 | 28 | // Finding the count of elements less 29 | // than or equal to 4 i.e. strictly less 30 | // than 5 if integers are present 31 | cout << o_set.order_of_key(5) << endl; 32 | 33 | // Deleting 2 from the set if it exists 34 | if (o_set.find(2) != o_set.end()) 35 | o_set.erase(o_set.find(2)); 36 | 37 | // Now after deleting 2 from the set 38 | // Finding the second smallest element in the set 39 | cout << *(o_set.find_by_order(1)) << endl; 40 | 41 | // Finding the number of 42 | // elements strictly less than k=4 43 | cout << o_set.order_of_key(4) << endl; 44 | } 45 | -------------------------------------------------------------------------------- /Data Structure/Persistent segment tree.cpp: -------------------------------------------------------------------------------- 1 | int n, cnt=0; 2 | ll sum[M], le[M], ri[M], root[M]; 3 | void build(int id, int b, int e){ 4 | sum[id]=0; 5 | if(e-b==1) 6 | return; 7 | int m=(b+e)/2; 8 | le[id]= ++cnt; 9 | build(le[id], b,m); 10 | ri[id]= ++cnt; 11 | build(le[id], m,e); 12 | } 13 | 14 | int g(int id, int b, int e, int l, int r){ 15 | if(l<=b && e<=r) return sum[id]; 16 | if(e<=l || r<=b) return 0; 17 | int m= (b+e)/2; 18 | return g(le[id], b,m, l,r) + g(ri[id], m,e ,l,r); 19 | } 20 | 21 | int upd(int id, int b, int e, int x, int y){ 22 | if(e-b==1){ 23 | sum[++cnt]= y; 24 | return cnt; 25 | } 26 | int m=(b+e)/2, tmp= ++cnt; 27 | le[tmp]= le[id],ri[tmp]= ri[id]; 28 | if(x sz[g[v][0]]) { 7 | swap(u, g[v][0]); 8 | } 9 | } 10 | } 11 | 12 | void dfs_hld(int v = 0) { 13 | in[v] = t++; 14 | for(auto u: g[v]) { 15 | nxt[u] = (u == g[v][0] ? nxt[v] : u); 16 | dfs_hld(u); 17 | } 18 | out[v] = t; 19 | } 20 | 21 | /* 22 | Then you will have such array that subtree of V correspond to segment [in(v), out(v)) 23 | and the path from V to the last vertex in ascending heavy path from V(which is nxt(v)) 24 | will be [in(nxt(v)), in(v)] subsegment 25 | which gives you the opportunity to process queries on paths 26 | and subtrees simultaneously in the same segment tree. 27 | */ -------------------------------------------------------------------------------- /Dynamic Programming/Convex Trick.cpp: -------------------------------------------------------------------------------- 1 | 2 | struct Line { 3 | ll k, b; 4 | 5 | Line() { 6 | k = b = 0ll; 7 | } 8 | 9 | Line(ll k, ll b) : k(k), b(b) {} 10 | 11 | ll get(ll x) { 12 | return k * x + b; 13 | } 14 | }; 15 | 16 | ld interLine(Line a, Line b) { 17 | return (ld)(a.b - b.b) / (ld)(b.k - a.k); 18 | } 19 | 20 | struct CHT { 21 | vector V; 22 | 23 | CHT() { 24 | V.clear(); 25 | } 26 | 27 | void addLine(Line l) { 28 | while (V.size() >= 2 && interLine(V[V.size() - 2], l) < interLine(V[V.size() - 2], V.back())) { 29 | V.pop_back(); 30 | } 31 | 32 | V.push_back(l); 33 | } 34 | 35 | ll get(ll x) { 36 | int l = 0, r = (int)V.size() - 2, idx = (int)V.size() - 1; 37 | 38 | while (l <= r) { 39 | int mid = (l + r) >> 1; 40 | 41 | if (interLine(V[mid], V[mid + 1]) <= x) { 42 | l = mid + 1; 43 | } 44 | else { 45 | r = mid - 1; 46 | idx = mid; 47 | } 48 | } 49 | 50 | return V[idx].get(x); 51 | } 52 | }; 53 | 54 | struct Hull_Static{ 55 | /** 56 | all m need to be decreasing order 57 | if m is in increasing order then negate the m ( like , add_line(-m,c) ), 58 | remember in query you have to negate the x also 59 | **/ 60 | 61 | const ll inf = 1000000000000000000; 62 | int min_or_max; ///if min then 0 otherwise 1 63 | int pointer; /// keep track for the best line for previous query, requires all insert first; 64 | vector < ll > M, C; ///y = m * x + c; 65 | 66 | inline void clear(){ 67 | min_or_max = 0; ///initially with minimum trick 68 | pointer = 0; 69 | M.clear(); 70 | C.clear(); 71 | } 72 | 73 | Hull_Static(){ 74 | clear(); 75 | } 76 | Hull_Static(int _min_or_max){ 77 | clear(); 78 | this->min_or_max = _min_or_max; 79 | } 80 | bool bad_min(int idx1, int idx2, int idx3){ 81 | //return (C[idx3] - C[idx1]) * (M[idx1] - M[idx2]) < (C[idx2] - C[idx1]) * (M[idx1] - M[idx3]); 82 | return 1.0 * (C[idx3] - C[idx1]) * (M[idx1] - M[idx2]) <= 1.0 *(C[idx2] - C[idx1]) * (M[idx1] - M[idx3]); /// for overflow 83 | } 84 | 85 | bool bad_max(int idx1, int idx2, int idx3){ 86 | //return (C[idx3] - C[idx1]) * (M[idx1] - M[idx2]) > (C[idx2] - C[idx1]) * (M[idx1] - M[idx3]); 87 | return 1.0 * (C[idx3] - C[idx1]) * (M[idx1] - M[idx2]) >= 1.0 *(C[idx2] - C[idx1]) * (M[idx1] - M[idx3]); /// for overflow 88 | } 89 | 90 | bool bad(int idx1, int idx2, int idx3){ /// for removing line, which isn't necessary 91 | if(!min_or_max) return bad_min(idx1, idx2, idx3); 92 | else return bad_max(idx1, idx2, idx3); 93 | } 94 | 95 | void add_line(ll m, ll c){ /// add line where m is given in decreasing order 96 | //if(M.size() > 0 and M.back() == m) return; /// same gradient, no need to add 97 | M.push_back(m); 98 | C.push_back(c); 99 | 100 | while(M.size() >= 3 and bad((int)M.size() - 3, (int)M.size() - 2, (int)M.size() - 1)){ 101 | M.erase(M.end() - 2); 102 | C.erase(C.end() - 2); 103 | } 104 | } 105 | ll getval(ll idx, ll x){ /// get the y coordinate of a specific line 106 | return M[idx] * x + C[idx]; 107 | } 108 | 109 | ll getminval(ll x){ /// if queries are sorted, make sure all insertion first. 110 | while(pointer < (int)M.size() - 1 and getval(pointer + 1, x) < getval(pointer, x)) pointer++; 111 | return M[pointer] * x + C[pointer]; 112 | } 113 | ll getmaxval(ll x){ /// if queries are sorted, make sure all insertion first. 114 | while(pointer < (int)M.size() - 1 and getval(pointer + 1, x) > getval(pointer, x)) pointer++; 115 | return M[pointer] * x + C[pointer]; 116 | } 117 | ll getminvalternary(ll x){ /// minimum value with ternary search 118 | ll lo = 0; 119 | ll hi = (ll)M.size() - 1; 120 | ll ans = inf; 121 | while(lo <= hi){ 122 | ll mid1 = lo + (hi - lo) / 3; 123 | ll mid2 = hi - (hi - lo) / 3; 124 | ll val1 = getval(mid1, x); 125 | ll val2 = getval(mid2, x); 126 | if(val1 < val2){ 127 | ans = min(ans, val2); 128 | hi = mid2 - 1; 129 | } 130 | else{ 131 | ans = min(ans, val1); 132 | lo = mid1 + 1; 133 | } 134 | } 135 | return ans; 136 | } 137 | 138 | ll getmaxvalternary(ll x){ /// maximum value with ternary search 139 | // cout< r) return; 9 | int mid = (l + r) / 2, idx = optl; 10 | dp[mid][k] = cost(optl, mid, k); 11 | for (int i = optl + 1; i <= min(mid, optr); i++) 12 | if(dp[mid][k] > cost(i, mid, k)) 13 | dp[mid][k] = cost(i, mid, k), idx = i; 14 | solve(l, mid - 1, k, optl, idx); 15 | solve(mid + 1, r, k, idx, optr); 16 | } 17 | int main() { 18 | cin >> n >> k; 19 | for (int i = 0; i < n; i++) { 20 | cin >> x; 21 | sum[i + 1] = sum[i] + x, rev[i + 1] = rev[i] + (1.0 / x), prefix[i + 1] = prefix[i] + (sum[i + 1] / x), dp[i + 1][0] = inf; 22 | } 23 | for (int i = 1; i <= k; i++) 24 | solve(i, n, i, i, n); 25 | cout << setprecision(6) << dp[n][k] << "\n"; 26 | } -------------------------------------------------------------------------------- /Dynamic Programming/Knuth Optimization.cpp: -------------------------------------------------------------------------------- 1 | for (int s = 0; s<=k; s++) //s - length(size) of substring 2 | for (int L = 0; L+s<=k; L++) { //L - left point 3 | int R = L + s; //R - right point 4 | if (s < 2) { 5 | res[L][R] = 0; //DP base - nothing to break 6 | mid[L][R] = l; //mid is equal to left border 7 | continue; 8 | } 9 | int mleft = mid[L][R-1]; //Knuth's trick: getting bounds on M 10 | int mright = mid[L+1][R]; 11 | res[L][R] = 1000000000000000000LL; 12 | for (int M = mleft; M<=mright; M++) { //iterating for M in the bounds only 13 | int64 tres = res[L][M] + res[M][R] + (x[R]-x[L]); 14 | if (res[L][R] > tres) { //relax current solution 15 | res[L][R] = tres; 16 | mid[L][R] = M; 17 | } 18 | } 19 | } 20 | int64 answer = res[0][k]; -------------------------------------------------------------------------------- /Geometry/3D Rotation.cpp: -------------------------------------------------------------------------------- 1 | //From "You Know Izad?" team cheat sheet 2 | Where c = cos (theta), s = sin(theta), t = 1-cos(theta), and is the unit vector representing the arbitary axis 3 | 1. Left handed about arbitrary axis: 4 | tX^2+c tXY-sZ tXZ+sY 0 5 | tXY+sZ tY^2+c tYZ-sX 0 6 | tXZ-sY tYZ+sX tZ^2+c 0 7 | 0 0 0 1 8 | 9 | 2. Right handed about arbitrary axis: 10 | tX^2+c tXY+sZ tXZ-sY 0 11 | tXY-sZ tY^2+c tYZ+sX 0 12 | tXZ+sY tYZ-sX tZ^2+c 0 13 | 0 0 0 1 14 | 15 | 3. About X Axis 16 | 1 0 0 0 17 | 0 c -s 0 18 | 0 s c 0 19 | 0 0 0 1 20 | 21 | 22 | 4. About Y Axis 23 | c 0 s 0 24 | 0 1 0 0 25 | -s 0 c 0 26 | 0 0 0 1 27 | 28 | 5. About Z Axis 29 | c -s 0 0 30 | s c 0 0 31 | 0 0 1 0 32 | 0 0 0 1 33 | -------------------------------------------------------------------------------- /Geometry/Angle Bisector.cpp: -------------------------------------------------------------------------------- 1 | // angle bisector 2 | int bcenter( PT p1, PT p2, PT p3, PT& r ){ 3 | if( triarea( p1, p2, p3 ) < EPS ) return -1; 4 | double s1, s2, s3; 5 | s1 = dist( p2, p3 ); 6 | s2 = dist( p1, p3 ); 7 | s3 = dist( p1, p2 ); 8 | double rt = s2/(s2+s3); 9 | PT a1,a2; 10 | a1 = p2*rt+p3*(1.0-rt); 11 | rt = s1/(s1+s3); 12 | a2 = p1*rt+p3*(1.0-rt); 13 | intersection( a1,p1, a2,p2, r ); 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /Geometry/Circle Circle Intersection.cpp: -------------------------------------------------------------------------------- 1 | // rotate a point CCW or CW around the origin 2 | PT RotateCCW90(PT p) { return PT(-p.y,p.x); } 3 | PT RotateCW90(PT p) { return PT(p.y,-p.x); } 4 | PT RotateCCW(PT p, double t) { 5 | return PT(p.x*cos(t)-p.y*sin(t), p.x*sin(t)+p.y*cos(t)); 6 | } 7 | 8 | // compute intersection of circle centered at a with radius r 9 | // with circle centered at b with radius R 10 | vector CircleCircleIntersection(PT a, PT b, double r, double R) { 11 | vector ret; 12 | double d = sqrt(dist2(a, b)); 13 | if (d > r + R || d + min(r, R) < max(r, R)) return ret; 14 | double x = (d * d - R * R + r * r) / (2 * d); 15 | double y = sqrt(r * r - x * x); 16 | PT v = (b - a) / d; 17 | ret.push_back(a + v * x + RotateCCW90(v) * y); 18 | if (y > 0) 19 | ret.push_back(a + v * x - RotateCCW90(v) * y); 20 | return ret; 21 | } 22 | -------------------------------------------------------------------------------- /Geometry/Circle Line Intersection.cpp: -------------------------------------------------------------------------------- 1 | // compute intersection of line through points a and b with 2 | // circle centered at c with radius r > 0 3 | vector CircleLineIntersection(PT a, PT b, PT c, double r) { 4 | vector ret; 5 | b = b-a; 6 | a = a-c; 7 | double A = dot(b, b); 8 | double B = dot(a, b); 9 | double C = dot(a, a) - r*r; 10 | double D = B*B - A*C; 11 | if (D < -EPS) return ret; 12 | ret.push_back(c+a+b*(-B+sqrt(D+EPS))/A); 13 | if (D > EPS) 14 | ret.push_back(c+a+b*(-B-sqrt(D))/A); 15 | return ret; 16 | } 17 | -------------------------------------------------------------------------------- /Geometry/Circle from Three Points.cpp: -------------------------------------------------------------------------------- 1 | Point center_from(double bx, double by, double cx, double cy) { 2 | double B=bx*bx+by*by, C=cx*cx+cy*cy, D=bx*cy-by*cx; 3 | return Point((cy*B-by*C)/(2*D), (bx*C-cx*B)/(2*D)); 4 | } 5 | 6 | Point circle_from(Point A, Point B, Point C) { 7 | Point I = center_from(B.X-A.X, B.Y-A.Y, C.X-A.X, C.Y-A.Y); 8 | return Point(I.X + A.X, I.Y + A.Y); 9 | } -------------------------------------------------------------------------------- /Geometry/Closest Pair of Points.cpp: -------------------------------------------------------------------------------- 1 | struct point { 2 | double x, y; 3 | int id; 4 | point() {} 5 | point (double a, double b) : x(a), y(b) {} 6 | }; 7 | 8 | double dist(const point &o, const point &p) { 9 | double a = p.x - o.x, b = p.y - o.y; 10 | return sqrt(a * a + b * b); 11 | } 12 | 13 | double cp(vector &p, vector &x, vector &y) { 14 | if (p.size() < 4) { 15 | double best = 1e100; 16 | for (int i = 0; i < p.size(); ++i) 17 | for (int j = i + 1; j < p.size(); ++j) 18 | best = min(best, dist(p[i], p[j])); 19 | return best; 20 | } 21 | 22 | int ls = (p.size() + 1) >> 1; 23 | double l = (p[ls - 1].x + p[ls].x) * 0.5; 24 | vector xl(ls), xr(p.size() - ls); 25 | unordered_set left; 26 | for (int i = 0; i < ls; ++i) { 27 | xl[i] = x[i]; 28 | left.insert(x[i].id); 29 | } 30 | for (int i = ls; i < p.size(); ++i) { 31 | xr[i - ls] = x[i]; 32 | } 33 | 34 | vector yl, yr; 35 | vector pl, pr; 36 | yl.reserve(ls); yr.reserve(p.size() - ls); 37 | pl.reserve(ls); pr.reserve(p.size() - ls); 38 | for (int i = 0; i < p.size(); ++i) { 39 | if (left.count(y[i].id)) 40 | yl.push_back(y[i]); 41 | else 42 | yr.push_back(y[i]); 43 | 44 | if (left.count(p[i].id)) 45 | pl.push_back(p[i]); 46 | else 47 | pr.push_back(p[i]); 48 | } 49 | 50 | double dl = cp(pl, xl, yl); 51 | double dr = cp(pr, xr, yr); 52 | double d = min(dl, dr); 53 | vector yp; yp.reserve(p.size()); 54 | for (int i = 0; i < p.size(); ++i) { 55 | if (fabs(y[i].x - l) < d) 56 | yp.push_back(y[i]); 57 | } 58 | for (int i = 0; i < yp.size(); ++i) { 59 | for (int j = i + 1; j < yp.size() && j < i + 7; ++j) { 60 | d = min(d, dist(yp[i], yp[j])); 61 | } 62 | } 63 | return d; 64 | } 65 | 66 | double closest_pair(vector &p) { 67 | vector x(p.begin(), p.end()); 68 | sort(x.begin(), x.end(), [](const point &a, const point &b) { 69 | return a.x < b.x; 70 | }); 71 | vector y(p.begin(), p.end()); 72 | sort(y.begin(), y.end(), [](const point &a, const point &b) { 73 | return a.y < b.y; 74 | }); 75 | return cp(p, x, y); 76 | } 77 | -------------------------------------------------------------------------------- /Geometry/Closest Point on Line.cpp: -------------------------------------------------------------------------------- 1 | //From In 1010101 We Trust cheatsheet: 2 | //the closest point on the line p1->p2 to p3 3 | void closestpt( PT p1, PT p2, PT p3, PT &r ){ 4 | if(fabs(triarea(p1, p2, p3)) < EPS){ r = p3; return; } 5 | PT v = p2-p1; v.normalize(); 6 | double pr; // inner product 7 | pr = (p3.y-p1.y)*v.y + (p3.x-p1.x)*v.x; 8 | r = p1+v*pr; 9 | } 10 | -------------------------------------------------------------------------------- /Geometry/Convexhull.cpp: -------------------------------------------------------------------------------- 1 | ll cross(Point a , Point b){ 2 | return a.x * b.y - a.y *b.x; 3 | } 4 | 5 | void convex(){ 6 | sort(points.begin(), points.end()); 7 | int m = 0; 8 | fore(i,0,points.size()-1){ 9 | while (m > 1 && cross(CH[m-1] - CH[m-2] , points[i] - CH[m-2]) <= 0){ 10 | CH.pop_back(); 11 | m--; 12 | } 13 | CH.push_back(points[i]); 14 | m++; 15 | } 16 | 17 | int k = m; 18 | forn(i,points.size()-2 , 0){ 19 | while (m > k && cross(CH[m-1] - CH[m-2] , points[i] - CH[m-2]) <= 0){ 20 | CH.pop_back(); 21 | m--; 22 | } 23 | CH.push_back(points[i]); 24 | m++; 25 | } 26 | } 27 | 28 | ld area() { 29 | ld sum = 0; 30 | int i; 31 | fore(i,0,CH.size()-2){ 32 | sum += (CH[i].x*CH[i+1].y - CH[i].y*CH[i+1].x); 33 | } 34 | return fabs(sum/2); 35 | } -------------------------------------------------------------------------------- /Geometry/Delaunay Triangulation.cpp: -------------------------------------------------------------------------------- 1 | // Slow but simple Delaunay triangulation. Does not handle 2 | // degenerate cases (from O'Rourke, Computational Geometry in C) 3 | // 4 | // Running time: O(n^4) 5 | // 6 | // INPUT: x[] = x-coordinates 7 | // y[] = y-coordinates 8 | // 9 | // OUTPUT: triples = a vector containing m triples of indices 10 | // corresponding to triangle vertices 11 | 12 | typedef double T; 13 | 14 | struct triple { 15 | int i, j, k; 16 | triple() {} 17 | triple(int i, int j, int k) : i(i), j(j), k(k) {} 18 | }; 19 | 20 | vector delaunayTriangulation(vector& x, vector& y) { 21 | int n = x.size(); 22 | vector z(n); 23 | vector ret; 24 | 25 | for (int i = 0; i < n; i++) 26 | z[i] = x[i] * x[i] + y[i] * y[i]; 27 | 28 | for (int i = 0; i < n-2; i++) { 29 | for (int j = i+1; j < n; j++) { 30 | for (int k = i+1; k < n; k++) { 31 | if (j == k) continue; 32 | double xn = (y[j]-y[i])*(z[k]-z[i]) - (y[k]-y[i])*(z[j]-z[i]); 33 | double yn = (x[k]-x[i])*(z[j]-z[i]) - (x[j]-x[i])*(z[k]-z[i]); 34 | double zn = (x[j]-x[i])*(y[k]-y[i]) - (x[k]-x[i])*(y[j]-y[i]); 35 | bool flag = zn < 0; 36 | for (int m = 0; flag && m < n; m++) 37 | flag = flag && ((x[m]-x[i])*xn + 38 | (y[m]-y[i])*yn + 39 | (z[m]-z[i])*zn <= 0); 40 | if (flag) ret.push_back(triple(i, j, k)); 41 | } 42 | } 43 | } 44 | return ret; 45 | } 46 | 47 | int main() 48 | { 49 | T xs[]={0, 0, 1, 0.9}; 50 | T ys[]={0, 1, 0, 0.9}; 51 | vector x(&xs[0], &xs[4]), y(&ys[0], &ys[4]); 52 | vector tri = delaunayTriangulation(x, y); 53 | 54 | //expected: 0 1 3 55 | // 0 3 2 56 | 57 | int i; 58 | for(i = 0; i < tri.size(); i++) 59 | printf("%d %d %d\n", tri[i].i, tri[i].j, tri[i].k); 60 | return 0; 61 | } -------------------------------------------------------------------------------- /Geometry/Latitude and Longitude.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Converts from rectangular coordinates to latitude/longitude and vice 3 | versa. Uses degrees (not radians). 4 | */ 5 | 6 | using namespace std; 7 | 8 | struct ll 9 | { 10 | double r, lat, lon; 11 | }; 12 | 13 | struct rect 14 | { 15 | double x, y, z; 16 | }; 17 | 18 | ll convert(rect& P) 19 | { 20 | ll Q; 21 | Q.r = sqrt(P.x*P.x+P.y*P.y+P.z*P.z); 22 | Q.lat = 180/M_PI*asin(P.z/Q.r); 23 | Q.lon = 180/M_PI*acos(P.x/sqrt(P.x*P.x+P.y*P.y)); 24 | 25 | return Q; 26 | } 27 | 28 | rect convert(ll& Q) 29 | { 30 | rect P; 31 | P.x = Q.r*cos(Q.lon*M_PI/180)*cos(Q.lat*M_PI/180); 32 | P.y = Q.r*sin(Q.lon*M_PI/180)*cos(Q.lat*M_PI/180); 33 | P.z = Q.r*sin(Q.lat*M_PI/180); 34 | 35 | return P; 36 | } 37 | 38 | int main() 39 | { 40 | rect A; 41 | ll B; 42 | 43 | A.x = -1.0; A.y = 2.0; A.z = -3.0; 44 | 45 | B = convert(A); 46 | cout << B.r << " " << B.lat << " " << B.lon << endl; 47 | 48 | A = convert(B); 49 | cout << A.x << " " << A.y << " " << A.z << endl; 50 | } -------------------------------------------------------------------------------- /Geometry/Line Intersection.cpp: -------------------------------------------------------------------------------- 1 | // Ax + By = C 2 | A = y2 - y1 3 | B = x1 - x2 4 | C = A*x1 + B*y1 5 | double det = A1*B2 - A2*B1 6 | double x = (B2*C1 - B1*C2)/det 7 | double y = (A1*C2 - A2*C1)/det 8 | 9 | typedef pair pointd; 10 | #define X first 11 | #define Y second 12 | bool eqf(double a, double b) { 13 | return fabs(b - a) < 1e-6; 14 | } 15 | int crossVecs(pointd a, pointd b) { 16 | return a.X * b.Y - a.Y*b.X; 17 | } 18 | int cross(pointd o, pointd a, pointd b){ 19 | return crossVecs(make_pair(a.X - o.X, a.Y - o.Y), make_pair(b.X - o.X, b.Y - o.Y)); 20 | } 21 | int dotVecs(pointd a, pointd b) { 22 | return a.X * b.X + a.Y * b.Y; 23 | } 24 | int dot(pointd o, pointd a, pointd b) { 25 | return dotVecs(make_pair(a.X - o.X, a.Y - o.Y), make_pair(b.X - o.X, b.Y - o.Y)); 26 | } 27 | bool onTheLine(const pointd& a, const pointd& p, const pointd& b) { 28 | return eqf(cross(p, a, b), 0) && dot(p, a, b) < 0 ; 29 | } 30 | class LineSegment { 31 | public: 32 | double A, B, C; 33 | pointd from, to; 34 | LineSegment(const pointd& a, const pointd& b) { 35 | A = b.Y - a.Y; 36 | B = a.X - b.X; 37 | C = A*a.X + B*a.Y; 38 | from = a; 39 | to = b; 40 | } 41 | 42 | bool between(double l, double a, double r) const { 43 | if(l > r) { 44 | swap(l, r); 45 | } 46 | return l <= a && a <= r; 47 | } 48 | 49 | bool pointOnSegment(const pointd& p) const { 50 | return eqf(A*p.X + B*p.Y, C) && between(from.X, p.X, to.X) && between(from.Y, p.Y, to.Y); 51 | } 52 | 53 | pair segmentsIntersect(const LineSegment& l) const { 54 | double det = A * l.B - B * l.A; 55 | pair ret; 56 | ret.first = false; 57 | if(det != 0) { 58 | pointd inter((l.B*C - B*l.C)/det, (A*l.C - l.A*C)/det); 59 | if(l.pointOnSegment(inter) && pointOnSegment(inter)) { 60 | ret.first = true; 61 | ret.second = inter; 62 | } 63 | } 64 | return ret; 65 | } 66 | }; 67 | -------------------------------------------------------------------------------- /Geometry/Point in Polygon.cpp: -------------------------------------------------------------------------------- 1 | // determine if point is in a possibly non-convex polygon (by William 2 | // Randolph Franklin); returns 1 for strictly interior points, 0 for 3 | // strictly exterior points, and 0 or 1 for the remaining points. 4 | // Note that it is possible to convert this into an *exact* test using 5 | // integer arithmetic by taking care of the division appropriately 6 | // (making sure to deal with signs properly) and then by writing exact 7 | // tests for checking point on polygon boundary 8 | bool PointInPolygon(const vector &p, PT q) { 9 | bool c = 0; 10 | for (int i = 0; i < p.size(); i++){ 11 | int j = (i+1)%p.size(); 12 | if ((p[i].y <= q.y && q.y < p[j].y || 13 | p[j].y <= q.y && q.y < p[i].y) && 14 | q.x < p[i].x + (p[j].x - p[i].x) * (q.y - p[i].y) / (p[j].y - p[i].y)) 15 | c = !c; 16 | } 17 | return c; 18 | } -------------------------------------------------------------------------------- /Geometry/Polygon Centroid.cpp: -------------------------------------------------------------------------------- 1 | // This code computes the area or centroid of a (possibly nonconvex) 2 | // polygon, assuming that the coordinates are listed in a clockwise or 3 | // counterclockwise fashion. Note that the centroid is often known as 4 | // the "center of gravity" or "center of mass". 5 | double ComputeSignedArea(const vector &p) { 6 | double area = 0; 7 | for(int i = 0; i < p.size(); i++) { 8 | int j = (i+1) % p.size(); 9 | area += p[i].x*p[j].y - p[j].x*p[i].y; 10 | } 11 | return area / 2.0; 12 | } 13 | 14 | double ComputeArea(const vector &p) { 15 | return fabs(ComputeSignedArea(p)); 16 | } 17 | 18 | PT ComputeCentroid(const vector &p) { 19 | PT c(0,0); 20 | double scale = 6.0 * ComputeSignedArea(p); 21 | for (int i = 0; i < p.size(); i++){ 22 | int j = (i+1) % p.size(); 23 | c = c + (p[i]+p[j])*(p[i].x*p[j].y - p[j].x*p[i].y); 24 | } 25 | return c / scale; 26 | } 27 | -------------------------------------------------------------------------------- /Geometry/Rotation Around Origin by t.cpp: -------------------------------------------------------------------------------- 1 | x’ = x.Cos(t) - y.Sin(t) 2 | y’ = x.Sin(t) + y.Cos(t) -------------------------------------------------------------------------------- /Geometry/Segment Circle Distance.cpp: -------------------------------------------------------------------------------- 1 | bool find_min_dis(P p1, P p2, P c, ld ratio){ 2 | //no intersection: segment inside circle 3 | if(p1.dis(c) <= ratio*ratio && p2.dis(c)<= ratio*ratio) 4 | return 0; 5 | 6 | P v= p2-p1; 7 | ld l, r, ax, ay, az, base; 8 | if(v.x != 0) 9 | l= p1.x, r= p2.x, ax=1, ay=v.y/v.x, az=v.z/v.x, base=p1.x; 10 | else if(v.y !=0) 11 | l= p1.y, r= p2.y, ax= v.x/v.y, ay=1, az=v.z/v.y, base=p1.y; 12 | else 13 | l= p1.z, r= p2.z, ax= v.x/v.z, ay=v.y/v.z, az=1, base=p1.z; 14 | 15 | ld lastd= p1.dis(c); 16 | while(abs(r-l)>eps){ 17 | ld m1= (2*l+r)/3,m2=(l+2*r)/3; 18 | P t1= {p1.x+ax*(m1-base), p1.y+ay*(m1-base), p1.z+az*(m1-base)}; 19 | P t2= {p1.x+ax*(m2-base), p1.y+ay*(m2-base), p1.z+az*(m2-base)}; 20 | ld d1= t1.dis(c), d2= t2.dis(c); 21 | if(d1 > d2) 22 | l= m1; 23 | else 24 | r= m2; 25 | lastd= d1; 26 | } 27 | if(lastd <= ratio*ratio) 28 | return 1; 29 | return 0; 30 | } -------------------------------------------------------------------------------- /Geometry/Two Point and Radius Circle.cpp: -------------------------------------------------------------------------------- 1 | vector find_center(point a, point b, long double r) { 2 | point d = (a - b) * 0.5; 3 | if (d.dot(d) > r * r) { 4 | return vector (); 5 | } 6 | point e = b + d; 7 | long double fac = sqrt(r * r - d.dot(d)); 8 | vector ans; 9 | point x = point(-d.y, d.x); 10 | long double l = sqrt(x.dot(x)); 11 | x = x * (fac / l); 12 | ans.push_back(e + x); 13 | x = point(d.y, -d.x); 14 | x = x * (fac / l); 15 | ans.push_back(e + x); 16 | return ans; 17 | } 18 | 19 | -------------------------------------------------------------------------------- /Geometry/geometry algorithms.cpp: -------------------------------------------------------------------------------- 1 | Line(Point p1 , Point p2){ 2 | a = p2.y - p1.y; 3 | b = p1.x - p2.x; 4 | c = a * p1.x + b * p1.y; 5 | c = -c; 6 | 7 | } 8 | 9 | Point intersection(Line l1 , Line l2){ 10 | ld a1 = l1.a; 11 | ld b1 = l1.b; 12 | ld c1 = -l1.c; 13 | ld a2 = l2.a; 14 | ld b2 = l2.b; 15 | ld c2 = -l2.c; 16 | ld determinant = a1*b2 - a2*b1; 17 | ld x = (b2*c1 - b1*c2)/determinant; 18 | ld y = (a1*c2 - a2*c1)/determinant; 19 | return Point(x, y); 20 | } 21 | 22 | Point mirrorImage(Point p , Line l) 23 | { 24 | ld a = l.a; 25 | ld b = l.b; 26 | ld c = l.c; 27 | ld x1 = p.x; 28 | ld y1 = p.y; 29 | ld temp = -2 * (a * x1 + b * y1 + c) / 30 | (a * a + b * b); 31 | ld x = temp * a + x1; 32 | ld y = temp * b + y1; 33 | return Point(x, y); 34 | } 35 | 36 | ld pointToLine(Point p0, Point p1, Point p2){ 37 | //p0 to (p1 , p2) 38 | ll x0 = p0.x; 39 | ll y0 = p0.y; 40 | ll x1 = p1.x; 41 | ll y1 = p1.y; 42 | ll x2 = p2.x; 43 | ll y2 = p2.y; 44 | ld a = ((y2 - y1)*x0 - (x2 - x1)*y0 + x2 * y1 - y2 * x1); 45 | ld b = (y2 - y1)*(y2 - y1) + (x2 - x1)*(x2 - x1); 46 | return a * a / b; 47 | } 48 | 49 | inline p3d rotate(const p3d& p /*pt*/, const p3d& u /*axis*/, const ld& angle) { 50 | //p center u 51 | ld c = cos(angle), s = sin(angle), t = 1 - cos(angle); return { 52 | p.x*(t*u.x*u.x + c) + p.y*(t*u.x*u.y - s*u.z) + p.z*(t*u.x*u.z + s*u.y), 53 | p.x*(t*u.x*u.y + s*u.z) + p.y*(t*u.y*u.y + c) + p.z*(t*u.y*u.z - s*u.x), 54 | p.x*(t*u.x*u.z - s*u.y) + p.y*(t*u.y*u.z + s*u.x) + p.z*(t*u.z*u.z + c) }; 55 | } 56 | 57 | 58 | int cmp(ld x){ 59 | if (fabs(x) < eps) 60 | return 0; 61 | return ((x < 0 ) ? -1 : 1); 62 | } 63 | 64 | ld Dot( const Vec2& a, const Vec2& b ) 65 | { 66 | return a.x * b.x + a.y * b.y; 67 | } 68 | 69 | int orientation(Point p, Point q, Point r) 70 | { 71 | ld val = (q.y - p.y) * (r.x - q.x) - 72 | (q.x - p.x) * (r.y - q.y); 73 | 74 | if (cmp(val) == 0) return 0; 75 | return (cmp(val) > 0)? 1: 2; 76 | } 77 | 78 | bool onSegment(Point p, Point q, Point r) 79 | { 80 | // (p , r) point q 81 | if (cmp(q.x - max(p.x, r.x)) >= 0 && cmp(q.x - min(p.x, r.x)) <= 0 && 82 | cmp(q.y - max(p.y, r.y)) >= 0 && cmp(q.y - min(p.y, r.y)) <= 0 ) 83 | return true; 84 | return false; 85 | } 86 | 87 | bool doIntersect(Point p1, Point q1, Point p2, Point q2) 88 | { 89 | // (p1 , q1) intersect (p2 , q2) 90 | int o1 = orientation(p1, q1, p2); 91 | int o2 = orientation(p1, q1, q2); 92 | int o3 = orientation(p2, q2, p1); 93 | int o4 = orientation(p2, q2, q1); 94 | if (o1 != o2 && o3 != o4) 95 | return true; 96 | if (o1 == 0 && onSegment(p1, p2, q1)) return true; 97 | if (o2 == 0 && onSegment(p1, q2, q1)) return true; 98 | if (o3 == 0 && onSegment(p2, p1, q2)) return true; 99 | if (o4 == 0 && onSegment(p2, q1, q2)) return true; 100 | return false; // Doesn't fall in any of the above cases 101 | } 102 | 103 | bool isInside(Point p) 104 | { 105 | if (n < 3) return false; 106 | Point extreme = {1e18, p.y}; 107 | int count = 0, i = 0; 108 | do 109 | { 110 | int next = (i+1)%n; 111 | if (doIntersect(polygon[i], polygon[next], p, extreme)) 112 | { 113 | if (orientation(polygon[i], p, polygon[next]) == 0) 114 | return onSegment(polygon[i], p, polygon[next]); 115 | 116 | count++; 117 | } 118 | i = next; 119 | } while (i != 0); 120 | return count&1; 121 | } 122 | ld cross(Vec2 a , Vec2 b){ 123 | return a.x * b.y - a.y * b.x; 124 | } 125 | ld len(Vec2 a){ 126 | return hypotl(a.x , a.y); 127 | } 128 | ld SqDistancePtSegment( Vec2 a, Vec2 b, Vec2 p ) 129 | { 130 | Vec2 v1 = b - a; 131 | Vec2 v2 = p - a; 132 | Vec2 v3 = p - b; 133 | if (cmp(Dot(v1 , v2)) < 0)return len(v2); 134 | if (cmp(Dot(v1 , v3)) > 0) return len(v3); 135 | return fabs(cross(v1 , v2)) /len(v1); 136 | } 137 | Point F( int i ,int j , int k){ 138 | Vec2 a , b , c; 139 | a.x = polygon[i].x; 140 | a.y = polygon[i].y; 141 | b.x = polygon[j].x; 142 | b.y = polygon[j].y; 143 | c.x = polygon[k].x; 144 | c.y = polygon[k].y; 145 | Vec2 v1 = b - a; 146 | Vec2 v2 = c - a; 147 | Vec2 nimsaz = (v2 * len(v1)) + (v1 * len(v2)) ; 148 | ld sz = len(nimsaz); 149 | nimsaz.x /= sz; 150 | nimsaz.y /= sz; 151 | ld costeta = Dot(nimsaz , v2) / (len(nimsaz) * len(v2)); 152 | ld sinteta = sqrt(1.0 - costeta * costeta); 153 | ld d = R / sinteta; 154 | Vec2 point = (nimsaz * d) + a; 155 | return {point.x , point.y}; 156 | 157 | } 158 | 159 | Point rotate(Point c , Point p , ld angle) 160 | { 161 | ld sn = sin(angle); 162 | ld cs = cos(angle); 163 | Point q(cs*(p.x-c.x) - sn *(p.y-c.y) + c.x , sn *(p.x-c.x) + cs * (p.y-c.y) + c.y); 164 | return q; 165 | } -------------------------------------------------------------------------------- /Graph/Bipartite Matching and Vertex Cover.cpp: -------------------------------------------------------------------------------- 1 | //Bipartite Matching is O(M * N) 2 | #define M 128 3 | #define N 128 4 | bool graph[M][N]; 5 | bool seen[N]; 6 | int matchL[M], matchR[N]; 7 | int n, m; 8 | bool bpm( int u ) 9 | { 10 | for( int v = 0; v < n; v++ ) if( graph[u][v] ) 11 | { 12 | if( seen[v] ) continue; 13 | seen[v] = true; 14 | 15 | if( matchR[v] < 0 || bpm( matchR[v] ) ) 16 | { 17 | matchL[u] = v; 18 | matchR[v] = u; 19 | return true; 20 | } 21 | } 22 | return false; 23 | } 24 | vector vertex_cover() 25 | { 26 | // Comment : Vertices on the left side (n side) are labeled like this : m+i where i is the index 27 | set s, t, um; // um = UnMarked 28 | vector vc; 29 | for(int i = 0; i < m; i++) 30 | if(matchL[i]==-1) 31 | s.insert(i), um.insert(i); 32 | while( um.size() ) 33 | { 34 | int v = *(um.begin()); 35 | for(int i = 0; i < n; i++) 36 | if( graph[v][i] && matchL[v]!=i) 37 | { 38 | t.insert(i); 39 | if( s.find(matchR[i]) == s.end()) 40 | s.insert(matchR[i]), um.insert(matchR[i]); 41 | } 42 | um.erase(v); 43 | } 44 | for(int i = 0; i < m; i++) 45 | if( s.find(i) == s.end() ) 46 | vc.push_back(i); 47 | for(set::iterator i = t.begin(); i != t.end(); i++) 48 | vc.push_back((*i) + m); 49 | return vc; 50 | } 51 | int main() 52 | { 53 | // Read input and populate graph[][] 54 | // Set m, n 55 | memset( matchL, -1, sizeof( matchL ) ); 56 | memset( matchR, -1, sizeof( matchR ) ); 57 | int cnt = 0; 58 | for( int i = 0; i < m; i++ ) 59 | { 60 | memset( seen, 0, sizeof( seen ) ); 61 | if( bpm( i ) ) cnt++; 62 | } 63 | vector vc = vertex_cover(); 64 | // cnt contains the number of happy pigeons 65 | // matchL[i] contains the hole of pigeon i or -1 if pigeon i is unhappy 66 | // matchR[j] contains the pigeon in hole j or -1 if hole j is empty 67 | // vc contains the Vertex Cover 68 | return 0; 69 | } -------------------------------------------------------------------------------- /Graph/Count Triangles.cpp: -------------------------------------------------------------------------------- 1 | vector adj[maxn], Adj[maxn]; 2 | 3 | int ord[maxn], f[maxn], fi[maxn], se[maxn], ans[maxn]; 4 | 5 | bool get(int v,int u) { 6 | int idx = lower_bound(adj[v].begin(), adj[v].end(), u) - adj[v].begin(); 7 | if (idx != adj[v].size() && adj[v][idx] == u) 8 | return true; 9 | return false; 10 | } 11 | 12 | bool cmp(int v,int u) { 13 | if (adj[v].size() < adj[u].size()) 14 | return true; 15 | if (adj[v].size() > adj[u].size()) 16 | return false; 17 | return (v < u); 18 | } 19 | 20 | int main() { 21 | int n, m, q; 22 | cin >> n >> m >> q; 23 | for (int i = 0; i < m; i++) { 24 | cin >> fi[i] >> se[i]; 25 | fi[i]--, se[i]--; 26 | adj[fi[i]].push_back(se[i]); 27 | adj[se[i]].push_back(fi[i]); 28 | Adj[fi[i]].push_back(se[i]); 29 | Adj[se[i]].push_back(fi[i]); 30 | } 31 | for (int i = 0; i < n; i++) 32 | sort(adj[i].begin(), adj[i].end()), 33 | sort(Adj[i].begin(), Adj[i].end(), cmp); 34 | for (int i = 0; i < n; i++) 35 | ord[i] = i; 36 | sort (ord, ord + n, cmp); 37 | for (int i = 0; i < n; i++) 38 | f[ord[i]] = i; 39 | for (int v = 0; v < n; v++) { 40 | int idx = -1; 41 | for (int j = 0; j < adj[v].size(); j++) { 42 | int u = Adj[v][j]; 43 | if (f[u] > f[v]) 44 | break; 45 | idx = j; 46 | } 47 | for (int i = 0; i <= idx; i++) 48 | for (int j = 0; j < i; j++) { 49 | int u = Adj[v][i]; 50 | int w = Adj[v][j]; 51 | if (get(u,w)) 52 | ans[v]++, ans[u]++, ans[w]++; 53 | } 54 | } 55 | for (int i = 0; i < q; i++) { 56 | int v; 57 | cin >> v; 58 | v--; 59 | cout << ans[v] << '\n'; 60 | } 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /Graph/DFS on Complement Graph.cpp: -------------------------------------------------------------------------------- 1 | int nxt[maxn], cmp, n; 2 | vector adj[maxn], ver[maxn]; 3 | bool con(int v,int u) { 4 | int idx = lower_bound(adj[v].begin(), adj[v].end(), u) - adj[v].begin(); 5 | return (idx != adj[v].size() && adj[v][idx] == u); 6 | } 7 | int get(int v) { 8 | if (nxt[v] == v) 9 | return v; 10 | return (nxt[v] = get(nxt[v])); 11 | } 12 | void dfs(int v) { 13 | nxt[v] = get(v + 1); 14 | ver[cmp].push_back(v); 15 | for (int u = get(0); u < n; u = get(u + 1)) { 16 | if (!con(u, v)) 17 | dfs(u); 18 | } 19 | } 20 | 21 | int main() { 22 | //we have zero based normal graph in adj 23 | for (int i = 0; i <= n; i++) 24 | sort (adj[i].begin(), adj[i].end()); 25 | for (int i = 0; i < maxn; i++) 26 | nxt[i] = i; 27 | for (int i = 0; i < n; i++) 28 | if (get(i) == i) 29 | dfs(i), cmp++; 30 | printf("%d\n", cmp); 31 | for (int i = 0; i < cmp; i++) { 32 | printf("%d ", (int)ver[i].size()); 33 | for (int j = 0; j < ver[i].size(); j++) 34 | printf("%d ", ver[i][j] + 1); 35 | printf("\n"); 36 | } 37 | } -------------------------------------------------------------------------------- /Graph/DSU on Tree.cpp: -------------------------------------------------------------------------------- 1 | // How many vertices in subtree of vertices v has some property in O(n lg n) time (for all of the queries). 2 | // Approach 1 3 | //sz[i] = size of subtree of node i 4 | int cnt[maxn]; 5 | bool big[maxn]; 6 | void add(int v, int p, int x){ 7 | cnt[ col[v] ] += x; 8 | for(auto u: g[v]) 9 | if(u != p && !big[u]) 10 | add(u, v, x) 11 | } 12 | void dfs(int v, int p, bool keep){ 13 | int mx = -1, bigChild = -1; 14 | for(auto u : g[v]) 15 | if(u != p && sz[u] > mx) 16 | mx = sz[u], bigChild = u; 17 | for(auto u : g[v]) 18 | if(u != p && u != bigChild) 19 | dfs(u, v, 0); // run a dfs on small childs and clear them from cnt 20 | if(bigChild != -1) 21 | dfs(bigChild, v, 1), big[bigChild] = 1; // bigChild marked as big and not cleared from cnt 22 | add(v, p, 1); 23 | //now cnt[c] is the number of vertices in subtree of vertice v that has color c. You can answer the queries easily. 24 | if(bigChild != -1) 25 | big[bigChild] = 0; 26 | if(keep == 0) 27 | add(v, p, -1); 28 | } -------------------------------------------------------------------------------- /Graph/Euler Tour.cpp: -------------------------------------------------------------------------------- 1 | //Directed Euler Tour­O( E )  2 | void visit (Graph& g, int a , vector& path) { 3 | while (!g[a].empty()){ 4 | int b = g[a].back().dst; 5 | g[a].pop_back(); 6 | visit (g, b, path); 7 | } 8 | path.push_back (a); 9 | } 10 | bool eulerPath (Graph g, int s , vector &path) { 11 | int n = g.size(), m = 0; 12 | vector deg (n); 13 | REP (u , n) { 14 | m += g[u].size(); 15 | FOR (e , g[u]) --deg[e->dst]; // in-deg 16 | deg[u] += g[u].size(); // out-deg 17 | } 18 | int k = n - count (ALL (deg), 0); 19 | if (k == 0 || (k == 2 && deg[s] == 1)) { 20 | path.clear(); 21 | visit (g, s , path); 22 | reverse (ALL (path)); 23 | return path.size () == m + 1; 24 | } 25 | return false; 26 | }  27 | //Undirected Euler Tour­O( E )  28 | void visit(const Graph &g, vector< vector > &adj, int s, vector &path) { 29 | FOR (e , g[s]) 30 | if (adj[e->src][e->dst]) { 31 | --adj[e->src][e->dst]; 32 | --adj[e->dst][e->src]; 33 | visit(g, adj, e->dst , path); 34 | } 35 | path.push_back(s); 36 | } 37 | bool eulerPath (const Graph &g, int s , vector &path) 38 | { 39 | int n = g.size(); 40 | int odd = 0, m = 0; 41 | REP (i, n) { 42 | if (g[i].size() % 2 == 1) 43 | ++odd; 44 | m += g[i].size(); 45 | } 46 | m/= 2; 47 | if (odd == 0 || (odd == 2 && g[s].size() % 2 == 0)) 48 | { 49 | vector< vector > adj (n , vector (n)); 50 | 51 | REP (u , n) FOR (e , g[u]) ++adj[e->src][e->dst]; 52 | path.clear (); 53 | visit (g, adj, s, path); 54 | reverse (ALL (path)); 55 | return path.size() == m + 1; 56 | } 57 | return false; 58 | }  -------------------------------------------------------------------------------- /Graph/Flow With Demands.tex: -------------------------------------------------------------------------------- 1 | \textbf{Finding an arbitrary flow:} We make the following changes in the network. We add a new source $s'$ 2 | and a new sink $t'$, a new edge from the source $s'$ to every other 3 | vertex, a new edge for every vertex to the sink $t'$, and one edge 4 | from $t$ to $s$. Additionally we define the new capacity function 5 | $c'$ as: \\ 6 | • $c'((s', v)) = \sum_{u \in V} d((u, v))$ for each edge $(s', v)$. \\ 7 | • $c'((v, t')) = \sum_{w \in V} d((v, w))$ for each edge $(v, t')$. \\ 8 | • $c'((u, v)) = c((u, v)) - d((u, v))$ for each edge $(u, v)$ in the 9 | old network. \\ 10 | • $c'((t, s)) = \infty$ \\ 11 | 12 | If the new network has a saturating flow (a flow where each edge 13 | outgoing from $s'$ is completely filled, which is equivalent to every 14 | edge incoming to $t'$ is completely filled), then the network with 15 | demands has a valid flow, and the actual flow can be easily 16 | reconstructed from the new network. Otherwise there doesn't exist a flow 17 | that satisfies all conditions. Since a saturating flow has to be a 18 | maximum flow, it can be found by any maximum flow algorithm. \\ 19 | 20 | \textbf{Minimal flow:} 21 | Note that along the edge $(t, s)$ (from the old sink to the old 22 | source) with the capacity $\infty$ flows the entire flow of the 23 | corresponding old network. I.e. the capacity of this edge effects the 24 | flow value of the old network. By giving this edge a sufficient large 25 | capacity (i.e. $\infty$), the flow of the old network is unlimited. By 26 | limiting this edge by smaller capacities, the flow value will decrease. 27 | However if we limit this edge by a too small value, than the network 28 | will not have a saturated solution, e.g. the corresponding solution for 29 | the original network will not satisfy the demand of the edges. Obviously 30 | here can use a binary search to find the lowest value with which all 31 | constraints are still satisfied. This gives the minimal flow of the 32 | original network. -------------------------------------------------------------------------------- /Graph/Min Cost Bipartite Matching.cpp: -------------------------------------------------------------------------------- 1 | //From "You Know Izad?" team cheat sheet 2 | vi u (n+1), v (m+1), p (m+1), way (m+1); 3 | for (int i=1; i<=n; ++i) { 4 | p[0] = i; 5 | int j0 = 0; 6 | vi minv (m+1, INF); 7 | vector used (m+1, false); 8 | do { 9 | used[j0] = true; 10 | int i0 = p[j0], delta = INF, j1; 11 | for (int j=1; j<=m; ++j) 12 | if (!used[j]) { 13 | int cur = a[i0][j]-u[i0]-v[j]; 14 | if (cur < minv[j]) 15 | minv[j] = cur, way[j] = j0; 16 | if (minv[j] < delta) 17 | delta = minv[j], j1 = j; 18 | } 19 | for (int j=0; j<=m; ++j) 20 | if (used[j]) 21 | u[p[j]] += delta, v[j] -= delta; 22 | else 23 | minv[j] -= delta; 24 | j0 = j1; 25 | } while (p[j0] != 0); 26 | do { 27 | int j1 = way[j0]; 28 | p[j0] = p[j1]; 29 | j0 = j1; 30 | } while (j0); 31 | } 32 | int cost = -v[0]; // minimum cost 33 | // ans -> printable matching result 34 | vi ans (n+1); 35 | for (int j=1; j<=m; ++j) 36 | ans[p[j]] = j; -------------------------------------------------------------------------------- /Graph/Weighted Min Cut.cpp: -------------------------------------------------------------------------------- 1 | // Maximum number of vertices in the graph 2 | #define NN 256 3 | 4 | // Maximum edge weight (MAXW * NN * NN must fit into an int) 5 | #define MAXW 1000 6 | 7 | // Adjacency matrix and some internal arrays 8 | int g[NN][NN], v[NN], w[NN], na[NN]; 9 | bool a[NN]; 10 | 11 | int minCut( int n ) 12 | { 13 | // init the remaining vertex set 14 | for( int i = 0; i < n; i++ ) v[i] = i; 15 | 16 | // run Stoer-Wagner 17 | int best = MAXW * n * n; 18 | while( n > 1 ) 19 | { 20 | // initialize the set A and vertex weights 21 | a[v[0]] = true; 22 | for( int i = 1; i < n; i++ ) 23 | { 24 | a[v[i]] = false; 25 | na[i - 1] = i; 26 | w[i] = g[v[0]][v[i]]; 27 | } 28 | 29 | // add the other vertices 30 | int prev = v[0]; 31 | for( int i = 1; i < n; i++ ) 32 | { 33 | // find the most tightly connected non-A vertex 34 | int zj = -1; 35 | for( int j = 1; j < n; j++ ) 36 | if( !a[v[j]] && ( zj < 0 || w[j] > w[zj] ) ) 37 | zj = j; 38 | 39 | // add it to A 40 | a[v[zj]] = true; 41 | 42 | // last vertex? 43 | if( i == n - 1 ) 44 | { 45 | // remember the cut weight 46 | best > f(m, vector(m)); 5 | int s = m - 2, t = m - 1; 6 | int cost = 0; 7 | while (true) { 8 | vector dist(m, INF); 9 | vector p(m); 10 | vector type(m, 2); 11 | deque q; 12 | dist[s] = 0; 13 | p[s] = -1; 14 | type[s] = 1; 15 | q.push_back(s); 16 | while (!q.empty()) { 17 | int v = q.front(); 18 | q.pop_front(); 19 | type[v] = 0; 20 | if (v == s) { 21 | for (int i = 0; i < n; ++i) { 22 | if (f[s][i] == 0) { 23 | dist[i] = 0; 24 | p[i] = s; 25 | type[i] = 1; 26 | q.push_back(i); 27 | } 28 | } 29 | } else { 30 | if (v < n) { 31 | for (int j = n; j < n + n; ++j) { 32 | if (f[v][j] < 1 && dist[j] > dist[v] + a[v][j - n]) { 33 | dist[j] = dist[v] + a[v][j - n]; 34 | p[j] = v; 35 | if (type[j] == 0) 36 | q.push_front(j); 37 | else if (type[j] == 2) 38 | q.push_back(j); 39 | type[j] = 1; 40 | } 41 | } 42 | } else { 43 | for (int j = 0; j < n; ++j) { 44 | if (f[v][j] < 0 && dist[j] > dist[v] - a[j][v - n]) { 45 | dist[j] = dist[v] - a[j][v - n]; 46 | p[j] = v; 47 | if (type[j] == 0) 48 | q.push_front(j); 49 | else if (type[j] == 2) 50 | q.push_back(j); 51 | type[j] = 1; 52 | } 53 | } 54 | } 55 | } 56 | } 57 | 58 | int curcost = INF; 59 | for (int i = n; i < n + n; ++i) { 60 | if (f[i][t] == 0 && dist[i] < curcost) { 61 | curcost = dist[i]; 62 | p[t] = i; 63 | } 64 | } 65 | if (curcost == INF) 66 | break; 67 | cost += curcost; 68 | for (int cur = t; cur != -1; cur = p[cur]) { 69 | int prev = p[cur]; 70 | if (prev != -1) 71 | f[cur][prev] = -(f[prev][cur] = 1); 72 | } 73 | } 74 | 75 | // vector answer(n); 76 | int answer = 0; 77 | for (int i = 0; i < n; ++i) { 78 | for (int j = 0; j < n; ++j) { 79 | if (f[i][j + n] == 1) 80 | answer+=a[i][j]; 81 | } 82 | } 83 | return answer; 84 | } -------------------------------------------------------------------------------- /Graph/bipartie mcmf.cpp: -------------------------------------------------------------------------------- 1 | 2 | vector g[maxn]; 3 | int h[maxn], dst[maxn], prevv[maxn ], preve[maxn]; 4 | inline void add_edge(int f, int t, int cap, int cost) 5 | { 6 | g[f].emplace_back(t, cap, cost, g[t].size()); 7 | g[t].emplace_back(f, 0, -cost, g[f].size() - 1); 8 | } 9 | 10 | int mcmf(int s, int t , int maxFlow) 11 | { 12 | int res = 0; 13 | int c = INT_MAX; 14 | memset(h, 0, sizeof(h)); 15 | int f = 0; 16 | while (f < maxFlow) { 17 | priority_queue, greater > que; 18 | fill(dst, dst + n , inf); 19 | dst[s] = 0; 20 | que.push(mp(0, s)); 21 | while (!que.empty()) { 22 | ii p = que.top(); que.pop(); 23 | int v = p.second; 24 | if (dst[v] < p.first) continue; 25 | for(int i=0; i 0 && dst[e.to] > nd){ 29 | dst[e.to] = nd; 30 | prevv[e.to] = v; 31 | preve[e.to] = i; 32 | que.push(mp(dst[e.to], e.to)); 33 | } 34 | } 35 | } 36 | 37 | if (dst[t] == inf) return c; 38 | for(int i=0; i= 0) break; 47 | 48 | for(int v = t; v != s; v = prevv[v]){ 49 | edge &e = g[prevv[v]][preve[v]]; 50 | e.cap -= d; 51 | g[v][e.rev].cap += d; 52 | } 53 | } 54 | 55 | return c; 56 | } 57 | -------------------------------------------------------------------------------- /Graph/flow.cpp: -------------------------------------------------------------------------------- 1 | // In any case it won't work worse than O(FE) 2 | // O(EV^2) on normal graph 3 | // O(E sqrt(v)) on unit graph: for each vertex 4 | // either incoming or outgoing edge is unique 5 | // and that edge has 1 capacity 6 | // min O(V Sqrt(E)), O(E V^2/3) on graph with only 1 capacity edges 7 | struct FlowEdge { 8 | int v, u; 9 | long long cap, flow = 0; 10 | FlowEdge(int v, int u, long long cap) : v(v), u(u), cap(cap) {} 11 | }; 12 | 13 | struct Dinic { 14 | const long long flow_inf = 1e18; 15 | vector edges; 16 | vector> adj; 17 | int n, m = 0; 18 | int s, t; 19 | vector level, ptr; 20 | queue q; 21 | 22 | Dinic(int n, int s, int t) : n(n), s(s), t(t) { 23 | adj.resize(n); 24 | level.resize(n); 25 | ptr.resize(n); 26 | } 27 | 28 | void add_edge(int v, int u, long long cap) { 29 | // TRACE(v _ u _ cap); 30 | edges.emplace_back(v, u, cap); 31 | edges.emplace_back(u, v, 0); 32 | adj[v].push_back(m); 33 | adj[u].push_back(m + 1); 34 | m += 2; 35 | } 36 | 37 | bool bfs() { 38 | while (!q.empty()) { 39 | int v = q.front(); 40 | q.pop(); 41 | for (int id : adj[v]) { 42 | if (edges[id].cap - edges[id].flow < 1) 43 | continue; 44 | if (level[edges[id].u] != -1) 45 | continue; 46 | level[edges[id].u] = level[v] + 1; 47 | q.push(edges[id].u); 48 | } 49 | } 50 | return level[t] != -1; 51 | } 52 | 53 | long long dfs(int v, long long pushed) { 54 | if (pushed == 0) 55 | return 0; 56 | if (v == t) 57 | return pushed; 58 | for (int& cid = ptr[v]; cid < (int)adj[v].size(); cid++) { 59 | int id = adj[v][cid]; 60 | int u = edges[id].u; 61 | if (level[v] + 1 != level[u] || edges[id].cap - edges[id].flow < 1) 62 | continue; 63 | long long tr = dfs(u, min(pushed, edges[id].cap - edges[id].flow)); 64 | if (tr == 0) 65 | continue; 66 | edges[id].flow += tr; 67 | edges[id ^ 1].flow -= tr; 68 | return tr; 69 | } 70 | return 0; 71 | } 72 | 73 | long long flow() { 74 | long long f = 0; 75 | while (true) { 76 | fill(level.begin(), level.end(), -1); 77 | level[s] = 0; 78 | q.push(s); 79 | if (!bfs()) 80 | break; 81 | fill(ptr.begin(), ptr.end(), 0); 82 | while (long long pushed = dfs(s, flow_inf)) { 83 | f += pushed; 84 | } 85 | } 86 | return f; 87 | } 88 | }; 89 | -------------------------------------------------------------------------------- /Graph/hungarian.cpp: -------------------------------------------------------------------------------- 1 | const int64_t INF64 = int64_t(2e18) + 5; 2 | 3 | vector assignment; 4 | 5 | template 6 | int64_t hungarian(vector> costs) { 7 | int n = int(costs.size()); 8 | int m = costs.empty() ? 0 : int(costs[0].size()); 9 | 10 | if (n > m) { 11 | vector> new_costs(m, vector(n)); 12 | 13 | for (int i = 0; i < n; i++) 14 | for (int j = 0; j < m; j++) 15 | new_costs[j][i] = costs[i][j]; 16 | 17 | swap(costs, new_costs); 18 | swap(n, m); 19 | } 20 | 21 | vector u(n + 1), v(m + 1); 22 | vector p(m + 1), way(m + 1); 23 | 24 | for (int i = 1; i <= n; i++) { 25 | vector min_v(m + 1, INF64); 26 | vector used(m + 1, false); 27 | p[0] = i; 28 | int j0 = 0; 29 | 30 | do { 31 | used[j0] = true; 32 | int i0 = p[j0], j1 = 0; 33 | int64_t delta = INF64; 34 | 35 | for (int j = 1; j <= m; j++) 36 | if (!used[j]) { 37 | int64_t cur = costs[i0 - 1][j - 1] - u[i0] - v[j]; 38 | 39 | if (cur < min_v[j]) { 40 | min_v[j] = cur; 41 | way[j] = j0; 42 | } 43 | 44 | if (min_v[j] < delta) { 45 | delta = min_v[j]; 46 | j1 = j; 47 | } 48 | } 49 | 50 | for (int j = 0; j <= m; j++) 51 | if (used[j]) { 52 | u[p[j]] += delta; 53 | v[j] -= delta; 54 | } else { 55 | min_v[j] -= delta; 56 | } 57 | 58 | j0 = j1; 59 | } while (p[j0] != 0); 60 | 61 | do { 62 | int j1 = way[j0]; 63 | p[j0] = p[j1]; 64 | j0 = j1; 65 | } while (j0 != 0); 66 | } 67 | 68 | // Note that p[j] is the row assignment of column j (both 1-based). If p[j] = 0, the column is unassigned. 69 | assignment = p; 70 | return -v[0]; 71 | } 72 | 73 | -------------------------------------------------------------------------------- /Math/Binary Gaussian Elimination.cpp: -------------------------------------------------------------------------------- 1 | //Amin Anvari's solution to Shortest XOR Path problem 2 | #include 3 | using namespace std; 4 | typedef pair pii; 5 | #define L first 6 | #define R second 7 | const int maxn = 1e5, maxl = 31; 8 | bool mark[maxn]; 9 | vector adj[maxn]; 10 | vector all; 11 | int n, s, w[maxn], pat[maxn], b[maxn]; 12 | void dfs(int v,int par = -1) { 13 | mark[v] = true; 14 | for (int i = 0; i < adj[v].size(); i++) { 15 | int u = adj[v][i].L, e = adj[v][i].R, W = w[e]; 16 | if (!mark[u]) { 17 | pat[u] = pat[v] ^ W; 18 | dfs(u, e); 19 | } 20 | else if (e != par) 21 | all.push_back(pat[v] ^ pat[u] ^ W); 22 | } 23 | } 24 | int get(int x) { 25 | for (int i = maxl - 1; i >= 0; i--) 26 | if (x & (1 << i)) 27 | return i; 28 | return -1; 29 | } 30 | void add(int x) { 31 | for (int i = 0; i < s; i++) 32 | if (get(b[i]) != -1 && (x & (1 << get(b[i])))) 33 | x ^= b[i]; 34 | if (x == 0) 35 | return; 36 | for (int i = 0; i < s; i++) 37 | if (b[i] < x) 38 | swap(x, b[i]); 39 | b[s++] = x; 40 | } 41 | int GET(int x) { 42 | for (int i = 0; i < s; i++) 43 | if (get(b[i]) != -1 && (x & (1 << get(b[i])))) 44 | x ^= b[i]; 45 | return x; 46 | } 47 | int main() { 48 | ios_base::sync_with_stdio(false); 49 | int m; 50 | cin >> n >> m; 51 | for (int i = 0; i < m; i++) { 52 | int v, u; 53 | cin >> v >> u >> w[i]; 54 | v--, u--; 55 | adj[v].push_back(pii(u, i)); 56 | adj[u].push_back(pii(v, i)); 57 | } 58 | dfs(0); 59 | for (int i = 0; i < all.size(); i++) 60 | add(all[i]); 61 | cout << GET(pat[n - 1]) << endl; 62 | return 0; 63 | } -------------------------------------------------------------------------------- /Math/Discrete Logarithm Solver.cpp: -------------------------------------------------------------------------------- 1 | // discrete-logarithm, finding y for equation k = x^y % mod 2 | int discrete_logarithm(int x, int mod, int k) { 3 | if (mod == 1) return 0; 4 | int s = 1, g; 5 | for (int i = 0; i < 64; ++i) { 6 | if (s == k) return i; 7 | s = (1ll * s * x) % mod; 8 | } 9 | while ((g = gcd(x, mod)) != 1) { 10 | if (k % g) return -1; 11 | mod /= g; 12 | } 13 | static unordered_map M; M.clear(); 14 | int q = int(sqrt(double(euler(mod)))) + 1; // mod-1 is also okay 15 | for (int i = 0, b = 1; i < q; ++i) { 16 | if (M.find(b) == M.end()) M[b] = i; 17 | b = (1ll * b * x) % mod; 18 | } 19 | int p = fpow(x, q, mod); 20 | for (int i = 0, b = 1; i <= q; ++i) { 21 | int v = (1ll * k * inverse(b, mod)) % mod; 22 | if (M.find(v) != M.end()) { 23 | int y = i * q + M[v]; 24 | if (y >= 64) return y; 25 | } 26 | b = (1ll * b * p) % mod; 27 | } 28 | return -1; 29 | } -------------------------------------------------------------------------------- /Math/Euler Totient Function.cpp: -------------------------------------------------------------------------------- 1 | /* Returns the number of positive integers that are 2 | * relatively prime to n. As efficient as factor(). 3 | * REQUIRES: factor() 4 | * REQUIRES: sqrt() must work on Int. 5 | * REQUIRES: the constructor Int::Int( double ). 6 | **/ 7 | int phi( int n ) { 8 | vector< int > p; 9 | factor( n, p ); 10 | for( int i = 0; i < ( int )p.size(); i++ ) { 11 | if( i && p[i] == p[i - 1] ) continue; 12 | n /= p[i]; 13 | n *= p[i] - 1; 14 | } 15 | return n; 16 | } -------------------------------------------------------------------------------- /Math/Extended GCD.cpp: -------------------------------------------------------------------------------- 1 | template< class Int > 2 | struct Triple 3 | { 4 | Int d, x, y; 5 | Triple( Int q, Int w, Int e ) : d( q ), x( w ), y( e ) {} 6 | }; 7 | 8 | /* Given nonnegative a and b, computes d = gcd( a, b ) 9 | * along with integers x and y, such that d = ax + by 10 | * and returns the triple (d, x, y). 11 | * WARNING: needs a small modification to work on 12 | * negative integers (operator% fails). 13 | **/ 14 | 15 | template< class Int > 16 | Triple< Int > egcd( Int a, Int b ) 17 | { 18 | if( !b ) return Triple< Int >( a, Int( 1 ), Int( 0 ) ); 19 | Triple< Int > q = egcd( b, a % b ); 20 | return Triple< Int >( q.d, q.y, q.x - a / b * q.y ); 21 | } 22 | -------------------------------------------------------------------------------- /Math/Fibonacci Numbers Properties.tex: -------------------------------------------------------------------------------- 1 | Let A, B and n be integer numbers. 2 | 3 | 4 | \begin{equation} 5 | k = A - B 6 | \end{equation} 7 | 8 | 9 | \begin{equation} 10 | F_{A} F_{B} = F_{k + 1} F_{A} ^ 2 + F_{k} F_{A} F_{A - 1} 11 | \end{equation} 12 | 13 | \begin{equation} 14 | \sum_{i = 0}^{n} F_{i} ^ 2 = F_{n + 1} F_{n} 15 | \end{equation} 16 | 17 | $ev(n)$ = returns 1 if $n$ is even. 18 | 19 | \begin{equation} 20 | \sum_{i = 0}^{n} F_{i} F_{i + 1} = F_{n + 1} ^ {2} - ev(n) 21 | \end{equation} 22 | 23 | \begin{equation} 24 | \sum_{i = 0}^{n} F_{i} F_{i - 1} = \sum_{i = 0}^{n - 1} F_{i} F_{i + 1} 25 | \end{equation} -------------------------------------------------------------------------------- /Math/Linear Diophantine Equation Solver.cpp: -------------------------------------------------------------------------------- 1 | /* Solves integer equations of the form ax + by = c 2 | * for integers x and y. Returns a triple containing 3 | * the answer (in .x and .y) and a flag (in .d). 4 | * If the returned flag is zero, then there are no 5 | * solutions. Otherwise, there is an infinite number 6 | * of solutions of the form 7 | * x = t.x + k * b / t.d, 8 | * y = t.y - k * a / t.d; 9 | * where t is the returned triple, and k is any 10 | * integer. 11 | * REQUIRES: struct Triple, egcd 12 | **/ 13 | template< class Int > 14 | Triple< Int > ldioph( Int a, Int b, Int c ) { 15 | Triple< Int > t = egcd( a, b ); 16 | if( c % t.d ) return Triple< Int >( 0, 0, 0 ); 17 | t.x *= c / t.d; t.y *= c / t.d; 18 | return t; 19 | } 20 | -------------------------------------------------------------------------------- /Math/Maximum XOR (SGU 275).cpp: -------------------------------------------------------------------------------- 1 | const int B= 62; 2 | ll a[B+1]; 3 | void add(ll x){ 4 | for(int i=B;i>=0;i--){ 5 | ll v= (1ll << i); 6 | if(v & x){ 7 | if(a[i]) 8 | x^= a[i]; 9 | else{ 10 | a[i] = x; 11 | break; 12 | } 13 | } 14 | } 15 | } 16 | ll find_ans(){ 17 | ll ans = 0; 18 | for(int i=B;i>=0;i--){ 19 | ll v= (1ll << i); 20 | if(a[i] && (v & ans)==0) 21 | ans ^= a[i]; 22 | } 23 | return ans; 24 | } 25 | int main(){ 26 | int n; 27 | cin>>n; 28 | while(n--){ 29 | ll x; 30 | cin>>x; 31 | add(x); 32 | } 33 | cout< 8 | vector< Int > msolve( Int a, Int b, Int n ) { 9 | if( n < 0 ) n = -n; 10 | Triple< Int > t = egcd( a, n ); 11 | vector< Int > r; 12 | if( b % t.d ) return r; 13 | Int x = ( b / t.d * t.x ) % n; 14 | if( x < Int( 0 ) ) x += n; 15 | for( Int i = 0; i < t.d; i++ ) 16 | r.push_back( ( x + i * n / t.d ) % n ); 17 | return r; 18 | } 19 | -------------------------------------------------------------------------------- /Math/Number of Divisors.cpp: -------------------------------------------------------------------------------- 1 | /* Returns the number of positive divisors of n. 2 | * Complexity: about O(sqrt(n)). 3 | * REQUIRES: factor() 4 | * REQUIRES: sqrt() must work on Int. 5 | * REQUIRES: the constructor Int::Int( double ). 6 | **/ 7 | template< class Int > 8 | Int divisors( Int n ) { 9 | vector< Int > f; 10 | factor( n, f ); 11 | int k = f.size(); 12 | vector< Int > table( k + 1, Int( 0 ) ); 13 | table[k] = Int( 1 ); 14 | 15 | for( int i = k - 1; i >= 0; i-- ) { 16 | table[i] = table[i + 1]; 17 | for( int j = i + 1; ; j++ ) 18 | if( j == k || f[j] != f[i] ) 19 | { table[i] += table[j]; break; } 20 | } 21 | 22 | return table[0]; 23 | } 24 | -------------------------------------------------------------------------------- /Math/Prime Factors in n Factorial.cpp: -------------------------------------------------------------------------------- 1 | using namespace std; 2 | typedef long long ll; 3 | typedef pair pii; 4 | vector v; 5 | //////////// bozorgtarin i b shekli k N!%k^i==0 6 | void fact(ll n) { 7 | ll x = 2; 8 | while (x * x <= n) 9 | { 10 | ll num = 0; 11 | while (n % x == 0) { 12 | num++; 13 | n /= x; 14 | } 15 | if (num) v.push_back(MP(x, num)); 16 | x++; 17 | if (n == 1ll) break; 18 | } 19 | if(n > 1) v.push_back(MP(n, 1)); 20 | } 21 | 22 | ll getfact(ll n) { 23 | ll ret = n; 24 | Rep(i, v.size()) { 25 | ll k = v[i].first; 26 | ll cnt = 0; 27 | ll t = n; 28 | while (k <= n) { 29 | cnt += n / k; 30 | n /= k; 31 | } 32 | n = t; 33 | ret = min(ret, cnt / v[i].second); 34 | } 35 | return ret; 36 | } 37 | 38 | int main() { 39 | int tc; 40 | ll n, k; 41 | cin >> tc; 42 | while (tc--) { 43 | v.clear(); 44 | cin >> n >> k; 45 | fact(k); 46 | cout << getfact(n) << endl; 47 | } 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /Math/Reduced Row Echelon Form.cpp: -------------------------------------------------------------------------------- 1 | // Reduced row echelon form via Gauss-Jordan elimination 2 | // with partial pivoting. This can be used for computing 3 | // the rank of a matrix. 4 | // 5 | // Running time: O(n^3) 6 | // 7 | // INPUT: a[][] = an nxm matrix 8 | // 9 | // OUTPUT: rref[][] = an nxm matrix (stored in a[][]) 10 | // returns rank of a[][] 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | using namespace std; 17 | 18 | const double EPSILON = 1e-10; 19 | 20 | typedef double T; 21 | typedef vector VT; 22 | typedef vector VVT; 23 | 24 | int rref(VVT &a) { 25 | int n = a.size(); 26 | int m = a[0].size(); 27 | int r = 0; 28 | for (int c = 0; c < m && r < n; c++) { 29 | int j = r; 30 | for (int i = r + 1; i < n; i++) 31 | if (fabs(a[i][c]) > fabs(a[j][c])) j = i; 32 | if (fabs(a[j][c]) < EPSILON) continue; 33 | swap(a[j], a[r]); 34 | 35 | T s = 1.0 / a[r][c]; 36 | for (int j = 0; j < m; j++) a[r][j] *= s; 37 | for (int i = 0; i < n; i++) if (i != r) { 38 | T t = a[i][c]; 39 | for (int j = 0; j < m; j++) a[i][j] -= t * a[r][j]; 40 | } 41 | r++; 42 | } 43 | return r; 44 | } 45 | 46 | int main() { 47 | const int n = 5, m = 4; 48 | double A[n][m] = { 49 | {16, 2, 3, 13}, 50 | { 5, 11, 10, 8}, 51 | { 9, 7, 6, 12}, 52 | { 4, 14, 15, 1}, 53 | {13, 21, 21, 13}}; 54 | VVT a(n); 55 | for (int i = 0; i < n; i++) 56 | a[i] = VT(A[i], A[i] + m); 57 | 58 | int rank = rref(a); 59 | 60 | // expected: 3 61 | cout << "Rank: " << rank << endl; 62 | 63 | // expected: 1 0 0 1 64 | // 0 1 0 3 65 | // 0 0 1 -3 66 | // 0 0 0 3.10862e-15 67 | // 0 0 0 2.22045e-15 68 | cout << "rref: " << endl; 69 | for (int i = 0; i < 5; i++) { 70 | for (int j = 0; j < 4; j++) 71 | cout << a[i][j] << ' '; 72 | cout << endl; 73 | } 74 | } -------------------------------------------------------------------------------- /Math/Solving Recursive Functions.cpp: -------------------------------------------------------------------------------- 1 | //From "You Know Izad?" team cheat sheet 2 | /* 3 | a[i] = b[i] (for i <= k) 4 | a[i] = c[1]*a[i-1] + c[2]a[i-2] + ... + c[k]a[i-k] (for i > k) 5 | Given: 6 | b[1], b[2], ..., b[k] 7 | c[1], c[2], ..., c[k] 8 | a[N]=? 9 | */ 10 | typedef vector > matrix; 11 | int K; 12 | matrix mul(matrix A, matrix B){ 13 | matrix C(K+1, vector(K+1)); 14 | REP(i, K) REP(j, K) REP(k, K) 15 | C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % INF32; 16 | return C; 17 | } 18 | matrix pow(matrix A, ll p){ 19 | if (p == 1) return A; 20 | if (p % 2) return mul(A, pow(A, p-1)); 21 | matrix X = pow(A, p/2); 22 | return mul(X, X); 23 | } 24 | ll solve() { 25 | // base (initial) values 26 | vector F1(K+1); 27 | REP (i, K) 28 | cin >> F1[i]; 29 | matrix T(K+1, vector(K+1)); 30 | REP(i, K) { 31 | REP(j, K) { 32 | if(j == i + 1) T[i][j] = 1; 33 | else if(i == K) cin >> T[i][K - j + 1]; // multipliers 34 | else T[i][j] = 0; 35 | } 36 | } 37 | ll N; 38 | cin >> N; 39 | if (N == 1) return 1; 40 | T = pow(T, N-1); 41 | ll res = 0; 42 | REP(i, K) 43 | res = (res + T[1][i] * F1[i]) % INF32; // Mod Value 44 | return res; 45 | } 46 | int main() { 47 | cin >> K; 48 | cout << solve() << endl; 49 | } 50 | -------------------------------------------------------------------------------- /Other/FFT and Multiplication.cpp: -------------------------------------------------------------------------------- 1 | #define base complex 2 | void fft (vector & a, bool invert){ 3 | if (L(a) == 1) return; 4 | int n = L(a); 5 | vector a0(n / 2), a1(n / 2); 6 | for (int i = 0, j = 0; i < n; i += 2, ++j){ 7 | a0[j] = a[i]; 8 | a1[j] = a[i + 1]; 9 | } 10 | fft (a0, invert); 11 | fft (a1, invert); 12 | double ang = 2 * PI / n * (invert ? -1 : 1); 13 | base w(1), wn(cos(ang), sin(ang)); 14 | fore(i, 0, n / 2) { 15 | a[i] = a0[i] + w * a1[i]; 16 | 3 17 | a[i + n / 2] = a0[i] - w * a1[i]; 18 | if (invert) 19 | a[i] /= 2, a[i + n / 2] /= 2; 20 | w *= wn; 21 | } 22 | } 23 | void multiply (const vector &a, const vector & b, vector &res){ 24 | vector fa(all(a)), fb(all(b)); 25 | size_t n = 1; 26 | while (n < max(L(a), (L(b)))) n <<= 1; 27 | n <<= 1; 28 | fa.resize(n), fb.resize(n); 29 | fft(fa, false), fft(fb, false); 30 | fore(i, 0, n) 31 | fa[i] *= fb[i]; 32 | fft (fa, true); 33 | res.resize (n); 34 | fore(i, 0, n) 35 | res[i] = int (fa[i].real() + 0.5); 36 | } -------------------------------------------------------------------------------- /Other/Grundy.cpp: -------------------------------------------------------------------------------- 1 | // A function to Compute Grundy Number of 'n' 2 | // Only this function varies according to the game 3 | int calculateGrundy(int n) { 4 | if (n == 0) 5 | return (0); 6 | unordered_set Set; // A Hash Table 7 | for (int i=0; i<=n-1; i++) 8 | Set.insert(calculateGrundy(i)); 9 | return (calculateMex(Set)); 10 | } -------------------------------------------------------------------------------- /Other/Miller-Rabin primality test.cpp: -------------------------------------------------------------------------------- 1 | using u64 = uint64_t; 2 | using u128 = __uint128_t; 3 | 4 | u64 binpower(u64 base, u64 e, u64 mod) { 5 | u64 result = 1; 6 | base %= mod; 7 | while (e) { 8 | if (e & 1) 9 | result = (u128)result * base % mod; 10 | base = (u128)base * base % mod; 11 | e >>= 1; 12 | } 13 | return result; 14 | } 15 | 16 | bool check_composite(u64 n, u64 a, u64 d, int s) { 17 | u64 x = binpower(a, d, n); 18 | if (x == 1 || x == n - 1) 19 | return false; 20 | for (int r = 1; r < s; r++) { 21 | x = (u128)x * x % n; 22 | if (x == n - 1) 23 | return false; 24 | } 25 | return true; 26 | }; 27 | 28 | bool millerRabin(u64 n) { // returns true if n is prime, else returns false. 29 | if (n < 2) 30 | return false; 31 | 32 | int r = 0; 33 | u64 d = n - 1; 34 | while ((d & 1) == 0) { 35 | d >>= 1; 36 | r++; 37 | } 38 | 39 | for (u64 a : {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}) { 40 | if (n == a) 41 | return true; 42 | if (check_composite(n, a, d, r)) 43 | return false; 44 | } 45 | return true; 46 | } -------------------------------------------------------------------------------- /Other/faster FFT.cpp: -------------------------------------------------------------------------------- 1 | const double PI = acos(-1); 2 | #define base complex 3 | int lg_n; 4 | int rev [maxn * 20]; 5 | vector polies[maxn]; 6 | int reverse(int num ,int lll) { 7 | return rev[num]; 8 | } 9 | 10 | void fft(vector & a, bool invert) { 11 | int n = a.size(); 12 | 13 | 14 | for (int i = 0; i < n; i++) { 15 | if (i < reverse(i, lg_n)) 16 | swap(a[i], a[reverse(i, lg_n)]); 17 | } 18 | 19 | for (int len = 2; len <= n; len <<= 1) { 20 | double ang = 2 * PI / len * (invert ? -1 : 1); 21 | base wlen(cos(ang), sin(ang)); 22 | for (int i = 0; i < n; i += len) { 23 | base w(1); 24 | for (int j = 0; j < len / 2; j++) { 25 | base u = a[i+j], v = a[i+j+len/2] * w; 26 | a[i+j] = u + v; 27 | a[i+j+len/2] = u - v; 28 | w *= wlen; 29 | } 30 | } 31 | } 32 | 33 | if (invert) { 34 | for (base & x : a) 35 | x /= n; 36 | } 37 | } 38 | 39 | 40 | void multiply (int u , int v){ 41 | int n = 1; 42 | while (n < max(L(a) , L(b))) { 43 | n <<= 1; 44 | } 45 | n <<= 1; 46 | lg_n = 0; 47 | while ((1 << lg_n) < n) 48 | lg_n++; 49 | 50 | for (int i=0; i q; 16 | last[1]=1; 17 | f[1]=1; 18 | 19 | for(int c=0;c<26;c++){ 20 | if(!nxt[c][1]) 21 | nxt[c][1] = 1; 22 | else{ 23 | f[nxt[c][1]]= 1; 24 | q.push(nxt[c][1]); 25 | } 26 | } 27 | 28 | while(q.size()){ 29 | int v = q.front(); 30 | q.pop(); 31 | if(label[f[v]]) 32 | last[v]= f[v]; 33 | else 34 | last[v]= last[f[v]]; 35 | for(int c=0;c<26;c++){ 36 | if(!nxt[c][v]) 37 | nxt[c][v] = nxt[c][f[v]]; 38 | else{ 39 | f[nxt[c][v]]= nxt[c][f[v]]; 40 | q.push(nxt[c][v]); 41 | } 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /String/Kmp.cpp: -------------------------------------------------------------------------------- 1 | f[0]=f[1]=0; //f[length] s is text and t is pattern 2 | int cur= 0,ans=0; 3 | for(int i=1;i i) ? min(R-i, P[i_mirror]) : 0; 20 | // Attempt to expand palindrome centered at i 21 | while (T[i + 1 + P[i]] == T[i - 1 - P[i]]) 22 | P[i]++; 23 | // If palindrome centered at i expand past R, 24 | // adjust center based on expanded palindrome. 25 | if (i + P[i] > R) { 26 | C = i; 27 | R = i + P[i]; 28 | } 29 | } 30 | // Find the maximum element in P. 31 | int maxLen = 0; 32 | int centerIndex = 0; 33 | for (int i = 1; i < n-1; i++) { 34 | if (P[i] > maxLen) { 35 | maxLen = P[i]; 36 | centerIndex = i; 37 | } 38 | } 39 | delete[] P; 40 | 41 | return s.substr((centerIndex - 1 - maxLen)/2, maxLen); 42 | } 43 | -------------------------------------------------------------------------------- /String/Non Cyclic Suffix Array.cpp: -------------------------------------------------------------------------------- 1 | const int N = 4e5 + 5, LOG = 20; 2 | int n, r[N][LOG]; 3 | string s; 4 | void radix_sort(vector > &a) { 5 | int n = a.size(); 6 | const int c = 5; 7 | { 8 | vector cnt(N + 10, 0), pos(N + 10); 9 | vector > a_new(n); 10 | for (auto x : a) 11 | cnt[x.first.second + c]++; 12 | pos[0] = 0; 13 | for (int i = 1; i <= N + c; i++) 14 | pos[i] = pos[i - 1] + cnt[i - 1]; 15 | for (auto x : a) { 16 | int i = x.first.second + c; 17 | a_new[pos[i]] = x; 18 | pos[i]++; 19 | } 20 | a = a_new; 21 | } 22 | { 23 | vector cnt(N + 10, 0), pos(N + 10); 24 | vector > a_new(n); 25 | for (auto x : a) 26 | cnt[x.first.first + c]++; 27 | pos[0] = 0; 28 | for (int i = 1; i <= N + c; i++) 29 | pos[i] = pos[i - 1] + cnt[i - 1]; 30 | for (auto x : a) { 31 | int i = x.first.first + c; 32 | a_new[pos[i]] = x; 33 | pos[i]++; 34 | } 35 | a = a_new; 36 | } 37 | } 38 | 39 | int lcp(int x, int y) { 40 | int ans = 0; 41 | for (int i = LOG - 1; ~i; i--) { 42 | if(y + (1 << i) > n) 43 | continue; 44 | if(r[x][i] == r[y][i]) 45 | x += (1 << i), y += (1 << i), ans += (1 << i); 46 | } 47 | return ans; 48 | } 49 | 50 | int main() { 51 | ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0); 52 | cin >> s; 53 | n = s.size(); 54 | for (int i = 0; i < n; i++) 55 | r[i][0] = (int)s[i]; 56 | for (int j = 0; j < LOG - 1; j++) { 57 | vector > a(n); 58 | for (int i = 0; i < n; i++) { 59 | if(i + (1 << j) < n) 60 | a[i] = {{r[i][j], r[i + (1 << j)][j]}, i}; 61 | else 62 | a[i] = {{r[i][j], -1}, i}; 63 | } 64 | radix_sort(a); 65 | r[a[0].second][j + 1] = 0; 66 | for (int i = 1; i < n; i++) { 67 | if(a[i].first == a[i - 1].first) 68 | r[a[i].second][j + 1] = r[a[i - 1].second][j + 1]; 69 | else 70 | r[a[i].second][j + 1] = i; 71 | } 72 | } 73 | vector vec; 74 | for (int i = 0; i <= n; i++) 75 | vec.push_back({r[i][LOG - 1], -i}); 76 | sort(vec.begin(), vec.end()); 77 | for (auto x : vec) 78 | cout << x.second * -1 << " "; 79 | cout << "\n"; 80 | } -------------------------------------------------------------------------------- /String/Suffix-Array.cpp: -------------------------------------------------------------------------------- 1 | //minimum cyclic shift using O(nlogn) suffix array 2 | const int M=2e5+137,ML=18; 3 | int n,lev,rnk[ML][M],ord[M]; 4 | 5 | bool cmp(int x, int y){ 6 | if(rnk[lev][x] != rnk[lev][y]) 7 | return rnk[lev][x] < rnk[lev][y]; 8 | return rnk[lev][(x+(1<=0;k--){ 17 | //for cyclic check ans<=n and use mod for i and j 18 | if((1< radix[2][M]; 30 | string minimum_cyclic_shift(string s){ 31 | //to make non cyclic: s+="$" $ is smaller than most of characters 32 | n= s.size(); 33 | for(int i=0;i 2 | #define NV N[v] 3 | string s; 4 | struct node { 5 | int p, b, e, link; 6 | /*map< char, int > children;*/ 7 | vector< pci > children; 8 | node( int _p, int _b, int _e ) { p = _p, b = _b, e = _e, link = -1; } 9 | void addChild( pci a ) { 10 | children.push_back( a ); 11 | } 12 | void changeChild( pci a ) { 13 | //children[a.first] = a.second; 14 | for( int i = 0; i < children.size(); i++ ) { 15 | if( children[i].first == a.first ) { 16 | children[i].second = a.second; 17 | return; 18 | } 19 | } 20 | } 21 | int length() { return e - b + 1; } 22 | bool gotoNext( char c, int &nv, int &nd) { 23 | if( nd < e - b ) { 24 | if( s[b + nd + 1] == c ) { 25 | nd++; 26 | return true; 27 | } 28 | } else { 29 | for( int i = 0; i < children.size(); i++ ) { 30 | if( children[i].first == c ) { 31 | nv = children[i].second, nd = 0; 32 | return true; 33 | } 34 | } 35 | } 36 | return false; 37 | } 38 | }; 39 | vector< node > N; 40 | void add2Tree( ) { 41 | N.clear(); 42 | N.push_back( node( -1, -1, -1 ) ); 43 | N[0].link = 0; 44 | int j = 0, pp = -1, v = 0, d = 0; 45 | for( int i = 0; i < s.length(); i++ ) { 46 | pp = -1; 47 | for( ; j <= i; j++ ) { 48 | if( NV.gotoNext( s[i], v, d ) ) { 49 | if( pp != -1 ) N[pp].link = NV.p; 50 | break; 51 | } else { 52 | int id = N.size(); 53 | if( d < NV.e - NV.b ) { 54 | if( pp != -1 ) N[pp].link = id; 55 | N.push_back( node( NV.p, NV.b, NV.b + d ) ); 56 | N[NV.p].changeChild( pci( s[NV.b], id ) ); 57 | NV.b += d + 1; 58 | NV.p = pp = id; 59 | N[id].addChild( pci( s[NV.b], v ) ); 60 | int len = N[id].p ? d + 1 : d; 61 | v = N[N[id].p].link; 62 | d = NV.length() - 1; 63 | while( len ) { 64 | int temp = v; 65 | N[temp].gotoNext( s[i - len] , v, d ); 66 | int l = NV.length(); 67 | if( len <= l ) { 68 | d = len - 1; 69 | break; 70 | } 71 | d = l - 1; 72 | len -= l; 73 | } 74 | id++; 75 | } else { 76 | if( pp != -1 ) N[pp].link = v; 77 | pp = v; 78 | v = NV.link; 79 | d = NV.length() - 1; 80 | } 81 | N[pp].addChild( pci( s[i], id ) ); 82 | N.push_back( node( pp, i, s.length() - 1 ) ); 83 | } 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /String/Z Algorithm.cpp: -------------------------------------------------------------------------------- 1 | // Z[i] => max len perfixi az s k az khuneye i e S shoru mishe 2 | 3 | int L = 0, R = 0; 4 | n=s.size(); 5 | for (int i = 1; i < n; i++) 6 | { 7 | if (i > R) { 8 | L = R = i; 9 | while (R < n && s[R-L] == s[R]) R++; 10 | z[i] = R-L; R--; 11 | } 12 | else 13 | { 14 | int k = i-L; 15 | if (z[k] < R-i+1) z[i] = z[k]; 16 | else 17 | { 18 | L = i; 19 | while (R < n && s[R-L] == s[R]) R++; 20 | z[i] = R-L; R--; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /String/hash.cpp: -------------------------------------------------------------------------------- 1 | const ll M=2e5+137,T= 4; 2 | const ll bas[]= {31, 53, 727, 727}; 3 | const ll mod[]= {(ll)1e9+7, (ll)1e9+9, (ll)1e9+7, (ll)1e9+9}; 4 | ll pw[T][M],hs[T][M],n; 5 | 6 | ll substr(int t, int l, int r){ //1-based closed-closed range 7 | return (hs[t][r] -(hs[t][l-1]* pw[t][r-l+1]%mod[t]) + mod[t])%mod[t]; 8 | } 9 | ll substrRev(int t, int l, int r){ 10 | return (rhs[t][l] -(rhs[t][r+1]* pw[t][r-l+1]%mod[t]) + mod[t])%mod[t]; 11 | } 12 | 13 | string s; 14 | bool cmp(int l1, int l2, int sz){ 15 | for(int i=0;i0;i--){ 41 | rhs[j][i]= (rhs[j][i+1]*bas[j]+(str[i-1]-'a'+1)) %mod[j]; 42 | } 43 | } 44 | } 45 | 46 | int lcp(int x, int y){ 47 | int l= 1, r=n, m; 48 | if(s[x-1] != s[y-1]) 49 | return 0; 50 | 51 | bool is=1; 52 | while(l 2 | #include //header with rope 3 | using namespace std; 4 | using namespace __gnu_cxx; //namespace with rope and some additional stuff 5 | int main(){ 6 | rope v; //use as usual STL container 7 | int n, m; 8 | cin >> n >> m; 9 | for(int i = 1; i <= n; ++i) 10 | v.push_back(i); //initialization 11 | string p ; 12 | int idx; 13 | cin>>p>>idx; 14 | for(i=1;i<=p.size();i++){ 15 | s.insert(i + idx -1 , p[i-1]); 16 | } 17 | int l, r; 18 | for(int i = 0; i < m; ++i) 19 | { 20 | cin >> l >> r; 21 | --l, --r; 22 | rope cur = v.substr(l, r - l + 1); 23 | v.erase(l, r - l + 1); 24 | v.insert(v.mutable_begin(), cur); 25 | 26 | } 27 | for(rope ::iterator it = v.mutable_begin(); it != v.mutable_end(); ++it) 28 | cout << *it << " "; 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /Tips, Tricks and Theorems/Bitset.cpp: -------------------------------------------------------------------------------- 1 | bitset b=st; 2 | st.count(); //number of 1 bits 3 | st.all() st.any() st.none() 4 | for(int j=b._Find_first();j<=s;j=b._Find_next(j)) -------------------------------------------------------------------------------- /Tips, Tricks and Theorems/Burnside's lemma.tex: -------------------------------------------------------------------------------- 1 | In the following, let G be a finite group that acts on a set X. For each g in G let Xg denote the set of elements in X that are fixed by g (also said to be left invariant by g), i.e. X^g = \{ x \in X | g.x = x \}. 2 | 3 | Burnside's lemma asserts the following formula for the number of orbits, denoted {\displaystyle |X/G| }: 4 | 5 | 6 | {\displaystyle |X/G|={\frac {1}{|G|}}\sum _{g\in G}|X^{g}|.} |X/G|={\frac {1}{|G|}}\sum _{{g\in G}}|X^{g}|. 7 | 8 | 9 | Thus the number of orbits (a natural number or +infinity) is equal to the average number of points fixed by an element of G (which is also a natural number or infinity). If G is infinite, the division by G may not be well-defined; in this case the following statement in cardinal arithmetic holds: 10 | 11 | 12 | {\displaystyle |G||X/G|=\sum _{g\in G}|X^{g}|.} 13 | 14 | 15 | Example application: 16 | 17 | The number of rotationally distinct colourings of the faces of a cube using three colours can be determined from this formula as follows. 18 | 19 | Let X be the set of 3*3*3*3*3*3 possible face colour combinations that can be applied to a cube in one particular orientation, and let the rotation group G of the cube act on X in the natural manner. Then two elements of X belong to the same orbit precisely when one is simply a rotation of the other. The number of rotationally distinct colourings is thus the same as the number of orbits and can be found by counting the sizes of the fixed sets for the 24 elements of G. 20 | 21 | 22 | - one identity element which leaves all 3*3*3*3*3*3 elements of X unchanged 23 | 24 | - six 90-degree face rotations, each of which leaves 3*3*3 of the elements of X unchanged 25 | 26 | - three 180-degree face rotations, each of which leaves 3*3*3*3 of the elements of X unchanged 27 | 28 | - eight 120-degree vertex rotations, each of which leaves 3*3 of the elements of X unchanged 29 | 30 | - six 180-degree edge rotations, each of which leaves 3*3*3 of the elements of X unchanged 31 | 32 | The average fix size is thus 33 | 34 | {\displaystyle {\frac {1}{24}}\left(3^{6}+6\cdot 3^{3}+3\cdot 3^{4}+8\cdot 3^{2}+6\cdot 3^{3}\right)=57.} 35 | 36 | Hence there are 57 rotationally distinct colourings of the faces of a cube in three colours. In general, the number of rotationally distinct colorings of the faces of a cube in n colors is given by 37 | 38 | {\displaystyle {\frac {1}{24}}\left(n^{6}+3n^{4}+12n^{3}+8n^{2}\right).} 39 | -------------------------------------------------------------------------------- /Tips, Tricks and Theorems/C++ Tricks.cpp: -------------------------------------------------------------------------------- 1 | cout << fixed << setprecision(7) << M_PI << endl; // 3.1415927 2 | cout << scientific << M_PI << endl; // 3.1415927e+000 3 | int x=15, y=12094; 4 | cout << setbase(10) << x << " " << y << endl; // 15 12094 5 | cout << setbase(8) << x << " " << y << endl; // 17 27476 6 | cout << setbase(16) << x << " " << y << endl; // f 2f3e 7 | x=5; y=9; 8 | cout< 1-based 10 | • Division by zero. Integer division a/(double)b 11 | • Stack overflow (DFS on 1e5) 12 | • Infinite loop? 13 | • array bound check. maxn or x*maxn 14 | • Dont use .size()-1 ! 15 | • “(int)-3 < (unsigned int) 2” is false! 16 | • Check copy-pasted codes! 17 | • Be careful about -0.0 18 | • Remove debug info! 19 | • Output format: Spaces at the end of line. Blank lines. View the output in VIM if necessary 20 | • Add eps to double before getting floor or round 21 | • Convex Hull: Check if points are collinear 22 | • Geometry: Distance may not overflow, but its square or cross may does 23 | • Implementation: be careful about numbers limits to fit in long long in implementation problems with no given limits 24 | • If the problem has too many accepts maybe you are thinking too hard! 25 | • Apply the simplest, random, or ternary search with block min/max at the last hour if you have not any solutions -------------------------------------------------------------------------------- /Tips, Tricks and Theorems/Dilworth Theorem.cpp: -------------------------------------------------------------------------------- 1 | Let S be a finite partially ordered set. The size of a maximal antichain equals the size of a minimal chain cover of S. This is called the Dilworth’s theorem. 2 | 3 | The width of a finite partially ordered set S is the maximum size of an antichain in S. In other words, the width of a finite partially ordered set S is the minimum number of chains needed to cover S, i.e. the minimum number of chains such that any element of S is in at least one of the chains. 4 | 5 | Definition of chain : A chain in a partially ordered set is a subset of elements which are all comparable to each other. 6 | Definition of antichain : An antichain is a subset of elements, no two of which are comparable to each other. -------------------------------------------------------------------------------- /Tips, Tricks and Theorems/Gallai Theorem.cpp: -------------------------------------------------------------------------------- 1 | a(G) := max{|C| | C is a stable set}, 2 | b(G) := min{|W| | W is a vertex cover}, 3 | c(G) := max{|M| | M is a matching}, 4 | d(G) := min{|F| | F is an edge cover}. 5 | Gallai’s theorem: If G = (V, E) is a graph without isolated vertices, then 6 | a(G) + b(G) = |V| = c(G) + d(G). 7 | -------------------------------------------------------------------------------- /Tips, Tricks and Theorems/Konig Theorem.cpp: -------------------------------------------------------------------------------- 1 | König theorem can be proven in a way that provides additional useful information beyond just its truth: the proof provides a way of constructing a minimum vertex cover from a maximum matching. Let {G=(V,E)} be a bipartite graph, and let the vertex set { V} be partitioned into left set { L} and right set { R}. Suppose that { M} is a maximum matching for { G}. No vertex in a vertex cover can cover more than one edge of { M} (because the edge half-overlap would prevent { M} from being a matching in the first place), so if a vertex cover with { |M|} vertices can be constructed, it must be a minimum cover. 2 | To construct such a cover, let { U} be the set of unmatched vertices in { L} (possibly empty), and let { Z} be the set of vertices that are either in { U} or are connected to { U} by alternating paths (paths that alternate between edges that are in the matching and edges that are not in the matching). Let 3 | { K=(L - Z) Union (R Intersect Z).} 4 | Every edge { e} in { E} either belongs to an alternating path (and has a right endpoint in { K}), or it has a left endpoint in { K}. For, if { e} is matched but not in an alternating path, then its left endpoint cannot be in an alternating path (for such a path could only end at { e}) and thus belongs to { L- Z}. Alternatively, if { e} is unmatched but not in an alternating path, then its left endpoint cannot be in an alternating path, for such a path could be extended by adding { e} to it. Thus, { K} forms a vertex cover. 5 | Additionally, every vertex in { K} is an endpoint of a matched edge. For, every vertex in { L - Z} is matched because Z is a superset of U, the set of unmatched left vertices. And every vertex in { R intersect Z} must also be matched, for if there existed an alternating path to an unmatched vertex then changing the matching by removing the matched edges from this path and adding the unmatched edges in their place would increase the size of the matching. However, no matched edge can have both of its endpoints in { K}. Thus, { K} is a vertex cover of cardinality equal to { M}, and must be a minimum vertex cover. 6 | -------------------------------------------------------------------------------- /Tips, Tricks and Theorems/Lucas Theorem.tex: -------------------------------------------------------------------------------- 1 | For non-negative integers $m$ and $n$ and a prime $p$, the following congruence relation holds: 2 | :$$\binom{m}{n}\equiv\prod_{i=0}^k\binom{m_i}{n_i}\pmod p,$$ 3 | where 4 | :$$m=m_kp^k+m_{k-1}p^{k-1}+\cdots +m_1p+m_0,$$ 5 | and 6 | :$$n=n_kp^k+n_{k-1}p^{k-1}+\cdots +n_1p+n_0$$ 7 | are the base $p$ expansions of $m$ and $n$ respectively. This uses the convention that $\tbinom{m}{n} = 0$ if $m \le n$. 8 | -------------------------------------------------------------------------------- /Tips, Tricks and Theorems/Minimum Path Cover in DAG.tex: -------------------------------------------------------------------------------- 1 | Given a directed acyclic graph $G = (V, E)$, we are to find the minimum number 2 | of vertex-disjoint paths to cover each vertex in V. 3 | 4 | We can construct a bipartite graph $G' = (Vout \cup Vin, E' )$ from $G$, where : \\ 5 | 6 | $$ Vout = \{ v \in V : v~has~positive~out-degree \} $$ 7 | $$ Vin = \{ v \in V : v~has~positive~in-degree \} $$ 8 | $$ E' = \{ (u,v) \in Vout \times Vin : (u,v) \in E \} $$ 9 | 10 | Then it can be shown, via König's theorem, that G' has a matching of size m if 11 | and only if there exists $n-m$ vertex-disjoint paths that cover each vertex in G, 12 | where $n$ is the number of vertices in G and $m$ is the maximum cardinality 13 | bipartite mathching in G'. \\ 14 | 15 | Therefore, the problem can be solved by finding the maximum cardinality matching in G' instead. 16 | 17 | \textbf{NOTE:} If the paths are note necesarily disjoints, find the transitive closure 18 | and solve the problem for disjoint paths. 19 | -------------------------------------------------------------------------------- /Tips, Tricks and Theorems/Planar Graph (Euler).tex: -------------------------------------------------------------------------------- 1 | Euler's formula states that if a finite, connected, planar graph is drawn in the plane without any edge intersections, and $v$ is the number of vertices, $e$ is the number of edges and $f$ is the number of faces (regions bounded by edges, including the outer, infinitely large region), then: 2 | 3 | $$ f + v = e + 2$$ 4 | 5 | 6 | It can be extended to non connected planar graphs with $c$ connected components: 7 | 8 | $$ f + v = e + c + 1$$ 9 | -------------------------------------------------------------------------------- /Tips, Tricks and Theorems/Triangles.tex: -------------------------------------------------------------------------------- 1 | Let a, b, c be length of the three sides of a triangle. 2 | 3 | $$ p = (a + b + c) * 0.5 $$ 4 | 5 | The inradius is defined by: 6 | 7 | $$ iR = \sqrt{\frac{(p - a)(p - b)(p - c)}{p}}$$ 8 | 9 | The radius of its circumcircle is given by the formula: 10 | 11 | $$ cR = \frac{abc}{\sqrt{(a + b + c)(a + b - c)(a + c - b)(b + c - a)}}$$ 12 | -------------------------------------------------------------------------------- /Tips, Tricks and Theorems/Uniform Random Number Generator.cpp: -------------------------------------------------------------------------------- 1 | using namespace std; 2 | //seed: 3 | random_device rd; 4 | mt19937 gen(rd()); 5 | uniform_int_distribution<> dis(0, n - 1); 6 | //generate: 7 | int r = dis(gen); -------------------------------------------------------------------------------- /notebook.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mohammadreza-mz/icpc-cheatsheet/6113773686f70a9311515895682ef3da8b282367/notebook.pdf --------------------------------------------------------------------------------