├── Codes ├── .cproject ├── .gitignore ├── .project ├── CHIVO DELUXE EDITION (ACM_2012).pdf ├── DynamicProgramming │ ├── ConvexHullTrick.cpp │ ├── ConvexHullTrickSet.cpp │ ├── ConvexHullTrickSet.cpp (Underwork) │ ├── DynamicConvexHullTrick.cpp │ ├── Histogram.cpp │ ├── InversionCount.cpp │ ├── LIS.cpp │ ├── Partitions.cpp │ ├── PersistentConvexHullTrick.cpp │ └── SubsetSum.cpp ├── Geometry │ ├── AngleBetweenVectors.cpp │ ├── BestCurveBuffer.cpp │ ├── ConvexHullUL.cpp │ ├── Generic │ │ ├── AllLineIntersections.cpp │ │ ├── InsideSimplePolygon.cpp │ │ ├── Line.cpp │ │ ├── Point.cpp │ │ ├── Polygon.cpp │ │ └── VectorMethods.cpp │ ├── Geometry.cpp │ ├── InsideConvex.cpp │ ├── PointStruct.cpp │ ├── PointToPolygonProjector.cpp │ ├── SegmentIntercect.cpp │ └── ThirdPointLeft.cpp ├── Graph │ ├── 2-SAT.cpp │ ├── ConnectedComponnents.cpp │ ├── CountMinimumSpanningTree.cpp │ ├── CountSpanningTree.cpp │ ├── EulerianPathAndCycle.cpp │ ├── Flow │ │ └── MinCostMaxFlow[AdjList].cpp │ ├── HopcroftCarp.cpp │ ├── HungarianAlgorithm.cpp │ ├── MaxFlow[Dinics-EdgeList].cpp │ ├── MaximumMatching.cpp │ ├── NOT_WORKING_MincostMaxflow[AdjMatrix].cpp │ ├── README.md │ └── VertexCover.cpp ├── Math │ ├── BigConvolutionFFT.cpp │ ├── BigInteger.cpp │ ├── BigPrimes.cpp │ ├── BitVector.cpp │ ├── Convolution.java │ ├── DiscreteLogarithm-PollardRho.cpp │ ├── DiscreteLogarithm.cpp │ ├── EducationalFFT.cpp │ ├── Equations │ │ ├── BitGauss.cpp │ │ ├── GaussDouble.cpp │ │ └── VectorSpace.cpp │ ├── Factors.cpp │ ├── FastestFFT.cpp │ ├── Fibo.cpp │ ├── Fourier.cpp │ ├── Fourier2.cpp │ ├── Gauss.cpp │ ├── GaussDouble.css │ ├── GenericMatrix.cpp │ ├── LinearCongruence.cpp │ ├── LinearSieve.cpp │ ├── Matrix.cpp │ ├── ModInt.cpp │ ├── ModIntShort.cpp │ ├── NCR.cpp │ ├── NTT.cpp │ ├── NaiveCycleFinding.cpp │ ├── Polinomial.cpp │ └── PrimitiveRoot.cpp ├── String │ ├── AhoCorasick.cpp │ ├── CompressedTrie.cpp │ ├── Hash.cpp │ ├── KMP.cpp │ ├── Manachers.cpp │ ├── NextLetter.cpp │ ├── RawHash.cpp │ ├── StringUtils.cpp │ ├── SubstringHash.cpp │ ├── SuffixArray(NlogN).cpp │ ├── SuffixArray.cpp │ ├── SuffixArrayShort.cpp │ ├── SuffixAutomaton.cpp │ ├── SuffixTree(uses SuffixArray).cpp │ └── Trie.cpp ├── Trees │ ├── BalancedTrees │ │ ├── VectorTreap.cpp │ │ └── VectorTreapUpdate.cpp │ ├── BlockedFenwick2D.cpp │ ├── CentroidDecompShort.cpp │ ├── CentroidDecomposition.cpp │ ├── CompressedFenwick2D.cpp │ ├── DinamycReversibleSegmentTree.cpp │ ├── DisjointSet.cpp │ ├── DynamicTrees │ │ ├── EulerTree.cpp │ │ ├── LinkCutTree.cpp │ │ └── UpdatableEulerTourTree.cpp │ ├── FEDisjointSet │ ├── FenwickTree.cpp │ ├── FragmentedTree.cpp │ ├── HLD.cpp │ ├── HeavyLightDecomposition.cpp │ ├── HeavyLightDecomposition_SegmentTree.cpp │ ├── ImplicitLazyPersistentSegmentTree.cpp │ ├── ImplicitTree2D.cpp │ ├── LCA.cpp │ ├── LinkCutTreeLab.cpp │ ├── Persistent │ │ ├── PersistentArray.cpp │ │ ├── PersistentFenwick.cpp │ │ └── PersistentTrie.cpp │ ├── PersistentSegmentTree.cpp │ ├── RangeTrees.cpp │ ├── SegmentTree.cpp │ ├── SegmentTrees │ │ ├── DynamicSegmentTree.cpp │ │ ├── DynamicWavelet.cpp │ │ ├── FastPersitenceSegmentTree.cpp │ │ ├── FastSegmentTree.cpp │ │ ├── ISegmentTree.cpp │ │ ├── ISegmentTreeTrim.cpp │ │ ├── PersistentDynamicSegmentTree.cpp │ │ ├── PersistentSegmentTree.cpp │ │ └── SegmentTree.cpp │ ├── SortedSplayTree.cpp │ ├── SparseTable.cpp │ ├── SplayTreeReversable │ ├── Sqrt │ │ ├── MoWithUpdate.cpp │ │ └── SqrtDecomposition.cpp │ ├── SquareRootOptimization.cpp │ ├── TreapSet.cpp │ ├── Treap_SegmentTree.cpp │ ├── UniqueTreeEncoding.cpp │ └── WaveletTree.cpp ├── Utils │ ├── Printer.cpp │ ├── Random.cpp │ └── SidePrinter.cpp └── src │ └── main.cpp ├── Images └── Aho-Corasick │ ├── AhoCorasick-Example.PNG │ └── AhoCorasick-Example.gliffy ├── LICENSE └── README.md /Codes/.gitignore: -------------------------------------------------------------------------------- 1 | /Graph 2 | /Debug 3 | -------------------------------------------------------------------------------- /Codes/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Codes 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | ?name? 14 | 15 | 16 | 17 | org.eclipse.cdt.make.core.append_environment 18 | true 19 | 20 | 21 | org.eclipse.cdt.make.core.autoBuildTarget 22 | all 23 | 24 | 25 | org.eclipse.cdt.make.core.buildArguments 26 | 27 | 28 | 29 | org.eclipse.cdt.make.core.buildCommand 30 | make 31 | 32 | 33 | org.eclipse.cdt.make.core.buildLocation 34 | ${workspace_loc:/Codes/Debug} 35 | 36 | 37 | org.eclipse.cdt.make.core.cleanBuildTarget 38 | clean 39 | 40 | 41 | org.eclipse.cdt.make.core.contents 42 | org.eclipse.cdt.make.core.activeConfigSettings 43 | 44 | 45 | org.eclipse.cdt.make.core.enableAutoBuild 46 | false 47 | 48 | 49 | org.eclipse.cdt.make.core.enableCleanBuild 50 | true 51 | 52 | 53 | org.eclipse.cdt.make.core.enableFullBuild 54 | true 55 | 56 | 57 | org.eclipse.cdt.make.core.fullBuildTarget 58 | all 59 | 60 | 61 | org.eclipse.cdt.make.core.stopOnError 62 | true 63 | 64 | 65 | org.eclipse.cdt.make.core.useDefaultBuildCmd 66 | true 67 | 68 | 69 | 70 | 71 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 72 | full,incremental, 73 | 74 | 75 | 76 | 77 | 78 | org.eclipse.cdt.core.cnature 79 | org.eclipse.cdt.core.ccnature 80 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 81 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 82 | 83 | 84 | -------------------------------------------------------------------------------- /Codes/CHIVO DELUXE EDITION (ACM_2012).pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cjtoribio/Algorithms/9e9609b12e47b8897f7026198f2e55ffc9f457f5/Codes/CHIVO DELUXE EDITION (ACM_2012).pdf -------------------------------------------------------------------------------- /Codes/DynamicProgramming/ConvexHullTrick.cpp: -------------------------------------------------------------------------------- 1 | // algorithms 2 | // vector 3 | struct ConvexHullTrick { 4 | struct Line { 5 | double m,b; 6 | Line(double m,double b):m(m),b(b){} 7 | double inter(const Line &L)const{ 8 | return (L.b-b) / (m - L.m); 9 | } 10 | double eval(double x){ 11 | return m*x + b; 12 | } 13 | }; 14 | vector V; 15 | vector X; 16 | int C; 17 | ConvexHullTrick():C(0){ }; 18 | void add(Line l){ 19 | while(V.size() >= 2){ 20 | if(V[V.size()-2].inter(l) < X.back()){ 21 | V.pop_back(); 22 | X.pop_back(); 23 | } else break; 24 | } 25 | if(V.size() >= 1){ 26 | X.push_back(V.back().inter(l)); 27 | } 28 | V.push_back(l); 29 | C = min(C , (int)X.size()); 30 | } 31 | double eval(double x){ 32 | int p = lower_bound(X.begin(),X.end(), x) - X.begin(); 33 | return V[p].eval(x); 34 | } 35 | // only if x are used in increasing order 36 | double evalConstant(double x){ 37 | while(C < X.size() && x > X[C])C++; 38 | return V[C].eval(x); 39 | } 40 | }; -------------------------------------------------------------------------------- /Codes/DynamicProgramming/ConvexHullTrickSet.cpp: -------------------------------------------------------------------------------- 1 | #define INF 1e200 2 | template 3 | struct ConvexHull { 4 | struct LineX { 5 | Curve l; 6 | long double x; 7 | bool operator<(const LineX &o) const { 8 | return (o.x == -INF || x == -INF) ? cmp()(l, o.l) : (x + 1e-9 < o.x); 9 | } 10 | }; 11 | set S; 12 | template static T prev(T a) { a--; return a; } 13 | template static T next(T a) { a++; return a; } 14 | void addLine(Curve l) { 15 | auto it = S.lower_bound({l, -INF}); 16 | if (it != S.end() && it->l.m == l.m) return; 17 | if (it != S.end() && it != S.begin() && l.pitty(prev(it)->l, it->l)) return; 18 | vector tr; 19 | if (it != S.begin()) 20 | for (auto r = prev(it); r != S.begin() && r->l.pitty(prev(r)->l, l); --r) { 21 | tr.push_back(r->l); 22 | } 23 | if (it != S.begin() && prev(it) == S.begin() && prev(it)->l.m == l.m) 24 | tr.push_back(prev(it)->l); 25 | for (auto f = it; f != S.end() && next(f) != S.end() && f->l.pitty(l, next(f)->l); f++) { 26 | tr.push_back(f->l); 27 | } 28 | for (auto t : tr) S.erase({t, -INF}); 29 | vector ta; 30 | auto pr = S.lower_bound({l, -INF}); 31 | if (pr != S.begin()) { pr--; ta.push_back(pr->l), S.erase(pr); } 32 | safeAdd(l); 33 | if (ta.size()) safeAdd(ta[0]); 34 | } 35 | void safeAdd(Curve l) { 36 | auto it = S.lower_bound({l, -INF}); 37 | S.insert({l, it == S.end() ? INF : l.xinter(it->l)}); 38 | } 39 | long double getBest(long double x) { 40 | auto it = S.lower_bound({{0, 0}, x}); 41 | return x * it->l.m + it->l.b; 42 | } 43 | }; 44 | struct Curve { 45 | double m, b; 46 | long double pitty(Curve le, Curve ri) const { 47 | return ((b - le.b)*(le.m - ri.m) >= (ri.b - le.b)*(le.m - m)); 48 | } 49 | long double xinter(Curve o) const { 50 | return 1.0L * (o.b - b) / (m - o.m); 51 | } 52 | }; 53 | struct IncSlope { 54 | bool operator()(const Curve &a, const Curve &b) { 55 | return a.m != b.m ? a.m < b.m : a.b < b.b; 56 | } 57 | }; 58 | struct DecSlope { 59 | bool operator()(const Curve &a, const Curve &b) { 60 | return a.m != b.m ? a.m > b.m : a.b > b.b; 61 | } 62 | }; 63 | -------------------------------------------------------------------------------- /Codes/DynamicProgramming/ConvexHullTrickSet.cpp (Underwork): -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Author: Simon Lindholm 4 | * Date: 2017-04-20 5 | * License: CC0 6 | * Source: own work 7 | * Description: Container where you can add lines of the form kx+m, and query maximum values at points x. 8 | * Useful for dynamic programming. 9 | * Time: O(\log N) 10 | * Status: tested 11 | */ 12 | #pragma once 13 | 14 | struct Line { 15 | mutable ll k, m, p; 16 | bool operator<(const Line& o) const { return k < o.k; } 17 | bool operator<(ll x) const { return p < x; } 18 | }; 19 | 20 | struct LineContainer : multiset> { 21 | // (for doubles, use inf = 1/.0, div(a,b) = a/b) 22 | const ll inf = LLONG_MAX; 23 | ll div(ll a, ll b) { // floored division 24 | return a / b - ((a ^ b) < 0 && a % b); } 25 | bool isect(iterator x, iterator y) { 26 | if (y == end()) { x->p = inf; return false; } 27 | if (x->k == y->k) x->p = x->m > y->m ? inf : -inf; 28 | else x->p = div(y->m - x->m, x->k - y->k); 29 | return x->p >= y->p; 30 | } 31 | void add(ll k, ll m) { 32 | auto z = insert({k, m, 0}), y = z++, x = y; 33 | while (isect(y, z)) z = erase(z); 34 | if (x != begin() && isect(--x, y)) isect(x, y = erase(y)); 35 | while ((y = x) != begin() && (--x)->p >= y->p) 36 | isect(x, erase(y)); 37 | } 38 | ll query(ll x) { 39 | assert(!empty()); 40 | auto l = *lower_bound(x); 41 | return l.k * x + l.m; 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /Codes/DynamicProgramming/DynamicConvexHullTrick.cpp: -------------------------------------------------------------------------------- 1 | struct Line { long double m, b; }; 2 | template 3 | struct ConvexHull { 4 | vector> lines; 5 | cmp c; 6 | ConvexHull():lines(1) { } 7 | void addLine(Line line){ 8 | lines[0].insert(lower_bound(lines[0].begin(), lines[0].end(), line, c), line); 9 | clean(lines[0]); 10 | for(int i = 0; i < lines.size(); ++i){ 11 | if(lines[i].size() > (1< &row : lines){ 27 | if(row.size() == 0)continue; 28 | int lo = 0, hi = row.size()-1, b = -1; 29 | while(lo <= hi){ 30 | int mi = (lo + hi)/2; 31 | if(mi == 0 || 1.0*(row[mi-1].b-row[mi].b)/(row[mi].m-row[mi-1].m) <= x){ 32 | b = mi; 33 | lo = mi+1; 34 | }else{ 35 | hi = mi-1; 36 | } 37 | } 38 | if(!hasValue) r = row[b].m * x + row[b].b; 39 | else r = c.best(r, row[b].m * x + row[b].b); 40 | hasValue = 1; 41 | } 42 | return r; 43 | } 44 | static bool pitty(Line a, Line b, Line c){ 45 | return ((b.b - a.b)*(a.m - c.m) >= (c.b - a.b)*(a.m - b.m)); 46 | } 47 | vector join(const vector &a, const vector &b){ 48 | vector nl; nl.resize(a.size() + b.size()); 49 | merge(a.begin(), a.end(), b.begin(), b.end(), nl.begin(), c); 50 | clean(nl); 51 | return nl; 52 | } 53 | static void clean(vector &lines){ 54 | vector nl; 55 | for(Line l : lines){ 56 | while(nl.size() >= 2 && pitty(nl[nl.size()-2], nl.back(), l)) 57 | nl.pop_back(); 58 | if (nl.size() && nl.back().m == l.m) nl.pop_back(); 59 | nl.push_back(l); 60 | } 61 | lines = nl; 62 | } 63 | }; 64 | struct IncSlope { 65 | bool operator()(const Line &a, const Line &b) { 66 | return a.m != b.m ? a.m < b.m : a.b < b.b; 67 | } 68 | double best(double a, double b) const { 69 | return max(a, b); 70 | } 71 | }; 72 | struct DecSlope { 73 | bool operator()(const Line &a, const Line &b) { 74 | return a.m != b.m ? a.m > b.m : a.b > b.b; 75 | } 76 | double best(double a, double b) const { 77 | return min(a, b); 78 | } 79 | }; 80 | -------------------------------------------------------------------------------- /Codes/DynamicProgramming/Histogram.cpp: -------------------------------------------------------------------------------- 1 | pair histogram(vector H) { 2 | stack> STK; // pos, height 3 | int mA = -1; 4 | pair ANS; 5 | STK.push(PII(-1, 0)); 6 | H.push_back(0); 7 | for (int i = 0; i < H.size(); ++i) { 8 | int h = H[i]; 9 | while (STK.size() > 1 && STK.top().second >= h) { 10 | auto c = STK.top(); STK.pop(); 11 | int st = STK.top().first + 1, en = i - 1; 12 | int area = c.second * (en - st + 1); 13 | if (area > mA) { 14 | ANS = PII(st, en); 15 | mA = area; 16 | } 17 | } 18 | STK.push(PII(i, H[i])); 19 | } 20 | return ANS; 21 | } 22 | -------------------------------------------------------------------------------- /Codes/DynamicProgramming/InversionCount.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | struct InversionCount 5 | { 6 | typedef long long Long; 7 | static Long inversionCount(vector V) 8 | { 9 | int N = V.size(); 10 | int arr[N]; 11 | for(int i = 0; i < N; ++i) 12 | arr[i] = V[i]; 13 | Long ret = 0; 14 | for(int i = 0; (1< 24 | static Long countInv(ITERATOR begin , ITERATOR end) 25 | { 26 | if(end - begin <= 1)return 0; 27 | int N = end - begin; 28 | vector tmp(N); 29 | 30 | int ia = 0 , ib = N/2 , idx = 0; 31 | Long ans = 0; 32 | while(ib < N) 33 | { 34 | while(ia < N/2 && *(begin+ia) > *(begin+ib)){ 35 | tmp[idx++] = *(begin + ia); 36 | ia++; 37 | } 38 | ans += ia; 39 | tmp[idx++] = *(begin + ib); 40 | ib++; 41 | } 42 | while(ia < N/2){ 43 | tmp[idx++] = *(begin + ia); 44 | ia++; 45 | } 46 | for(int i = 0; i < N; ++i) 47 | *(begin + i) = tmp[i]; 48 | return ans; 49 | } 50 | }; 51 | -------------------------------------------------------------------------------- /Codes/DynamicProgramming/LIS.cpp: -------------------------------------------------------------------------------- 1 | struct LIS 2 | { 3 | static vector PreviusNumberLIS(const vector &input) 4 | { 5 | int N = input.size(); 6 | vector KTH; 7 | vector P(N); 8 | for(int i = 0; i < N; ++i) 9 | { 10 | int v = input[i]; 11 | int p = lower_bound(KTH.begin(), KTH.end(),v) - KTH.begin(); 12 | if(p == (int)KTH.size()) KTH.push_back(v); 13 | else KTH[p] = v; 14 | P[i] = p > 0 ? KTH[p-1] : -1000000000; 15 | } 16 | map M; M[-1000000000] = -1; 17 | for(int i = 0; i < P.size(); ++i) 18 | { 19 | P[i] = M[P[i]]; 20 | M[input[i]] = i; 21 | } 22 | return P; 23 | } 24 | }; -------------------------------------------------------------------------------- /Codes/DynamicProgramming/Partitions.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | struct Partitions 5 | { 6 | const static int MOD = 1000000007; 7 | /** 8 | * It is known that MaxParts < SQRT(2*MaxSum) + 5 otherwise DP[MaxParts][MaxSum] = 0 9 | * parts from the theory of taking a PARTITION of size K parts with the 10 | * smallest partition of size X and then SUBTRACTING X from each partition 11 | * which is the same number of DP(PARTS-1 , SUM - X*PARTS) 12 | * then DP(PARTS,SUM) += DP(PARTS-1, SUM - X*PARTS ) FOR X = [1..SUM] 13 | */ 14 | static vector< vector > IncreasingDistinctParts(int MaxParts,int MaxSum) 15 | { 16 | vector > mem(MaxParts+1 , vector(MaxSum+1)); 17 | for(int i = 1; i <= MaxParts; ++i) 18 | { 19 | vector prev(MaxSum+1); 20 | for(int k = 1; k <= MaxSum; ++k) 21 | { 22 | prev[k] = mem[i-1][k]; 23 | if(i == 1) 24 | mem[i][k] = 1; 25 | else if(k >= i) 26 | { 27 | mem[i][k] = prev[k-i]; 28 | prev[k] += prev[k-i]; 29 | if(prev[k] >= MOD)prev[k] -= MOD; 30 | } 31 | } 32 | } 33 | return mem; 34 | } 35 | /** 36 | * parts from the theory of taking a PARTITION of size K parts with the 37 | * smallest partition of size X and then SUBTRACTING X from each partition 38 | * which is the same number of DP(PARTS-1 , SUM - X*PARTS) 39 | * then DP(PARTS,SUM) += DP(PARTS-1, SUM - X*PARTS ) FOR X = [0..SUM] 40 | */ 41 | static vector< vector > IncreasingParts(int MaxParts,int MaxSum) 42 | { 43 | vector > mem(MaxParts+1 , vector(MaxSum+1)); 44 | for(int i = 1; i <= MaxParts; ++i) 45 | { 46 | vector prev(MaxSum+1); 47 | for(int k = 0; k <= MaxSum; ++k) 48 | { 49 | prev[k] = mem[i-1][k]; 50 | if(i == 1) 51 | mem[i][k] = 1; 52 | else if(k >= i) 53 | { 54 | prev[k] += prev[k-i]; 55 | if(prev[k] >= MOD)prev[k] -= MOD; 56 | mem[i][k] = prev[k]; 57 | } 58 | } 59 | } 60 | return mem; 61 | } 62 | static vector< vector > PermutedDistinctParts(int MaxParts,int MaxSum) 63 | { 64 | vector > mem = IncreasingDistinctParts(MaxParts,MaxSum); 65 | int F = 1; 66 | for(int i = 1; i <= MaxParts; ++i) 67 | { 68 | F = (1LL * F * i) % MOD; 69 | for(int k = 0; k <= MaxSum; ++k) 70 | { 71 | mem[i][k] = (1LL * mem[i][k] * F) % MOD; 72 | } 73 | } 74 | return mem; 75 | } 76 | static vector< vector > PermutedParts(int MaxParts,int MaxSum) 77 | { 78 | vector > mem(MaxParts+1 , vector(MaxSum+1)); 79 | for(int i = 1; i <= MaxParts; ++i) 80 | { 81 | vector prev(MaxSum+1); 82 | for(int k = 0; k <= MaxSum; ++k) 83 | { 84 | prev[k] = mem[i-1][k]; 85 | if(i == 1) 86 | mem[i][k] = 1; 87 | else 88 | { 89 | if(k > 0)prev[k] += prev[k-1]; 90 | if(prev[k] >= MOD)prev[k] -= MOD; 91 | mem[i][k] = prev[k]; 92 | } 93 | } 94 | } 95 | return mem; 96 | } 97 | }; 98 | -------------------------------------------------------------------------------- /Codes/DynamicProgramming/PersistentConvexHullTrick.cpp: -------------------------------------------------------------------------------- 1 | typedef long double Double; 2 | typedef long long Long; 3 | struct ConvexHullTrick { 4 | struct Line { 5 | Double m,b; 6 | Line(Double m,Double b):m(m),b(b){} 7 | Double inter(const Line &L)const{ 8 | return (L.b-b) / (m - L.m); 9 | } 10 | Double eval(Double x){ 11 | return m*x + b; 12 | } 13 | }; 14 | struct Node { 15 | Line l = Line(1, 0); 16 | Double intWithPrev = -1e100; 17 | vector par; 18 | vector to; 19 | }; 20 | vector nodes; 21 | ConvexHullTrick(){ }; 22 | void add(Line l, int version = -1){ 23 | int id = nodes.size(); 24 | Node nn; nn.l = l; 25 | if(nodes.size() != 0) { 26 | int p = version == -1 ? nodes.size() -1 : version; 27 | for (int i = nodes[p].par.size(); i >= 0 && p != 0; --i) { 28 | if (nodes[p].par.size() <= i) continue; 29 | if (nodes[p].par[i] == 0) continue; 30 | int pp = nodes[p].par[i]; 31 | int ppp = nodes[pp].par[0]; 32 | if(nodes[ppp].l.inter(l) < nodes[pp].intWithPrev) { 33 | p = ppp; 34 | } else { 35 | break; 36 | } 37 | } 38 | while(p != 0) { 39 | int pp = nodes[p].par[0]; 40 | if(nodes[pp].l.inter(l) < nodes[p].intWithPrev) { 41 | p = pp; 42 | } else { 43 | break; 44 | } 45 | } 46 | nodes[p].to.push_back(id); 47 | nn.par.push_back(p); 48 | nn.intWithPrev = nn.l.inter(nodes[p].l); 49 | for(int i = 0; i < nodes[ nn.par[i] ].par.size(); ++i) { 50 | int rp = nn.par[i]; 51 | nn.par.push_back(nodes[rp].par[i]); 52 | } 53 | assert(nn.par.size() <= 20); 54 | } 55 | nodes.push_back(nn); 56 | } 57 | Double eval(Double x, int version = -1){ 58 | int n = version == -1 ? nodes.size() - 1 : version; 59 | // while(nodes[n].intWithPrev > x) 60 | // n = nodes[n].par[0]; 61 | for (int i = nodes[n].par.size(); i >= 0; --i) { 62 | if (nodes[n].par.size() <= i) continue; 63 | int p = nodes[n].par[i]; 64 | if (x < nodes[p].intWithPrev) { 65 | n = p; 66 | } 67 | } 68 | if (x < nodes[n].intWithPrev) n = nodes[n].par[0]; 69 | return nodes[n].l.eval(x); 70 | } 71 | void print(int n = 0, int lvl = 0) { 72 | cout << string(lvl * 3, ' ')<< n << " " << nodes[n].intWithPrev << endl; 73 | for(int v : nodes[n].to) 74 | print(v, lvl+1); 75 | } 76 | }; 77 | -------------------------------------------------------------------------------- /Codes/DynamicProgramming/SubsetSum.cpp: -------------------------------------------------------------------------------- 1 | typedef vector VI; 2 | typedef vector VVI; 3 | typedef long long Long; 4 | // http://codeforces.com/blog/entry/45223 5 | struct SubsetSum { 6 | int mb; 7 | VI A, B, F; 8 | SubsetSum(int mb):mb(mb), A(1<= 0; --i) { 34 | if( n & (1< V = {1, 3, 4 ,2, 1, 4, 2}; 45 | for (int i = 0; i < V.size(); ++i) { 46 | S.addVal(V[i], 1); 47 | } 48 | S.build(); 49 | for (int i = 0; i < V.size(); ++i) { 50 | cout << S.bestOr(V[i]) << " " << S.sumSubsets(V[i]) << " " << S.sumSupersets(V[i]) << endl; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Codes/Geometry/AngleBetweenVectors.cpp: -------------------------------------------------------------------------------- 1 | double angle(Point A, Point B){ 2 | return B.rotate(-A.angle()).angle(); 3 | } -------------------------------------------------------------------------------- /Codes/Geometry/BestCurveBuffer.cpp: -------------------------------------------------------------------------------- 1 | typedef long double Double; 2 | struct Curve { 3 | Double a, b, c; // a*(x - b) + c 4 | long double eval(Double x) { 5 | return a*(x - b)*(x - b) + c; 6 | } 7 | vector allInter(Curve &o) { 8 | /* a0 * (x - b0)^2 + c0 = a1 * (x - b1)^2 + c1 9 | (a0-a1)*x^2 - 2*(b0*a0-b1*a1)*x + (b0*b0+c0-c1-b1*b1) = 0 */ 10 | Double na = (a - o.a); 11 | Double nb = -2*(a*b - o.a*o.b); 12 | Double nc = (a*b*b + c - o.c - o.a*o.b*o.b); 13 | if (na == 0) return nb == 0 ? vector() : vector(1, -nc / nb); 14 | if (nb*nb - 4*na*nc < 0) return {}; 15 | Double det = sqrt(nb*nb - 4*na*nc); 16 | vector R = { (-nb - det) / (2*na), (-nb + det) / (2*na) }; 17 | if (R[0] > R[1]) swap(R[0], R[1]); 18 | return R; 19 | } 20 | }; 21 | 22 | struct Buffer { 23 | #define INF 1e200 24 | #define EPS 1e-9 25 | struct CurveDominance { 26 | int id; 27 | Double st, en; 28 | }; 29 | vector C; 30 | vector D; 31 | void add(Curve c) { 32 | int nid = C.size(); 33 | C.push_back(c); 34 | vector ND; 35 | for (auto p : D) { 36 | auto inters = c.allInter(C[p.id]); 37 | inters.push_back(INF); 38 | Double px = -INF; 39 | for (Double x : inters) { 40 | if (c.eval(x-1) >= C[p.id].eval(x-1)) { 41 | Double st = max(p.st, px); 42 | Double en = min(p.en, x); 43 | if (st <= en) { 44 | ND.push_back({p.id, st, en}); 45 | } 46 | } 47 | px = x; 48 | } 49 | } 50 | D.clear(); 51 | Double px = -INF; 52 | for (int i = 0; i < ND.size(); ++i) { 53 | if (ND[i].st > px) { 54 | D.push_back({nid, px, ND[i].st}); 55 | } 56 | D.push_back(ND[i]); 57 | px = ND[i].en; 58 | } 59 | if (ND.size() == 0 || ND.back().en < INF) { 60 | D.push_back({nid, px, INF}); 61 | } 62 | } 63 | Double query(Double x) { 64 | int lo = 0, hi = (int)D.size() - 1, ret = -1; 65 | while (lo <= hi) { 66 | int mi = (lo + hi) / 2; 67 | if (D[mi].en < x) { 68 | lo = mi + 1; 69 | } else { 70 | hi = mi - 1; 71 | ret = mi; 72 | } 73 | } 74 | return ret == -1 ? INF : C[D[ret].id].eval(x); 75 | } 76 | #undef EPS 77 | #undef INF 78 | }; 79 | -------------------------------------------------------------------------------- /Codes/Geometry/ConvexHullUL.cpp: -------------------------------------------------------------------------------- 1 | vector GetHull(vector V, int upper, int allow180 = true){ 2 | vector H; 3 | int sz = 0, sig = upper ? 1 : -1; 4 | double eps = allow180 ? 0 : 1e-9; 5 | for(Point p : V){ 6 | while(H.size() >= 2 && sig * ((H[sz-1]-H[sz-2])^(p-H[sz-2])) + eps > 0){ 7 | H.pop_back(); 8 | sz--; 9 | } 10 | H.push_back(p); 11 | sz++; 12 | } 13 | return H; 14 | } 15 | vector ConvexHullUL(vector V, int allow180 = true){ 16 | if(V.size() <= 1)return V; 17 | sort(V.begin(),V.end()); 18 | vector U = GetHull(V,true, allow180); 19 | vector L = GetHull(V,false, allow180); 20 | for(int i = L.size() - 2; i >= 1; --i){ 21 | U.push_back(L[i]); 22 | } 23 | return U; 24 | } -------------------------------------------------------------------------------- /Codes/Geometry/Generic/InsideSimplePolygon.cpp: -------------------------------------------------------------------------------- 1 | // returns -1 (inside), 0 (border), 1 (outside) 2 | template 3 | int pointVsPolygon(const Point& point, const Polygon& poly) { 4 | int n = static_cast(poly.size()), windingNumber = 0; 5 | for (int i = 0; i < n; ++i) { 6 | if (point == poly[i]) 7 | return 0; 8 | int j = next(i, n); 9 | if (poly[i].y == point.y && poly[j].y == point.y) { 10 | if (min(poly[i].x, poly[j].x) <= point.x && point.x <= max(poly[i].x, poly[j].x)) 11 | return 0; 12 | } else { 13 | bool below = poly[i].y < point.y; 14 | if (below != (poly[j].y < point.y)) { 15 | auto orientation = (poly[j] - poly[i]) ^ (point - poly[i]); 16 | if (orientation == 0) 17 | return 0; 18 | if (below == (orientation > 0)) 19 | windingNumber += below ? 1 : -1; 20 | } 21 | } 22 | } 23 | return windingNumber == 0 ? 1 : -1; 24 | } 25 | -------------------------------------------------------------------------------- /Codes/Geometry/Generic/Line.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct Line { 3 | Point a, ab; 4 | Line() : a(), ab() {} 5 | Line(Point a, Point b, bool twoPoints = true) : a(a), ab(twoPoints ? b - a : b) {} 6 | 7 | Point b() const { return a + ab; } 8 | operator bool () const { return ab != Point(); } 9 | bool aligned(Point o)const{ return ((o - a)^(ab)) == 0; } 10 | }; 11 | 12 | /// Method for line and segment intersection intersection 13 | enum EC { R, C, O }; // Ray, Closed, Open 14 | template 15 | bool check(EC t, F a, F b){ 16 | if(t == EC::R) return true; 17 | if(t == EC::C) return a <= b; 18 | if(t == EC::O) return a < b; 19 | } 20 | template 21 | bool intersectLines(Line lhs, Line rhs, Point& res, bool deb = 0) { 22 | auto s = lhs.ab ^ rhs.ab; 23 | if (s == 0) return false; 24 | auto ls = (rhs.a - lhs.a) ^ rhs.ab; 25 | auto rs = (rhs.a - lhs.a) ^ lhs.ab; 26 | if (s < 0) s = -s, ls = -ls, rs = -rs; 27 | bool intersect = check(LA, decltype(ls)(0), ls) && check(LB, ls, s) && 28 | check(RA, decltype(rs)(0), rs) && check(RB, rs, s); 29 | if (intersect) res = lhs.a + lhs.ab * static_cast(ls) / s; 30 | return intersect; 31 | } 32 | -------------------------------------------------------------------------------- /Codes/Geometry/Generic/Point.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct Point { 3 | F x, y; 4 | Point() : x(0), y(0) {} 5 | Point(const F& x, const F& y) : x(x), y(y) {} 6 | 7 | template 8 | Point& operator = (const Point& o) { x = o.x; y = o.y; return *this; } 9 | template explicit operator Point () const { 10 | return Point(static_cast(x), static_cast(y)); } 11 | 12 | }; 13 | 14 | template inline Point makePoint(const F& x, const F& y) { return Point(x, y); } 15 | 16 | #define FUNC1(name, arg, expr) \ 17 | template inline auto name(const arg) -> decltype(expr) { return expr; } 18 | #define FUNC2(name, arg1, arg2, expr) \ 19 | template \ 20 | inline auto name(const arg1, const arg2) -> decltype(expr) { return expr; } 21 | #define FUNC3(name, arg1, arg2, arg3, expr) \ 22 | template \ 23 | inline auto name(const arg1, const arg2, const arg3) -> decltype(expr) { return expr; } 24 | 25 | FUNC1(operator -, Point& p, makePoint(-p.x, -p.y)) 26 | FUNC1(gcd, Point& p, p / abs(__gcd(p.x, p.y)) ) 27 | FUNC2(operator +, Point& lhs, Point& rhs, makePoint(lhs.x + rhs.x, lhs.y + rhs.y)) 28 | FUNC2(operator -, Point& lhs, Point& rhs, makePoint(lhs.x - rhs.x, lhs.y - rhs.y)) 29 | FUNC2(operator *, F1& factor, Point& rhs, makePoint(factor * rhs.x, factor * rhs.y)) 30 | FUNC2(operator *, Point& lhs, F2& factor, makePoint(lhs.x * factor, lhs.y * factor)) 31 | FUNC2(operator /, Point& lhs, F2& factor, makePoint(lhs.x / factor, lhs.y / factor)) 32 | FUNC2(operator *, Point& lhs, Point& rhs, lhs.x * rhs.x + lhs.y * rhs.y) 33 | FUNC2(operator ^, Point& lhs, Point& rhs, lhs.x * rhs.y - lhs.y * rhs.x) 34 | 35 | FUNC2(operator ==, Point& lhs, Point& rhs, lhs.x == rhs.x && lhs.y == rhs.y) 36 | FUNC2(operator !=, Point& lhs, Point& rhs, !(lhs == rhs)) 37 | FUNC2(operator <, Point& lhs, Point& rhs, lhs.x < rhs.x || (lhs.x == rhs.x && lhs.y < rhs.y)) 38 | 39 | FUNC2(ccw, Point& lhs, Point& rhs, rhs ^ lhs) 40 | FUNC3(ccw, Point& lhs, Point& rhs, Point& origin, ccw(lhs - origin, rhs - origin)) 41 | 42 | #undef FUNC1 43 | #undef FUNC2 44 | #undef FUNC3 45 | 46 | template ostream& operator << (ostream& os, const Point& point) { return os << point.x << ',' << point.y; } 47 | -------------------------------------------------------------------------------- /Codes/Geometry/Generic/Polygon.cpp: -------------------------------------------------------------------------------- 1 | template using Polygon = vector>; 2 | inline int prev(int i, int n) { return i == 0 ? n-1 : i-1; } 3 | inline int next(int i, int n) { return i == n-1 ? 0 : i+1; } 4 | template inline int sgn(const T& x) { return (T(0) < x) - (x < T(0)); } 5 | -------------------------------------------------------------------------------- /Codes/Geometry/Generic/VectorMethods.cpp: -------------------------------------------------------------------------------- 1 | /// validates if c is a vector inside the angle aToB inclusive, 2 | /// for exclusive remove the first line. 3 | template 4 | bool betweenAngle(Point a, Point b, Point c){ 5 | if( ((a^c) == 0 && (a*c) > 0) || ((b^c) == 0 && (b*c) > 0) )return 1; 6 | if( (a^b) > 0 )return (a^c) > 0 && (c^b) > 0; 7 | if( (a^b) < 0 ) 8 | return !((b^c) > 0 && (c^a) > 0); 9 | return a*b == 0 ? 0 : (a^c) > 0; 10 | } 11 | -------------------------------------------------------------------------------- /Codes/Geometry/InsideConvex.cpp: -------------------------------------------------------------------------------- 1 | struct InsideConvexDetection { 2 | vector CH; 3 | vector A; // angles in increasing order [0,... 4 | Point center; 5 | // accept clockwise 6 | Wedge(vector _CH) : CH(_CH) { 7 | reverse(CH.begin(), CH.end()); 8 | for (Point p : CH) { 9 | center = center + p; 10 | } 11 | center = center.scale(1.0 / CH.size()); 12 | A.push_back(0); 13 | for (int i = 1; i < CH.size(); ++i) { 14 | A.push_back((CH[0] - center).angle(CH[i] - center)); 15 | } 16 | } 17 | bool isIn(Point p) { 18 | Double ang = (CH[0] - center).angle(p - center); 19 | int pos = upper_bound(A.begin(), A.end(), ang) - A.begin(); 20 | pos--; 21 | if (((CH[(pos + 1) % CH.size()] - CH[pos]) ^ (p - CH[pos])) < 0) { 22 | return false; 23 | } 24 | return true; 25 | } 26 | }; -------------------------------------------------------------------------------- /Codes/Geometry/PointStruct.cpp: -------------------------------------------------------------------------------- 1 | typedef long double Double; 2 | struct Point { 3 | Double x, y; 4 | Point(Double x = 0, Double y = 0) : x(x), y(y) {} 5 | Point round() const { return Point(round(x), round(y)); } 6 | Point operator-(const Point &P) const { return Point(x - P.x, y - P.y); } 7 | Point operator+(const Point &P) const { return Point(x + P.x, y + P.y); } 8 | Double operator^(const Point &P) { return x * P.y - y * P.x; } 9 | Double operator*(const Point &P) { return x * P.x + y * P.y; } 10 | Double sqMag() const { return x * x + y * y; } 11 | Double mag() const { return sqrt(sqMag()); } 12 | Point unit() const { 13 | Double m = mag(); 14 | return Point(x / m, y / m); 15 | } 16 | Point scale(const Double &d) const { return Point(x * d, y * d); } 17 | Point rotate90() { return Point(-y, x); } 18 | Point rotate(const Double &a) const { 19 | return Point(x * cos(a) - y * sin(a), x * sin(a) + y * cos(a)); 20 | } 21 | bool operator<(const Point &p) const { 22 | return (x != p.x ? x < p.x : y < p.y); 23 | } 24 | bool operator==(const Point &P) const { return x == P.x && y == P.y; } 25 | bool similar(const Point &P) { 26 | Double rex = abs(x - P.x) / max(1.0L, abs(P.x)); 27 | Double rey = abs(y - P.y) / max(1.0L, abs(P.y)); 28 | return rex < 1e-12 && rey < 1e-12; 29 | } 30 | Double angle() const { 31 | Double an = atan2(y, x); 32 | if (an < 0) an += 2 * acos(-1); 33 | return an; 34 | } 35 | Double angle(const Point &p) const { 36 | return p.rotate(-angle()).angle(); 37 | } 38 | Double smallAngle(const Point &p) const { 39 | Double ang = angle(p); 40 | if (ang > M_PI) return ang - 2 * M_PI; 41 | return ang; 42 | } 43 | int getSide(const Point &p){ // (< 0):left, (==0):aligned, (> 0):right 44 | return (*this)^(p); 45 | } 46 | static long long round(Double d) { 47 | if (d < 0) return (long long)(d - 0.5); 48 | return (long long)(d + 0.5); 49 | } 50 | }; 51 | ostream& operator<<(ostream& o, const Point &P){ 52 | return o <<"("<< P.x << "," << P.y << ")"; 53 | } -------------------------------------------------------------------------------- /Codes/Geometry/PointToPolygonProjector.cpp: -------------------------------------------------------------------------------- 1 | struct PointToPolygonProjector { 2 | vector CH; // convex-hull clockwise 3 | Point center; 4 | PointToPolygonProjector(vector _CH) : CH(_CH), center(0, 0) { 5 | for (Point &p : CH) { 6 | center = center + p; 7 | } 8 | center = center.scale(1.0 / CH.size()); 9 | } 10 | pair getWindow(Point p) { 11 | int ff = lowerBoundAngle(p, 0); 12 | int fs = lowerBoundAngle(p, M_PI) - 1; 13 | if (fs < 0) fs += CH.size(); 14 | int sf = (CH.size() + ff - 1) % CH.size(); 15 | int ss = (fs + 1) % CH.size(); 16 | return make_pair(bestAngle(p, ss, sf, -1), bestAngle(p, ff, fs, 1)); 17 | } 18 | int bestAngle(Point p, int lo, int hi, int sig = 1) { 19 | // int sig = (center - p).getSide(CH[lo] - p) < 0 ? -1 : 1; 20 | int N = CH.size(); 21 | if (hi < lo) hi += N; 22 | while (hi - lo > 2) { 23 | int mi1 = lo + 1 * (hi - lo) / 3; 24 | int mi2 = lo + 2 * (hi - lo) / 3; 25 | if ((CH[mi1%N] - p).getSide(CH[mi2%N] - p) * sig > 0) { 26 | lo = mi1; 27 | } else { 28 | hi = mi2; 29 | } 30 | } 31 | int b = lo; 32 | for (int i = lo; i <= hi; ++i) { 33 | if ((CH[b%N] - p).getSide(CH[i%N] - p) * sig > 0) { 34 | b = i; 35 | } 36 | } 37 | return b % N; 38 | } 39 | Double getAngle(Point f, Point s) { 40 | return (f - center).angle(s - center); 41 | } 42 | int lowerBoundAngle(Point p, Double target) { 43 | Double ang = getAngle(CH[0], p); 44 | // Double ang = getAngle(AN[0], ref); 45 | if (target < ang) target += 2 * M_PI; 46 | int N = CH.size(); 47 | int lo = 0, hi = N; 48 | while (lo < hi) { 49 | int mi = (lo + hi) / 2; 50 | Double e = getAngle(CH[mi], p); 51 | if (e < ang) e += 2 * M_PI; 52 | if (e < target) 53 | lo = mi + 1; 54 | else 55 | hi = mi; 56 | } 57 | lo %= N; 58 | return lo; 59 | } 60 | }; -------------------------------------------------------------------------------- /Codes/Geometry/SegmentIntercect.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | (A-C + (B-A)*t) ^ (D-C) = 0 3 | (B-A -> m : D-C -> n) 4 | (a.x + t*m.x)*n.y - (a.y + t*m.y)*n.x = 0 5 | a.x*n.y - a.y*n.x + t*(m^n) = 0 6 | t*(m^n) = n^a 7 | t = - ((a-c)^n) / (m^n) 8 | */ 9 | Point segIntercept(const Point &A, const Point &B, const Point &C, const Point &D){ 10 | Point m = (B-A); 11 | Point n = (D-C); 12 | Double t = - ((A-C)^n) / (m^n); 13 | return A + m.scale(t); 14 | } 15 | bool hasIntercept(const Point &A, const Point &B, const Point &C, const Point &D){ 16 | Point m = (B-A); 17 | Point n = (D-C); 18 | if(Point::similar(m^n, 0))return false; // parallel 19 | double t = - ((A-C)^n) / (m^n); 20 | return 0-1e9 <= t && t <= 1+1e9; // lies between 21 | } -------------------------------------------------------------------------------- /Codes/Geometry/ThirdPointLeft.cpp: -------------------------------------------------------------------------------- 1 | Point thirdPointLeft(Point A,Point B, Double ac, Double bc){ 2 | Point AB = B-A; 3 | Double ab = AB.mag(); 4 | Double s = (ac+ab+bc)/2; 5 | // assert(s > ac && s > ab && s > bc); 6 | Double area = sqrt(s*(s-ab))*sqrt((s-bc)*(s-ac)); 7 | Double h = 2*area / ab; 8 | Double ax = sqrt(ac*ac - h*h); 9 | Double bx = sqrt(bc*bc - h*h); 10 | if(ax > bx){ 11 | return A + AB.unit().scale(ax) + AB.unit().rotate90().scale(h); 12 | }else{ 13 | return B + AB.unit().scale(-bx) + AB.unit().rotate90().scale(h); 14 | } 15 | } -------------------------------------------------------------------------------- /Codes/Graph/2-SAT.cpp: -------------------------------------------------------------------------------- 1 | // SOURCE: https://sites.google.com/site/indy256/algo/2_sat 2 | typedef vector VI; 3 | typedef vector VVI; 4 | struct SAT2 5 | { 6 | VVI adj , radj; 7 | VI vis , order, comp , sat; 8 | SAT2(int N){ 9 | adj = VVI(2*(N+1)); 10 | radj = VVI(2*(N+1)); 11 | } 12 | void addImplication(int i,int j) 13 | { 14 | int si = i < 0 ? 1 : 0; 15 | int sj = j < 0 ? 1 : 0; 16 | i = abs(i); j = abs(j); 17 | adj[2*i+si].push_back(2*j+sj); 18 | radj[2*j+sj].push_back(2*i+si); 19 | adj[2*j+!sj].push_back(2*j+!sj); 20 | radj[2*i+!sj].push_back(2*j+!si); 21 | } 22 | void addOr(int i, int j){ 23 | addImplication(-i, j); 24 | addImplication(-j, i); 25 | } 26 | void addXor(int i, int j){ 27 | addImplication(i, -j); 28 | addImplication(j, -i); 29 | addImplication(-i, j); 30 | addImplication(-j, i); 31 | } 32 | void setTrue(int i){ 33 | addImplication(-i, i); 34 | } 35 | void dfs1(int u) 36 | { 37 | vis[u] = 1; 38 | for(int i = 0; i < adj[u].size(); ++i) 39 | { 40 | int v = adj[u][i]; 41 | if(!vis[v]) dfs1(v); 42 | } 43 | order.push_back(u); 44 | } 45 | void dfs2(int u,int color) 46 | { 47 | comp[u] = color; 48 | for(int i = 0; i < radj[u].size(); ++i) 49 | { 50 | int v = radj[u][i]; 51 | if(comp[v] == -1) 52 | dfs2(v,color); 53 | } 54 | } 55 | bool run2SAT() 56 | { 57 | int N = adj.size(); 58 | vis = VI(N); 59 | comp = VI(N,-1); 60 | sat = VI(N / 2); 61 | for(int i = 0; i < N; ++i) 62 | if(!vis[i]) 63 | dfs1(i); 64 | int c = 0; 65 | for(int i = 0; i < N; ++i) 66 | { 67 | int u = order[N-i-1]; 68 | if(comp[u] == -1) 69 | dfs2(u,c++); 70 | } 71 | for(int i = 0; i < N; i++) 72 | if(comp[i] == comp[i^1]) 73 | return false; 74 | for (int i = 0; i < N; i += 2) 75 | { 76 | sat[i / 2] = comp[i] > comp[i ^ 1]; 77 | // cout << i/2 << " " << (sat[i/2]?"true":"false") << endl; 78 | } 79 | return true; 80 | } 81 | }; 82 | -------------------------------------------------------------------------------- /Codes/Graph/CountMinimumSpanningTree.cpp: -------------------------------------------------------------------------------- 1 | struct CountMST{ 2 | struct Edge { 3 | int u,v,w; 4 | bool operator<(const Edge &C)const{ 5 | return w < C.w; 6 | } 7 | }; 8 | int N; 9 | vector E; 10 | CountMST(int N):N(N){ } 11 | void addEdge(int u,int v,int w){ 12 | E.push_back((Edge){u,v,w}); 13 | } 14 | mint countMST(){ 15 | sort(E.begin(),E.end()); 16 | // exists MST 17 | { 18 | DisjointSet DS(N); 19 | for(Edge &e : E){ 20 | DS.join(e.u, e.v); 21 | } 22 | if(DS.size() > 1){ 23 | return 0; 24 | } 25 | } 26 | 27 | mint r = 1; 28 | // count 29 | { 30 | DisjointSet DS(N); 31 | for(int i = 0; i < E.size(); ){ 32 | vector S; 33 | {// put equal edges 34 | int j = i; 35 | while(j < E.size() && E[i].w == E[j].w){ 36 | S.push_back(E[j]); 37 | j++; 38 | } 39 | i = j; 40 | } 41 | for(Edge &e : S){ 42 | e.u = DS.find(e.u); 43 | e.v = DS.find(e.v); 44 | } 45 | for(Edge &e : S){ 46 | DS.join(e.u, e.v); 47 | } 48 | vector< pair > G; 49 | for(Edge &e : S){ 50 | if(e.u != e.v){ 51 | G.push_back(make_pair(DS.find(e.u), e)); 52 | } 53 | } 54 | sort(G.begin(),G.end()); 55 | for(int j = 0; j < G.size(); ){ 56 | vector ee; 57 | {// put all same node 58 | int k = j; 59 | while(k < G.size() && G[k].first == G[j].first){ 60 | ee.push_back(G[k].second); 61 | k++; 62 | } 63 | j = k; 64 | } 65 | vector NODS; 66 | for(Edge &e : ee){ 67 | NODS.push_back(e.u); 68 | NODS.push_back(e.v); 69 | } 70 | sort(NODS.begin(),NODS.end()); 71 | NODS.resize(unique(NODS.begin(),NODS.end())- NODS.begin()); 72 | CountSpanningTree CS(NODS.size()); 73 | for(Edge &e : ee){ 74 | int u = lower_bound(NODS.begin(),NODS.end(),e.u)-NODS.begin(); 75 | int v = lower_bound(NODS.begin(),NODS.end(),e.v)-NODS.begin(); 76 | CS.addEdge(u,v); 77 | } 78 | r = r * CS.run(); 79 | 80 | } 81 | 82 | } 83 | } 84 | return r; 85 | } 86 | }; -------------------------------------------------------------------------------- /Codes/Graph/CountSpanningTree.cpp: -------------------------------------------------------------------------------- 1 | struct CountSpanningTree { 2 | typedef vector VM; 3 | typedef vector VVM; 4 | VVM mat; 5 | int N; 6 | CountSpanningTree(int N):N(N){ 7 | mat = VVM(N, VM(N)); 8 | } 9 | void addEdge(int u, int v){ 10 | mat[u][u] += 1; 11 | mat[v][v] += 1; 12 | mat[u][v] -= 1; 13 | mat[v][u] -= 1; 14 | } 15 | mint run(){ 16 | for(int i = 0; i < N; ++i){ 17 | for(int j = i+1; j < N; ++j){ 18 | if(mat[i][i].n == 0)return 0; 19 | mint F = mat[j][i] / mat[i][i]; 20 | for(int k = 0; k < N; ++k){ 21 | mat[j][k] -= mat[i][k] * F; 22 | } 23 | } 24 | } 25 | mint r = 1; 26 | for(int i = 0; i < N-1; ++i){ 27 | r = r * mat[i][i]; 28 | } 29 | if(mat[N-1][N-1].n != 0)assert(false); 30 | return r; 31 | } 32 | }; -------------------------------------------------------------------------------- /Codes/Graph/EulerianPathAndCycle.cpp: -------------------------------------------------------------------------------- 1 | typedef vector VI; 2 | typedef vector VVI; 3 | struct EulerianPath { 4 | struct Edge{ 5 | int u,v,used; 6 | int getV(int _u){ 7 | return _u == u ? v : u; 8 | } 9 | }; 10 | bool directed; 11 | VVI adj; 12 | vector E; 13 | VI cId, outDeg, inDeg; 14 | int N; 15 | EulerianPath(int N, int directed = false){ 16 | this->directed = directed; 17 | this->N = N; 18 | adj = VVI(N); 19 | cId = VI(N); 20 | outDeg= VI(N); 21 | inDeg = VI(N); 22 | } 23 | void addEdge(int u,int v){ 24 | Edge e = (Edge){ u, v, 0 }; 25 | adj[u].push_back(E.size()); 26 | outDeg[u]++; 27 | inDeg[v]++; 28 | if(!directed){ 29 | adj[v].push_back(E.size()); 30 | outDeg[v]++; 31 | inDeg[u]++; 32 | } 33 | E.push_back(e); 34 | } 35 | vector getEulerPath(){ 36 | int st = -1 , cnt = 0; 37 | for(int i = 0; i < N; ++i){ 38 | if(st == -1 && outDeg[i]) 39 | st = i; 40 | if(directed){ 41 | int d = outDeg[i] - inDeg[i]; 42 | if(d > 1)return vector(); 43 | if(d ==1)st = i, cnt++; 44 | if(cnt>=2)return vector(); 45 | }else{ 46 | int d = outDeg[i]; 47 | if(d%2!=0)st = i, cnt++; 48 | if(cnt> 2)return vector(); 49 | } 50 | } 51 | stack STK; 52 | STK.push(st); 53 | vector ret; 54 | while(STK.size()){ 55 | int u = STK.top(); 56 | bool found = false; 57 | while(cId[u] < adj[u].size()){ 58 | Edge &e = E[adj[u][cId[u]++]]; 59 | if(e.used)continue; 60 | e.used = true; 61 | int v = e.getV(u); 62 | found = true; 63 | STK.push(v); 64 | break; 65 | } 66 | if(!found){ 67 | STK.pop(); 68 | ret.push_back(u); 69 | } 70 | } 71 | reverse(ret.begin(),ret.end()); 72 | return ret; 73 | } 74 | }; 75 | -------------------------------------------------------------------------------- /Codes/Graph/Flow/MinCostMaxFlow[AdjList].cpp: -------------------------------------------------------------------------------- 1 | typedef long long Long; 2 | const Long INF = 1000000000000000000LL; 3 | struct Edge { int to, cap, cost, flow, back; }; 4 | struct MinCostFlow { 5 | int n; 6 | vector> g; 7 | MinCostFlow(int n):n(n), g(n) {} 8 | void add_rib(int a, int b, int u, int c) { 9 | Edge r1 = {b, u, c, 0, g[b].size()}; 10 | Edge r2 = {a, 0, -c, 0, g[a].size()}; 11 | g[a].push_back(r1); 12 | g[b].push_back(r2); 13 | } 14 | pair run(int s, int t, Long k = 1000000000000000000LL) { 15 | Long flow = 0, cost = 0; 16 | while (flow < k) { 17 | vector id(n, 0); 18 | vector d(n, INF); 19 | vector q(n); 20 | vector p(n); 21 | vector p_rib(n); 22 | int qh = 0, qt = 0; 23 | q[qt++] = s; 24 | d[s] = 0; 25 | while (qh != qt) { 26 | int v = q[qh++]; 27 | id[v] = 2; 28 | if (qh == n) qh = 0; 29 | for (int i = 0; i < g[v].size(); ++i) { 30 | Edge &r = g[v][i]; 31 | if (r.flow < r.cap && d[v] + r.cost < d[r.to]) { 32 | d[r.to] = d[v] + r.cost; 33 | if (id[r.to] == 0) { 34 | q[qt++] = r.to; 35 | if (qt == n) qt = 0; 36 | } else if (id[r.to] == 2) { 37 | if (--qh == -1) qh = n - 1; 38 | q[qh] = r.to; 39 | } 40 | id[r.to] = 1; 41 | p[r.to] = v; 42 | p_rib[r.to] = i; 43 | } 44 | } 45 | } 46 | if (d[t] == INF) break; 47 | Long addflow = k - flow; 48 | for (int v = t; v != s; v = p[v]) { 49 | Edge &f = g[p[v]][p_rib[v]]; 50 | addflow = min(addflow, (Long) f.cap - f.flow); 51 | } 52 | for (int v = t; v != s; v = p[v]) { 53 | Edge &f = g[p[v]][p_rib[v]]; // forward edge 54 | Edge &b = g[v][f.back]; // backward edge 55 | f.flow += addflow; b.flow -= addflow; 56 | cost += f.cost * addflow; 57 | } 58 | flow += addflow; 59 | } 60 | return make_pair(flow, cost); 61 | } 62 | }; 63 | -------------------------------------------------------------------------------- /Codes/Graph/HopcroftCarp.cpp: -------------------------------------------------------------------------------- 1 | #define MAX 100001 2 | #define NIL 0 3 | #define INF (1<<28) 4 | 5 | vector< int > G[MAX]; 6 | int n, m, match[MAX], dist[MAX]; 7 | // n: number of nodes on left side, nodes are numbered 1 to n 8 | // m: number of nodes on right side, nodes are numbered n+1 to n+m 9 | // G = NIL[0] ∪ G1[G[1---n]] ∪ G2[G[n+1---n+m]] 10 | 11 | bool bfs() { 12 | int i, u, v, len; 13 | queue< int > Q; 14 | for(i=1; i<=n; i++) { 15 | if(match[i]==NIL) { 16 | dist[i] = 0; 17 | Q.push(i); 18 | } 19 | else dist[i] = INF; 20 | } 21 | dist[NIL] = INF; 22 | while(!Q.empty()) { 23 | u = Q.front(); Q.pop(); 24 | if(u!=NIL) { 25 | len = G[u].size(); 26 | for(i=0; i u(n + 1), v(m + 1), p(m + 1), way(m + 1); 8 | for (int i = 1; i <= n; ++i) { 9 | p[0] = i; 10 | int j0 = 0; 11 | vector minv(m + 1, INF); 12 | vector used(m + 1, false); 13 | do { 14 | used[j0] = true; 15 | int i0 = p[j0], delta = INF, j1; 16 | for (int j = 1; j <= m; ++j) 17 | if (!used[j]) { 18 | int cur = a[i0 - 1][j - 1] - u[i0] - v[j]; 19 | if (cur < minv[j]) 20 | minv[j] = cur, way[j] = j0; 21 | if (minv[j] < delta) 22 | delta = minv[j], j1 = j; 23 | } 24 | for (int j = 0; j <= m; ++j) 25 | if (used[j]) 26 | u[p[j]] += delta, v[j] -= delta; 27 | else 28 | minv[j] -= delta; 29 | j0 = j1; 30 | } while (p[j0] != 0); 31 | do { 32 | int j1 = way[j0]; 33 | p[j0] = p[j1]; 34 | j0 = j1; 35 | } while (j0); 36 | } 37 | matchL = VI(n, -1), matchR = VI(m); 38 | for (int j = 1; j <= m; ++j) if (p[j]) matchL[p[j] - 1] = j - 1; 39 | for (int j = 1; j <= m; ++j) matchR[j - 1] = p[j] - 1; 40 | return cost = -v[0]; 41 | } 42 | }; -------------------------------------------------------------------------------- /Codes/Graph/MaxFlow[Dinics-EdgeList].cpp: -------------------------------------------------------------------------------- 1 | // Adjacency list implementation of Dinic's blocking flow algorithm. 2 | // This is very fast in practice, and only loses to push-relabel flow. 3 | // 4 | // Running time: 5 | // O(|V|^2 |E|) 6 | // 7 | // INPUT: 8 | // - graph, constructed using AddEdge() 9 | // - source 10 | // - sink 11 | // 12 | // OUTPUT: 13 | // - maximum flow value 14 | // - To obtain the actual flow values, look at all edges with 15 | // capacity > 0 (zero capacity edges are residual edges). 16 | // SOURCE: 17 | // - http://www.stanford.edu/~liszt90/acm/notebook.html#file1 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | using namespace std; 25 | 26 | const int INF = 2000000000; 27 | 28 | struct Edge { 29 | int from, to, cap, flow, index; 30 | Edge(int from, int to, int cap, int flow, int index) : 31 | from(from), to(to), cap(cap), flow(flow), index(index) {} 32 | }; 33 | 34 | struct Dinic { 35 | int N; 36 | vector > G; 37 | vector dad; 38 | vector Q; 39 | 40 | Dinic(int N) : N(N), G(N), dad(N), Q(N) {} 41 | 42 | void AddEdge(int from, int to, int cap) { 43 | G[from].push_back(Edge(from, to, cap, 0, G[to].size())); 44 | if (from == to) G[from].back().index++; 45 | G[to].push_back(Edge(to, from, 0, 0, G[from].size() - 1)); 46 | } 47 | 48 | long long BlockingFlow(int s, int t) { 49 | fill(dad.begin(), dad.end(), (Edge *) NULL); 50 | dad[s] = &G[0][0] - 1; 51 | 52 | int head = 0, tail = 0; 53 | Q[tail++] = s; 54 | while (head < tail) { 55 | int x = Q[head++]; 56 | for (int i = 0; i < G[x].size(); i++) { 57 | Edge &e = G[x][i]; 58 | if (!dad[e.to] && e.cap - e.flow > 0) { 59 | dad[e.to] = &G[x][i]; 60 | Q[tail++] = e.to; 61 | } 62 | } 63 | } 64 | if (!dad[t]) return 0; 65 | 66 | long long totflow = 0; 67 | for (int i = 0; i < G[t].size(); i++) { 68 | Edge *start = &G[G[t][i].to][G[t][i].index]; 69 | int amt = INF; 70 | for (Edge *e = start; amt && e != dad[s]; e = dad[e->from]) { 71 | if (!e) { amt = 0; break; } 72 | amt = min(amt, e->cap - e->flow); 73 | } 74 | if (amt == 0) continue; 75 | for (Edge *e = start; amt && e != dad[s]; e = dad[e->from]) { 76 | e->flow += amt; 77 | G[e->to][e->index].flow -= amt; 78 | } 79 | totflow += amt; 80 | } 81 | return totflow; 82 | } 83 | 84 | long long GetMaxFlow(int s, int t) { 85 | long long totflow = 0; 86 | while (long long flow = BlockingFlow(s, t)) 87 | totflow += flow; 88 | return totflow; 89 | } 90 | }; 91 | 92 | //int main() 93 | //{ 94 | // cin.sync_with_stdio(false); 95 | // 96 | // 97 | // 98 | // 99 | // 100 | // 101 | // return 0; 102 | //} 103 | 104 | 105 | -------------------------------------------------------------------------------- /Codes/Graph/MaximumMatching.cpp: -------------------------------------------------------------------------------- 1 | struct MaxMatching { 2 | int L, R; 3 | vector ML, MR; 4 | VVI adj; 5 | MaxMatching(int L,int R) : ML(L,-1), MR(R,-1), adj(L), L(L), R(R) {} 6 | void AddEdge(int u, int v){ 7 | adj[u].push_back(v); 8 | } 9 | int findMatch(int u, VI &VIS) { 10 | if (VIS[u]) return 0; 11 | VIS[u] = 1; 12 | for (int v : adj[u]) { 13 | if (MR[v] == -1 || findMatch(MR[v], VIS)) { 14 | MR[v] = u; 15 | ML[u] = v; 16 | return 1; 17 | } 18 | } 19 | return 0; 20 | } 21 | int run() { 22 | VI VIS(L); 23 | int cnt = 0; 24 | for (int i = 0; i < L; ++i) { 25 | VIS = VI(L); 26 | cnt += findMatch(i, VIS); 27 | } 28 | return cnt; 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /Codes/Graph/NOT_WORKING_MincostMaxflow[AdjMatrix].cpp: -------------------------------------------------------------------------------- 1 | // SOURCE: 2 | // - http://www.stanford.edu/~liszt90/acm/notebook.html#file2 3 | // - http://ideone.com/h1p9o4 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | typedef long long Long; 12 | typedef vector VL; 13 | typedef vector VVL; 14 | typedef vector VPII; 15 | const Long INF = numeric_limits::max() / 4; 16 | struct MinCostMaxFlow { 17 | int N; 18 | VVL cap, flow, cost; 19 | VL dist, pi, width , found; 20 | VPII P; 21 | MinCostMaxFlow(int N) { 22 | this->N = N; 23 | cap = flow = cost= VVL(N,VL(N)); 24 | found = dist = pi = width = VL(N); 25 | P = VPII(N); 26 | } 27 | void AddEdge(int from, int to, Long cap, Long cost) { 28 | this->cap[from][to] = cap; 29 | this->cost[from][to] = cost; 30 | } 31 | Long Dijkstra(int s, int t) { 32 | fill(found.begin(), found.end(), false); 33 | fill(dist.begin(), dist.end(), INF); 34 | fill(width.begin(), width.end(), 0); 35 | dist[s] = 0; 36 | width[s] = INF; 37 | priority_queue PQ; 38 | PQ.push(PII(0, s)); 39 | while (PQ.size()) { 40 | int u = PQ.top().second; 41 | PQ.pop(); 42 | if (found[u]) continue; 43 | found[u] = true; 44 | for (int k = 0; k < N; k++) { 45 | if (found[k]) continue; 46 | int ca, nd; 47 | ca = cap[u][k] - flow[u][k], nd = dist[u] + pi[u] - pi[k] + cost[u][k]; 48 | if (ca && nd < dist[k]) 49 | dist[k] = nd, width[k] = ca, PQ.push(PII(-nd, k)), P[k] = PII(u, 1); 50 | ca = -flow[k][u], nd = dist[u] + pi[u] - pi[k] - cost[k][u]; 51 | if (ca && nd < dist[k]) 52 | dist[k] = nd, width[k] = ca, PQ.push(PII(-nd, k)), P[k] = PII(u, -1); 53 | } 54 | } 55 | for (int k = 0; k < N; k++) 56 | pi[k] = min(pi[k] + dist[k], INF); 57 | return width[t]; 58 | } 59 | pair GetMaxFlow(int s, int t) { 60 | Long totflow = 0, totcost = 0; 61 | while (Long amt = Dijkstra(s, t)) { 62 | totflow += amt; 63 | for (int x = t; x != s; x = P[x].first) { 64 | int d = P[x].second , u = P[x].first , v = x; 65 | if(d==-1)swap(u,v); 66 | flow[u][v] += amt * d; 67 | totcost += amt * cost[u][v] * d; 68 | } 69 | } 70 | return make_pair(totflow, totcost); 71 | } 72 | }; 73 | -------------------------------------------------------------------------------- /Codes/Graph/README.md: -------------------------------------------------------------------------------- 1 | # Graph 2 | ## [2-SAT](./Codes/Graph/2-SAT.cpp): 3 | * 1-based implementation of 2-Satisfiability Problem (positive numbers for positive propositions and negative number for negative propositions. 4 | 5 | ## [Connected Components](/Codes/Graph/ConnectedComponnents.cpp) 6 | * Note: Need to extract necesary code for each of the following subproblems. 7 | * StronglyConnectedComponents 8 | * BiconnectedComponents 9 | * ArticulationPointsAndBridges 10 | 11 | ## [Count Number of Minimum Spanning Trees](/Codes/Graph/CountMinimumSpanningTree.cpp) 12 | * This is uses Count Number of Spanning Trees and [mint](/Codes/Math/ModInt.cpp#L68) 13 | 14 | ## [Count Number of Spanning Trees](/Codes/Graph/CountSpanningTree.cpp) 15 | * Note: Code is equivalent to building the matrix with addEdge and finding determinant. [mint](/Codes/Math/ModInt.cpp#L68) is just a ModularInt with the defined operations (/, *, +, -) [note modular division needed] 16 | 17 | ## [Eulerian Path And Cycle](/Codes/Graph/EulerianPathAndCycle) 18 | * Finds an eulerian path or a cycle in O(N) 19 | 20 | ## [HopcroftCarp](/Codes/Graph/EulerianPathAndCycle) 21 | * Maximum matching O(sqrt(V)*E) 22 | 23 | ## [Hungarian Algorithm](/Graph/MaxFlow%5BDinics-EdgeList%5D.cpp) 24 | * Finds a weighted maximum matching in O(V^3) best for dense graphs, for non complete graphs use INF as edge cost, an alternative is to run MinCostMaxFlow. 25 | 26 | ## [MaxFlow](/Codes/Graph/MincostMaxflow%5BAdjMatrix%5D.cpp) 27 | * Has a running time of O(|V|^2 |E|). 28 | * Can be used to find MaximumMatching and runs relatively fast, in theory same complexity as HopcroftCarp if all edges has capacity 1. 29 | 30 | ## [MinCostMaxFlow](/Codes/Graph/MincostMaxflow%5BAdjMatrix%5D.cpp) 31 | * Can be a substitute of HungarianAlgorithm and also other MaxFlow with costs involved. 32 | 33 | ## [VertextCover](/Codes/Graph/VertexCover.cpp) 34 | * Can find a minimum vertex cover after a maximum matching is provided. 35 | * NOTE: It does not have MaxMatching you have to run MaxMatching and then pass the matching to this algorithm. 36 | -------------------------------------------------------------------------------- /Codes/Graph/VertexCover.cpp: -------------------------------------------------------------------------------- 1 | typedef vector VI; 2 | typedef vector VVI; 3 | struct Konig { 4 | vector ML, MR; 5 | VVI adj; 6 | int L,R, mm; 7 | Konig(int L,int R) : ML(L,-1), MR(R,-1), adj(L), L(L), R(R), mc(0) {} 8 | void AddEdge(int u, int v){ 9 | adj[u].push_back(v); 10 | } 11 | void setMatch(int u, int v){ 12 | ML[u] = v; 13 | MR[v] = u; 14 | mm++; 15 | } 16 | pair< vector , vector > getCover() { 17 | queue QL; 18 | vector VIS_L(L), VIS_R(R); 19 | for(int i = 0; i < L; ++i){ 20 | if(ML[i] == -1){ 21 | QL.push(i); 22 | VIS_L[i] = 1; 23 | } 24 | } 25 | while(QL.size()){ 26 | int u = QL.front(); QL.pop(); 27 | for(int i = 0; i < adj[u].size(); ++i){ 28 | int v = adj[u][i]; 29 | VIS_R[v] = 1; 30 | if(MR[v] != -1 && !VIS_L[ MR[v] ]) { 31 | VIS_L[MR[v]] = 1; 32 | QL.push(MR[v]); 33 | } 34 | } 35 | } 36 | vector AL, AR; 37 | for(int i = 0; i < L; ++i) 38 | if(!VIS_L[i]) AL.push_back(i); 39 | for(int i = 0; i < R; ++i) 40 | if(VIS_R[i]) AR.push_back(i); 41 | assert(mm == AL.size() + AR.size()); 42 | return make_pair(AL,AR); 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /Codes/Math/BigPrimes.cpp: -------------------------------------------------------------------------------- 1 | namespace BigPrimes { 2 | typedef long long ll; 3 | ll gcd(ll a, ll b) { 4 | return a ? gcd(b % a, a) : b; 5 | } 6 | 7 | ll mulmod(ll a, ll b, ll c) { //returns (a*b)%c, and minimize overfloor 8 | return ((__int128_t ) a * b) % c; 9 | ll x = 0, y = a % c; 10 | while (b > 0) { 11 | if (b % 2 == 1) 12 | x = (x + y) % c; 13 | y = (y * 2) % c; 14 | b /= 2; 15 | } 16 | return x % c; 17 | } 18 | 19 | ll expmod(ll b, ll e, ll m) { //O(log b) 20 | if (!e) 21 | return 1; 22 | ll q = expmod(b, e / 2, m); 23 | q = mulmod(q, q, m); 24 | return e % 2 ? mulmod(b, q, m) : q; 25 | } 26 | 27 | bool es_primo_prob(ll n, int a) { 28 | if (n == a) 29 | return true; 30 | ll s = 0, d = n - 1; 31 | while (d % 2 == 0) 32 | s++, d /= 2; 33 | 34 | ll x = expmod(a, d, n); 35 | if ((x == 1) || (x + 1 == n)) 36 | return true; 37 | for (int i = 0; i < s-1; ++i) { 38 | x = mulmod(x, x, n); 39 | if (x == 1) 40 | return false; 41 | if (x + 1 == n) 42 | return true; 43 | } 44 | return false; 45 | } 46 | 47 | bool rabinPrime(ll n) { //devuelve true si n es primo 48 | if (n == 1) 49 | return false; 50 | const int ar[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37 }; 51 | for(int j = 0; j < 12; ++j) 52 | if (!es_primo_prob(n, ar[j])) 53 | return false; 54 | return true; 55 | } 56 | 57 | ll rho(ll n) { 58 | if ((n & 1) == 0) 59 | return 2; 60 | ll x = 2, y = 2, d = 1; 61 | ll c = rand() % n + 1; 62 | while (d == 1) { 63 | x = (mulmod(x, x, n) + c) % n; 64 | y = (mulmod(y, y, n) + c) % n; 65 | y = (mulmod(y, y, n) + c) % n; 66 | if (x - y >= 0) 67 | d = gcd(x - y, n); 68 | else 69 | d = gcd(y - x, n); 70 | } 71 | return d == n ? rho(n) : d; 72 | } 73 | void factRho(ll n, map &prim) { // O( (logN)^3 ) 74 | if (n == 1) 75 | return; 76 | if (rabinPrime(n)) { 77 | prim[n]++; 78 | return; 79 | } 80 | ll factor = rho(n); 81 | factRho(factor, prim); 82 | factRho(n / factor, prim); 83 | } 84 | } -------------------------------------------------------------------------------- /Codes/Math/BitVector.cpp: -------------------------------------------------------------------------------- 1 | struct BitVector { 2 | typedef unsigned long long ULong; 3 | vector bits; 4 | vector acu; 5 | struct reference { 6 | BitVector &o; int p, b; 7 | reference(BitVector &o, int p) : o(o), p(p/64), b(p&63) { } 8 | bool operator=(bool v) const { 9 | if (v) o.bits[p] |= 1ULL << b; 10 | else o.bits[p] &= ~(1ULL << b); 11 | return v; 12 | } 13 | }; 14 | BitVector(ULong n = 0) : bits(1, n), acu(1, __builtin_popcountll(n)) { recompute(); } 15 | BitVector(string s, char one = '1') { 16 | reverse(s.begin(), s.end()); 17 | bits = vector(s.size() / 64 + 1); 18 | for (int i = 0; i < s.size(); ++i) 19 | if (s[i] == one) 20 | bits[i / 64] |= 1ULL << (i & 63); 21 | while (bits.size() > 1 && bits.back() == 0) bits.pop_back(); 22 | recompute(); 23 | } 24 | BitVector& operator<<=(const int n) { 25 | int osz = bits.size(); 26 | int whole = n / 64; 27 | int extra = n % 64; 28 | bits.resize(bits.size() + n / 64 + 1); 29 | for (int i = osz - 1; i >= 0; --i) { 30 | ULong x = bits[i]; bits[i] = 0; 31 | bits[i + whole] |= x << extra; 32 | bits[i + whole + 1] |= x >> (64 - extra); 33 | } 34 | while (bits.size() > 1 && bits.back() == 0) bits.pop_back(); 35 | recompute(); 36 | } 37 | BitVector operator<<(const int n) { 38 | BitVector o = *this; o <<= n; return o; 39 | } 40 | BitVector& operator>>=(const int n) { 41 | int whole = n / 64; 42 | int extra = n % 64; 43 | for (int i = 0; i < whole; ++i) bits[i] = 0; 44 | for (int i = whole; i < bits.size(); ++i) { 45 | ULong x = bits[i]; bits[i] = 0; 46 | bits[i - whole] |= x >> extra; 47 | bits[i - whole - 1] |= x << (64 - extra); 48 | } 49 | while (bits.size() > 1 && bits.back() == 0) bits.pop_back(); 50 | recompute(); 51 | } 52 | BitVector operator>>(const int n) { 53 | BitVector o = *this; o >>= n; return o; 54 | } 55 | BitVector operator&(const BitVector o) const { 56 | BitVector r; 57 | r.bits.resize(min(bits.size(), o.bits.size())); 58 | for (int i = 0; i < r.bits.size(); ++i) r.bits[i] = bits[i] & o.bits[i]; 59 | return r; 60 | } 61 | reference operator[](int p) { return reference(*this, p); } 62 | bool operator[](int p) const { return (bits[p / 64] >> (p & 63)) & 1; } 63 | void recompute() { 64 | acu.resize(bits.size()); 65 | for (int i = 0; i < bits.size(); ++i) { 66 | acu[i] = __builtin_popcountll(bits[i]); 67 | if (i > 0) acu[i] += acu[i-1]; 68 | } 69 | } 70 | friend ostream &operator<<(ostream &os, const BitVector &bitVector) { 71 | for (int i = bitVector.bits.size() - 1; i >= 0; --i) { 72 | os << bitset<64>(bitVector.bits[i]); 73 | } 74 | return os; 75 | } 76 | }; 77 | -------------------------------------------------------------------------------- /Codes/Math/Convolution.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.util.ArrayList; 3 | import java.util.Arrays; 4 | import java.util.Collections; 5 | import java.util.StringTokenizer; 6 | import java.io.BufferedReader;; 7 | 8 | public class Main { 9 | static int MOD = 1000000007; 10 | 11 | public static void main(String[] args) { 12 | // TODO Auto-generated method stub 13 | Double a[] = {1.0, 3.0, 4.0, 5.0, 7.0}; 14 | Double b[] = {2.0, 4.0, 6.0}; 15 | 16 | FFT fft = new FFT(); 17 | ArrayList c = fft.Convolution( 18 | (ArrayList) Arrays.asList(a), 19 | (ArrayList) Arrays.asList(b) 20 | ); 21 | for(Double d : c){ 22 | System.out.println(d); 23 | } 24 | 25 | } 26 | static class Complex { 27 | double x,y; 28 | Complex(double x, double y){ 29 | this.x = x; 30 | this.y = y; 31 | } 32 | double real(){ 33 | return x; 34 | } 35 | Complex multiply(Complex c){ 36 | return new Complex(x*c.x - y*c.y, x*c.y + y*c.x); 37 | } 38 | Complex divide(Complex c){ 39 | double m = c.x*c.x - c.y*c.y; 40 | return new Complex(x / m , y / m).multiply(new Complex(c.x,-c.y)); 41 | } 42 | Complex add(Complex c){ 43 | return new Complex(x+c.x,y+c.y); 44 | } 45 | static Complex exp(Complex c){ 46 | return new Complex(c.x*Math.cos(c.y), c.x*Math.sin(c.y)); 47 | } 48 | static Complex ONE(){ 49 | return new Complex(1,0); 50 | } 51 | static Complex ZERO(){ 52 | return new Complex(0,0); 53 | } 54 | } 55 | static class FFT 56 | { 57 | public FFT(){ 58 | 59 | } 60 | ArrayList A; 61 | int n, L; 62 | 63 | int ReverseBits(int k) { 64 | int ret = 0; 65 | for (int i = 0; i < L; i++) { 66 | ret = (ret << 1) | (k & 1); 67 | k >>= 1; 68 | } 69 | return ret; 70 | } 71 | 72 | void BitReverseCopy(ArrayList a) { 73 | for (n = 1, L = 0; n < a.size(); n <<= 1, L++) 74 | ; 75 | A.addAll(Collections.nCopies(n-A.size(), new Complex(0,0))); 76 | for (int k = 0; k < n; k++) 77 | A.set(ReverseBits(k), a.get(k)); 78 | } 79 | 80 | ArrayList DFT(ArrayList a, boolean inverse) { 81 | BitReverseCopy(a); 82 | for (int s = 1; s <= L; s++) { 83 | int m = 1 << s; 84 | Complex wm = Complex.exp(new Complex(0.0, 2.0 * Math.PI / m)); 85 | if (inverse) 86 | wm = Complex.ONE().divide(wm); 87 | for (int k = 0; k < n; k += m) { 88 | Complex w = Complex.ONE(); 89 | for (int j = 0; j < m / 2; j++) { 90 | Complex t = w.multiply(A.get(k + j + m / 2)); 91 | Complex u = w.multiply(A.get(k + j)); 92 | A.set(k + j, u.add(t)); 93 | A.set(k + j + m / 2, u.add(t)); 94 | w = w.multiply(wm); 95 | } 96 | } 97 | } 98 | if (inverse) 99 | for (int i = 0; i < n; i++) 100 | A.get(i).divide(new Complex(n,0)); 101 | return A; 102 | } 103 | 104 | // c[k] = sum_{i=0}^k a[i] b[k-i] 105 | ArrayList Convolution(ArrayList a, ArrayList b) { 106 | int L = 1; 107 | while ((1 << L) < a.size()) 108 | L++; 109 | while ((1 << L) < b.size()) 110 | L++; 111 | int n = 1 << (L + 1); 112 | 113 | ArrayList aa = new ArrayList(); 114 | ArrayList bb = new ArrayList(); 115 | for (int i = 0; i < n; i++) 116 | aa.add(i < a.size() ? new Complex(a.get(i), 0) : Complex.ZERO()); 117 | for (int i = 0; i < n; i++) 118 | bb.add(i < b.size() ? new Complex(b.get(i), 0) : Complex.ZERO()); 119 | 120 | ArrayList AA = DFT(aa, false); 121 | ArrayList BB = DFT(bb, false); 122 | ArrayList CC = new ArrayList(); 123 | for (int i = 0; i < AA.size(); i++) 124 | CC.add(AA.get(i).multiply(BB.get(i))); 125 | ArrayList cc = DFT(CC, true); 126 | 127 | ArrayList c = new ArrayList(); 128 | for (int i = 0; i < a.size() + b.size() - 1; i++) 129 | c.add(cc.get(i).real()); 130 | return c; 131 | } 132 | 133 | } 134 | 135 | } 136 | -------------------------------------------------------------------------------- /Codes/Math/DiscreteLogarithm-PollardRho.cpp: -------------------------------------------------------------------------------- 1 | 2 | int modPow(int b, int e, int m) { 3 | if (e == 0) return 1; 4 | int sq = modPow(b, e >> 1, m); 5 | sq = 1LL * sq * sq % m; 6 | return (e & 1) ? (sq * 1LL * b % m) : sq; 7 | } 8 | // a*x = b (mod m) 9 | int solveLinearCongruence(int a, int b, int m) { 10 | if (b == 0) return 0; 11 | if (a == 0) return -1; 12 | if (a == 1) return b; 13 | int y = solveLinearCongruence(m % a, (-b % a + a) % a, a); 14 | return y < 0 ? y : (1LL*m*y+b) / a % m; 15 | } 16 | // a^output = b 17 | int discreteLogarithm2(int a, int b, int m) { 18 | int o = m-1; 19 | auto sub = [] (int a, int b, int m) { return ((a - b) % m + m) % m; }; 20 | auto gen = [&](Long &x, Long &p, Long &q) { 21 | switch (x % 3) { 22 | case 0: x = x * x % m, p = p * 2 % o, q = q * 2 % o; break; 23 | case 1: x = x * a % m, p = (p == o-1) ? 0 : p+1; break; 24 | case 2: x = x * b % m, q = (q == o-1) ? 0 : q+1; break; 25 | } 26 | }; 27 | Long x = 1, p = 0, q = 0; 28 | Long X = x, P = p, Q = q; 29 | for (int i = 1; ; ++i) { 30 | gen(x, p, q); 31 | gen(X, P, Q); gen(X, P, Q); // double step 32 | if (x == X) { 33 | int r = sub(q, Q, o); 34 | int num = sub(P, p, o); 35 | if (r == 0) return -1; 36 | int gc = __gcd(r, o); 37 | int s = solveLinearCongruence(r, num, o); 38 | if (s == -1) return -1; 39 | for (int t = 0; t < gc; ++t) { 40 | int cn = s + o / gc * t; 41 | if (modPow(a, cn, m) == b) { 42 | return cn; 43 | } 44 | } 45 | return -1; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Codes/Math/DiscreteLogarithm.cpp: -------------------------------------------------------------------------------- 1 | Long discreteLogarithm(Long base, Long x, Long mod) { 2 | assert(x > 0); 3 | if (x == 1) return 0; 4 | Long n = (int) sqrt (mod) + 1; 5 | Long an = 1; 6 | for (int i = 0; i value; 9 | for (Long i = 1, cur = an; i<= n; ++i) { 10 | if (value.count(cur) == 0) 11 | value[ cur ] = i; 12 | cur = (cur * an) % mod; 13 | } 14 | for (Long i = 0, cur = x; i<= n; ++i) { 15 | if (value.count(cur)) { 16 | Long ans = value[cur] * n - i; 17 | if (ans < mod) 18 | return ans; 19 | } 20 | cur = (cur * base) % mod; 21 | } 22 | return -1; 23 | } 24 | -------------------------------------------------------------------------------- /Codes/Math/EducationalFFT.cpp: -------------------------------------------------------------------------------- 1 | namespace EducationalFFT { 2 | /* 3 | X0,...,N−1 ← ditfft2(x, N, s): DFT of (x0, xs, x2s, ..., x(N-1)s): 4 | if N = 1 then 5 | X0 ← x0 trivial size-1 DFT base case 6 | else 7 | X0,...,N/2−1 ← ditfft2(x, N/2, 2s) DFT of (x0, x2s, x4s, ...) 8 | XN/2,...,N−1 ← ditfft2(x+s, N/2, 2s) DFT of (xs, xs+2s, xs+4s, ...) 9 | for k = 0 to N/2−1 combine DFTs of two halves into full DFT: 10 | t ← Xk 11 | Xk ← t + exp(−2πi s k/N) Xk+N/2 12 | Xk+N/2 ← t − exp(−2πi s k/N) Xk+N/2 13 | endfor 14 | endif 15 | */ 16 | typedef complex Complex; 17 | long double PI = acos(-1.0L); 18 | struct ExpBucket { 19 | vector E, I; 20 | int N; 21 | ExpBucket(int N):E(N), I(N),N(N){ 22 | for(int i = 0; i < N; ++i){ 23 | E[i] = exp(Complex(0, -2.0L*PI*i/N)); 24 | I[i] = exp(Complex(0, 2.0L*PI*i/N)); 25 | } 26 | } 27 | Complex get(int i, int n, int inv){ 28 | i *= N / n; 29 | return inv == 1 ? E[i] : I[i]; 30 | } 31 | }; 32 | vector dft(ExpBucket &E, const vector &x, int n, int inv = 1, int st = 0, int s = 1) { 33 | if(n == 1){ 34 | return vector(1, x[st]); 35 | } 36 | vector X0 = dft(E, x, n/2, inv, st, 2*s); 37 | vector X1 = dft(E, x, n/2, inv, st + s, 2*s); 38 | vector X; 39 | X.insert(X.end(), X0.begin(), X0.end()); 40 | X.insert(X.end(), X1.begin(), X1.end()); 41 | for(int k = 0; k <= n/2-1; ++k){ 42 | Complex a = X[k]; 43 | Complex b = X[k + n/2]; 44 | /* sin(2*pi*s*i/n) */ 45 | long double ang = -2*PI*k/n*inv; 46 | Complex eb = exp(Complex(0, ang)) * b; 47 | X[k] = a + eb ; 48 | X[k+n/2] = a - eb; 49 | } 50 | return X; 51 | } 52 | vector convolution(vector A, vector B){ 53 | int n = max(A.size(), B.size()); 54 | reverse(B.begin(),B.end()); 55 | while( n != (n & -n))n++; 56 | n <<= 1; 57 | A.resize(n); 58 | B.resize(n); 59 | ExpBucket E(n); 60 | A = dft(E, A, A.size(), 1); 61 | B = dft(E, B, B.size(), 1); 62 | for (int i = 0; i < A.size(); ++i) { 63 | A[i] = A[i] * B[i]; 64 | } 65 | vector C = dft(E, A, A.size(), -1); 66 | for (Complex &v : C) { 67 | if(abs(v.real()) < 1e-9)v.real(0); 68 | if(abs(v.imag()) < 1e-9)v.imag(0); 69 | v.real(v.real() / A.size()); 70 | v.imag(v.imag() / A.size()); 71 | assert(abs(v.imag()) < 0.2); 72 | assert(abs(v.real() - round(v.real())) < 0.2); 73 | } 74 | return C; 75 | } 76 | vector convolution2(vector A, vector B){ 77 | int n = max(A.size(), B.size()); 78 | reverse(B.begin(),B.end()); 79 | while( n != (n & -n))n++; 80 | n <<= 1; 81 | A.resize(n); 82 | B.resize(n); 83 | ExpBucket E(n); 84 | vector T(n); 85 | for (int i = 0; i < n; ++i) { 86 | T[i] = Complex(A[i].real(), B[i].real()); 87 | } 88 | T = dft(E, T, T.size(), 1); 89 | vector T2(n); 90 | for (int i = 0; i < n; ++i) { 91 | Complex X = (T[i] + conj(T[(n - i) % n])) / Complex(2, 0); 92 | Complex Y = (T[i] - conj(T[(n - i) % n])) / Complex(0, 2); 93 | T2[i] = X*Y; 94 | } 95 | vector C = dft(E, T2, T2.size(), -1); 96 | for (Complex &v : C) { 97 | if(abs(v.real()) < 1e-9)v.real(0); 98 | if(abs(v.imag()) < 1e-9)v.imag(0); 99 | v.real(v.real() / A.size()); 100 | v.imag(v.imag() / A.size()); 101 | assert(abs(v.imag()) < 0.2); 102 | assert(abs(v.real() - round(v.real())) < 0.2); 103 | } 104 | return C; 105 | } 106 | } -------------------------------------------------------------------------------- /Codes/Math/Equations/BitGauss.cpp: -------------------------------------------------------------------------------- 1 | template 2 | vector bitGauss(VVI m){ // last column is arbitratry integer 3 | int R = m.size(), C = m[0].size(); 4 | vector> B(R); 5 | for (int i = 0; i < R; ++i) { 6 | for (int j = 0; j < C; ++j) { 7 | B[i][j] = m[i][j]; 8 | } 9 | } 10 | int pivot = 0; 11 | for (int r = 0; r < R && pivot+1 < C; ) { 12 | bool f = 0; 13 | for (int i = r; i < B.size(); ++i) { 14 | if(B[i][pivot]){ 15 | f = 1; 16 | swap(B[i], B[r]); 17 | break; 18 | } 19 | } 20 | if(f){ 21 | for (int i = r+1; i < B.size(); ++i) { 22 | if(B[i][pivot]){ 23 | B[i] ^= B[r]; 24 | } 25 | } 26 | r++; 27 | } 28 | pivot++; 29 | } 30 | for (int i = R-1; i >= 0; --i) { 31 | for (int j = 0; j < C; ++j) { 32 | if(B[i][j]){ 33 | for (int k = i-1; k >= 0; --k) { 34 | if(B[k][j]){ 35 | B[k] ^= B[i]; 36 | } 37 | } 38 | break; 39 | } 40 | } 41 | } 42 | for (int i = 0; i < R; ++i) { 43 | for (int j = 0; j < C; ++j) { 44 | m[i][j] = B[i][j]; 45 | } 46 | } 47 | return m; 48 | } -------------------------------------------------------------------------------- /Codes/Math/Equations/GaussDouble.cpp: -------------------------------------------------------------------------------- 1 | vector> gauss(vector> m){ 2 | int pivot = 0; 3 | for (int r = 0; r < m.size() && pivot+1 < m[0].size(); ) { 4 | int f = 0; 5 | for (int i = r; i < m.size(); ++i) { 6 | if(abs(m[i][pivot]) > 1e-5){ 7 | f = 1; 8 | swap(m[i], m[r]); 9 | break; 10 | } 11 | } 12 | if(f){ 13 | for (int j = m[0].size()-1; j >= pivot ; --j) { 14 | m[r][j] /= m[r][pivot]; 15 | } 16 | for (int i = r+1; i < m.size(); ++i) { 17 | if(m[i][pivot]){ 18 | for (int j = m[0].size()-1; j >= pivot; --j) { 19 | OPS++; 20 | m[i][j] -= m[i][pivot] * m[r][j]; 21 | } 22 | } 23 | } 24 | r++; 25 | } 26 | pivot++; 27 | } 28 | for (int i = m.size()-1; i >= 0; --i) { 29 | for (int j = 0; j+1 < m[0].size(); ++j) { 30 | if(m[i][j]){ 31 | for (int k = i-1; k >= 0; --k) { 32 | if(m[k][j]){ 33 | for (int l = m[0].size()-1; l >= j; --l) { 34 | OPS++; 35 | m[k][l] -= m[k][j] * m[i][l]; 36 | } 37 | } 38 | } 39 | break; 40 | } 41 | } 42 | } 43 | return m; 44 | } -------------------------------------------------------------------------------- /Codes/Math/Equations/VectorSpace.cpp: -------------------------------------------------------------------------------- 1 | #define DIM 10 2 | typedef bitset vec; 3 | struct VectorSpace { 4 | int cnt, cols; 5 | vector< vec > R; // rules to apply to that row 6 | vector< vec > V; 7 | VectorSpace(): cnt(0), cols(0), R(DIM), V(DIM) { 8 | for (int i = 0; i < DIM; ++i) 9 | R[i][i] = 1; 10 | } 11 | void add(vec nv) { // DIM^2 / 64 12 | cnt++; 13 | if (cols == DIM) return; // space complete 14 | if (nv.none()) return; 15 | vec nc = applyRules(nv); 16 | int firstOne = findFirstOne(nc, cols); 17 | if (firstOne == -1) return; 18 | nc[firstOne] = 0; nc[cols] = 1; // swap 19 | swap(R[firstOne], R[cols]); 20 | for (int i = cols+1; i < DIM; ++i) { 21 | if (nc[i]) { 22 | nc[i] = 0; 23 | R[i] = R[i] ^ R[cols]; 24 | } 25 | } 26 | for (int i = 0; i < DIM; ++i) { 27 | V[i][cols] = nc[i]; 28 | } 29 | cols++; 30 | } 31 | vec applyRules(const vec &nv) { // DIM^2 / 64 32 | vec ret; 33 | for (int i = 0; i < DIM; ++i) { // apply rules for all rows 34 | ret[i] = (nv & R[i]).count() & 1; 35 | } 36 | return ret; 37 | } 38 | static int findFirstOne(const vec &nv, int start = 0) { // DIM 39 | for (int i = start; i < DIM; ++i) { 40 | if (nv[i]) return i; 41 | } 42 | return -1; 43 | } 44 | bool possible(const vec &nv) { 45 | vec nc = applyRules(nv); 46 | return findFirstOne(nc, cols) == -1; 47 | 48 | } 49 | int ways(const vec &nv) { 50 | vec nc = applyRules(nv); 51 | if (findFirstOne(nc, cols) != -1) return 0; 52 | return pow(2.0, cnt - cols); // use modPow if needed 53 | } 54 | }; 55 | -------------------------------------------------------------------------------- /Codes/Math/Factors.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | struct Factors 5 | { 6 | static vector factorize(int N) 7 | { 8 | vector ANS; ANS.reserve(200); 9 | while(N % 2 == 0) ANS.push_back(2), N /= 2; 10 | for(int i = 3; i*i <= N && N > 1; i += 2) 11 | { 12 | while(N % i == 0) 13 | { 14 | ANS.push_back(i); 15 | N /= i; 16 | } 17 | } 18 | if(N > 1)ANS.push_back(N); 19 | return ANS; 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /Codes/Math/FastestFFT.cpp: -------------------------------------------------------------------------------- 1 | typedef long long Long; 2 | typedef long double Double; 3 | typedef long long Long; 4 | typedef vector VI; 5 | struct point { 6 | Double x, y; 7 | point(Double x = 0, Double y = 0) : x(x), y(y) { } 8 | point conjugate() const { return point(x, -y); } 9 | }; 10 | point operator+(const point &a, const point &b) { return {a.x + b.x, a.y + b.y}; } 11 | point operator-(const point &a, const point &b) { return {a.x - b.x, a.y - b.y}; } 12 | point operator*(const point &a, const point &b) { return {a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x}; } 13 | point operator/(const point &a, Double d) { return {a.x / d, a.y / d}; } 14 | void fft(vector &a, int sign = +1) { 15 | int n = a.size(); 16 | for (int i = 1, j = 0; i < n - 1; ++i) { 17 | for (int k = n >> 1; (j ^= k) < k; k >>= 1); 18 | if (i < j) swap(a[i], a[j]); 19 | } 20 | Double theta = 2 * atan2(0, -1) * sign; 21 | for (int m, mh = 1; (m = mh << 1) <= n; mh = m) { 22 | point wm(cos(theta / m), sin(theta / m)), w(1, 0); 23 | for (int i = 0; i < n; i += m, w = point(1, 0)) 24 | for (int j = i, k = j + mh; j < i + mh; ++j, ++k, w = w * wm) { 25 | point x = a[j], y = a[k] * w; 26 | a[j] = x + y; 27 | a[k] = x - y; 28 | } 29 | } 30 | if (sign == -1) for (point &p : a) p = p / n; 31 | } 32 | VI convolution(const VI &a, const VI &b, int isStraight = true) { 33 | vector ca(a.size()), cb(b.size()); 34 | for (int i = 0; i < ca.size(); ++i) ca[i] = a[i]; 35 | for (int i = 0; i < cb.size(); ++i) cb[i] = b[i]; 36 | int L = 1; 37 | if (isStraight) reverse(cb.begin(), cb.end()); 38 | while (L < a.size() + b.size() - 1) L *= 2; 39 | ca.resize(L); cb.resize(L); 40 | vector c(L); 41 | fft(ca, 1); fft(cb, 1); 42 | for (int i = 0; i < L; ++i) c[i] = ca[i] * cb[i]; 43 | fft(c, -1); 44 | c.resize(a.size() + b.size() - 1); 45 | vector cc(c.size()); 46 | for (int i = 0; i < c.size(); ++i) 47 | cc[i] = round(c[i].x); // dont truncate use round 48 | return cc; 49 | } 50 | // add code below for BigConvolution 51 | point operator/(const point &a, const point &b) { 52 | Double m = b.x * b.x + b.y * b.y; 53 | return point(a.x / m, a.y / m) * point(b.x, -b.y); 54 | } 55 | Long mround(Double A) { 56 | Long F = A; 57 | if (A < 0) F = (Long) (A - 0.5); 58 | if (A > 0) F = (Long) (A + 0.5); 59 | return F; 60 | } 61 | VI BigConvolution(const VI &a, const VI &b, Long MOD) { 62 | int ssss = a.size() + b.size() - 1; 63 | if (ssss <= 1024) { // remove this code if ans never less than 1024 64 | vector bf(ssss); 65 | for (int i = 0; i < a.size(); ++i) { 66 | for (int j = 0; j < b.size(); ++j) { 67 | bf[i + j] = (bf[i + j] + 1LL * a[i] * b[j]) % MOD; 68 | } 69 | } 70 | return bf; 71 | } 72 | int L = 1; 73 | while ((1 << L) < a.size()) L++; 74 | while ((1 << L) < b.size()) L++; 75 | int n = 1 << (L + 1); 76 | Long SH = 16; 77 | Long M = (1 << SH) - 1, S = 1 << SH; 78 | Long S1 = S; 79 | Long S2 = S * S % MOD; 80 | vector xy1(n), xy0(n); 81 | for (int i = 0; i < a.size(); ++i) { 82 | xy1[i].x = a[i] >> SH; 83 | xy0[i].x = a[i] & M; 84 | } 85 | for (int i = 0; i < b.size(); ++i) { 86 | xy1[i].y = b[i] >> SH; 87 | xy0[i].y = b[i] & M; 88 | } 89 | fft(xy1, 1); fft(xy0, 1); 90 | vector z2(n), z1(n), z0(n); 91 | for (int i = 0; i < n; i++) { 92 | point X0 = (xy0[i] + xy0[(n - i) % n].conjugate()) / point(2, 0); 93 | point X1 = (xy1[i] + xy1[(n - i) % n].conjugate()) / point(2, 0); 94 | point Y0 = (xy0[i] - xy0[(n - i) % n].conjugate()) / point(0, 2); 95 | point Y1 = (xy1[i] - xy1[(n - i) % n].conjugate()) / point(0, 2); 96 | z2[i] = X1 * Y1; 97 | z1[i] = X0 * Y1 + Y0 * X1; 98 | z0[i] = X0 * Y0; 99 | } 100 | fft(z2, -1); fft(z1, -1); fft(z0, -1); 101 | VI z(a.size() + b.size() - 1); 102 | for (int i = 0; i < z.size(); ++i) { 103 | Long dz2 = mround(z2[i].x) % MOD; 104 | Long dz1 = mround(z1[i].x) % MOD; 105 | Long dz0 = mround(z0[i].x) % MOD; 106 | Long l = (dz2 * S2) + (dz1 * S1) + dz0; 107 | z[i] = l % MOD; 108 | } 109 | return z; 110 | } 111 | -------------------------------------------------------------------------------- /Codes/Math/Fibo.cpp: -------------------------------------------------------------------------------- 1 | // If F[0] == 0 then b or mult(1, 0).second 2 | // If F[0] == 1 then get() or mult(1, 0).first 3 | #define MOD 1000000007 4 | #define add(a,b) (a+b>=MOD ? a+b-MOD : a+b) 5 | struct Fibo{ 6 | int b,c; 7 | Fibo(int b=0,int c=0):b(b),c(c){ } 8 | static Fibo one(){ // first fibo 9 | return Fibo(1,0); 10 | } 11 | static Fibo none(){ // neg-first fibo 12 | return Fibo(1,MOD-1); 13 | } 14 | static Fibo empty(){ 15 | return Fibo(0,0); 16 | } 17 | static Fibo identity(){ 18 | return Fibo(0,1); 19 | } 20 | static Fibo get(long long n){ 21 | return n >= 0 ? Fibo::one().pow(n) : Fibo::none().pow(-n); 22 | } 23 | int get(){ 24 | return add(b,c); 25 | } 26 | pair mult(int B, int A){ 27 | return make_pair((1LL*B*get()+1LL*A*b)%MOD, (1LL*B*b+1LL*A*c)%MOD); 28 | } 29 | Fibo operator*(const Fibo &F)const{ 30 | Fibo r; 31 | // r.a = (1LL*a*F.a + 1LL*b*F.b)%MOD; 32 | r.b = (1LL*(b+c)*F.b + 1LL*b*F.c)%MOD; 33 | r.c = (1LL*b*F.b + 1LL*c*F.c)%MOD; 34 | return r; 35 | } 36 | Fibo operator+(const Fibo &F)const{ 37 | return Fibo(add(b,F.b), add(c,F.c)); 38 | } 39 | Fibo pow(long long n){ 40 | Fibo m = *this; 41 | Fibo r = identity(); 42 | while(n){ 43 | if(n & 1)r = r * m; 44 | m = m * m; 45 | n >>= 1; 46 | } 47 | 48 | return r; 49 | } 50 | }; 51 | -------------------------------------------------------------------------------- /Codes/Math/Fourier.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | struct Fourier 6 | { 7 | typedef vector > VCD; 8 | typedef complex CD; 9 | typedef long long Long; 10 | 11 | #define MAXN 1000000 12 | static void four1(double *data, Long nn) { 13 | Long n, mmax, m, j, istep, i; 14 | double wtemp, wr, wpr, wpi, wi, theta; 15 | double tempr, tempi; 16 | 17 | // reverse-binary reindexing 18 | n = nn << 1; 19 | j = 1; 20 | for (i = 1; i < n; i += 2) { 21 | if (j > i) { 22 | swap(data[j - 1], data[i - 1]); 23 | swap(data[j], data[i]); 24 | } 25 | m = nn; 26 | while (m >= 2 && j > m) { 27 | j -= m; 28 | m >>= 1; 29 | } 30 | j += m; 31 | }; 32 | // here begins the Danielson-Lanczos section 33 | mmax = 2; 34 | while (n > mmax) { 35 | istep = mmax << 1; 36 | theta = -(2 * M_PI / mmax); 37 | wtemp = sin(0.5 * theta); 38 | wpr = -2.0 * wtemp * wtemp; 39 | wpi = sin(theta); 40 | wr = 1.0; 41 | wi = 0.0; 42 | for (m = 1; m < mmax; m += 2) { 43 | for (i = m; i <= n; i += istep) { 44 | j = i + mmax; 45 | tempr = wr * data[j - 1] - wi * data[j]; 46 | tempi = wr * data[j] + wi * data[j - 1]; 47 | data[j - 1] = data[i - 1] - tempr; 48 | data[j] = data[i] - tempi; 49 | data[i - 1] += tempr; 50 | data[i] += tempi; 51 | } 52 | wtemp = wr; 53 | wr += wr * wpr - wi * wpi; 54 | wi += wi * wpr + wtemp * wpi; 55 | } 56 | mmax = istep; 57 | } 58 | } 59 | static void _FFT(CD *V, Long &N) 60 | { 61 | while(N ^ (N & -N)) 62 | { 63 | V[N].real() = 0; 64 | V[N].imag() = 0; 65 | N++; 66 | } 67 | double *A_T = new double[2*N + 10]; 68 | // double A_T[6*MAXN]; 69 | for(int i = 0; i < N; ++i) 70 | { 71 | A_T[i+i] = V[i].real(); 72 | A_T[i+i+1]=V[i].imag(); } 73 | four1(A_T,N); 74 | for(int i = 0; i < N; ++i) 75 | { 76 | V[i].real() = A_T[i+i]; 77 | V[i].imag() = A_T[i+i+1]; 78 | } 79 | delete A_T; 80 | } 81 | static void _IFFT(CD *V , Long &N) 82 | { 83 | for(int i = 0; i < N; ++i) 84 | V[i].imag() *= -1; 85 | _FFT(V , N); 86 | for(int i = 0; i < N; ++i) 87 | { 88 | V[i].imag() *= -1; 89 | V[i] *= 1.0/double(N); 90 | } 91 | } 92 | static void doNothing(CD *CV, const int SZ){} 93 | static vector FFT(vector V , void (*process)(CD *CV,const int SZ) = doNothing) 94 | { 95 | Long SZ = V.size(); 96 | CD *CV = new CD[2 * V.size()]; 97 | for(int i = 0; i < V.size(); ++i) 98 | CV[i].real() = V[i] , CV[i].imag() = 0; 99 | _FFT(CV , SZ); 100 | process(CV,SZ); 101 | _IFFT(CV , SZ); 102 | for(int i = 0; i < V.size(); ++i) 103 | V[i] = CV[i].real(); 104 | return V; 105 | } 106 | }; 107 | -------------------------------------------------------------------------------- /Codes/Math/Fourier2.cpp: -------------------------------------------------------------------------------- 1 | namespace Fourier { 2 | #define lowbit(x) (((x) ^ (x-1)) & (x)) 3 | typedef complex Complex; 4 | 5 | void FFT(vector &A, int s){ 6 | int n = A.size(); 7 | int p = __builtin_ctz(n); 8 | 9 | vector a = A; 10 | 11 | for(int i = 0;i> j) & 1); 16 | } 17 | A[i] = a[rev]; 18 | } 19 | 20 | Complex w,wn; 21 | 22 | for(int i = 1;i<=p;++i){ 23 | int M = (1<>1); 24 | wn = Complex(cos(s*2.0*M_PI/(long double)M), sin(s*2.0*M_PI/(long double)M)); 25 | 26 | for(int j = 0;j FFT_Multiply(vector &P, vector &Q){ 46 | int n = P.size()+Q.size(); 47 | while(n!=lowbit(n)) n += lowbit(n); 48 | 49 | P.resize(n,0); 50 | Q.resize(n,0); 51 | 52 | FFT(P,1); 53 | FFT(Q,1); 54 | 55 | vector R; 56 | for(int i=0;i FFT_Multiply(vector &A, vector &B){ 63 | vector AF(A.size()); 64 | for(int i = 0; i < A.size(); ++i){ 65 | AF[i] = Complex(A[i], 0); 66 | } 67 | vector BF(B.size()); 68 | for(int i = 0; i < B.size(); ++i){ 69 | BF[i] = Complex(B[i], 0); 70 | } 71 | vector CF = FFT_Multiply(AF,BF); 72 | vector C; 73 | for (int i = 0; i < CF.size(); ++i) { 74 | C.push_back(CF[i].real()+0.1); 75 | } 76 | return C; 77 | } 78 | } -------------------------------------------------------------------------------- /Codes/Math/Gauss.cpp: -------------------------------------------------------------------------------- 1 | vector> gauss(vector> m){ 2 | int pivot = 0; 3 | for (int r = 0; r < m.size() && pivot+1 < m[0].size(); ) { 4 | int f = 0; 5 | for (int i = r; i < m.size(); ++i) { 6 | if(abs(m[i][pivot]) > 1e-5){ 7 | f = 1; 8 | swap(m[i], m[r]); 9 | break; 10 | } 11 | } 12 | if(f){ 13 | for (int j = m[0].size()-1; j >= pivot ; --j) { 14 | m[r][j] /= m[r][pivot]; 15 | } 16 | for (int i = r+1; i < m.size(); ++i) { 17 | if(m[i][pivot]){ 18 | for (int j = m[0].size()-1; j >= pivot; --j) { 19 | OPS++; 20 | m[i][j] -= m[i][pivot] * m[r][j]; 21 | } 22 | } 23 | } 24 | r++; 25 | } 26 | pivot++; 27 | } 28 | for (int i = m.size()-1; i >= 0; --i) { 29 | for (int j = 0; j+1 < m[0].size(); ++j) { 30 | if(m[i][j]){ 31 | for (int k = i-1; k >= 0; --k) { 32 | if(m[k][j]){ 33 | for (int l = m[0].size()-1; l >= j; --l) { 34 | OPS++; 35 | m[k][l] -= m[k][j] * m[i][l]; 36 | } 37 | } 38 | } 39 | break; 40 | } 41 | } 42 | } 43 | return m; 44 | } -------------------------------------------------------------------------------- /Codes/Math/GaussDouble.css: -------------------------------------------------------------------------------- 1 | vector> gauss(vector> m){ 2 | int pivot = 0; 3 | for (int r = 0; r < m.size() && pivot+1 < m[0].size(); ) { 4 | int f = 0; 5 | for (int i = r; i < m.size(); ++i) { 6 | if(abs(m[i][pivot]) > 1e-5){ 7 | f = 1; 8 | swap(m[i], m[r]); 9 | break; 10 | } 11 | } 12 | if(f){ 13 | for (int j = m[0].size()-1; j >= pivot ; --j) { 14 | m[r][j] /= m[r][pivot]; 15 | } 16 | for (int i = r+1; i < m.size(); ++i) { 17 | if(m[i][pivot]){ 18 | for (int j = m[0].size()-1; j >= pivot; --j) { 19 | OPS++; 20 | m[i][j] -= m[i][pivot] * m[r][j]; 21 | } 22 | } 23 | } 24 | r++; 25 | } 26 | pivot++; 27 | } 28 | for (int i = m.size()-1; i >= 0; --i) { 29 | for (int j = 0; j+1 < m[0].size(); ++j) { 30 | if(m[i][j]){ 31 | for (int k = i-1; k >= 0; --k) { 32 | if(m[k][j]){ 33 | for (int l = m[0].size()-1; l >= j; --l) { 34 | OPS++; 35 | m[k][l] -= m[k][j] * m[i][l]; 36 | } 37 | } 38 | } 39 | break; 40 | } 41 | } 42 | } 43 | return m; 44 | } -------------------------------------------------------------------------------- /Codes/Math/GenericMatrix.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct Matrix 3 | { 4 | struct VirtualVector{ 5 | vector &R; 6 | int off; 7 | VirtualVector(vector &R, const int off):R(R),off(off){} 8 | T& operator[](int k){ 9 | return R[off+k]; 10 | } 11 | }; 12 | vector MAT; 13 | int N,M; 14 | Matrix(int N,int M) { 15 | this->N = N; 16 | this->M = M; 17 | MAT = vector(N*M); 18 | } 19 | static Matrix identity(int N) { 20 | Matrix A(N,N); 21 | for(int i = 0; i < N; ++i) 22 | A[i][i] = 1; 23 | return A; 24 | } 25 | Matrix operator+(Matrix &M) { 26 | Matrix A(this->rows() , M.cols()); 27 | for(int i = 0; i < this->rows(); ++i) { 28 | for(int j = 0; j < this->cols(); ++j) { 29 | A[i][j] = ((*this)[i][j] + M[i][j]); 30 | } 31 | } 32 | return A; 33 | } 34 | Matrix operator*(Matrix &MA) const { 35 | Matrix A(this->rows() , MA.cols()); 36 | if(this->cols() != MA.rows())return A; 37 | for(int i = 0; i < this->rows(); ++i) { 38 | for(int j = 0; j < MA.cols(); ++j) { 39 | A[i][j] = 0; 40 | for(int k = 0; k < this->cols(); ++k) { 41 | A[i][j] = (A[i][j] + MAT[i*M + k] * MA[k][j]); 42 | } 43 | } 44 | } 45 | return A; 46 | } 47 | Matrix operator*(int &n) { 48 | Matrix A(this->rows() , this->cols()); 49 | for(int i = 0; i < this->rows(); ++i) { 50 | for(int j = 0; j < this->cols(); ++j) { 51 | A[i][j] = (1LL * n * (*this)[i][j]); 52 | } 53 | } 54 | return A; 55 | } 56 | Matrix pow(int n) { 57 | Matrix A = identity((*this).rows()); 58 | for(int b = (1<<30); b >= 1; b>>=1) { 59 | A = A * A; 60 | if(b & n)A = A * (*this); 61 | } 62 | return A; 63 | } 64 | VirtualVector operator[](int i){ 65 | return VirtualVector(MAT, i*M); 66 | } 67 | int rows() const {return N;} 68 | int cols() const {return M;} 69 | string toString() { 70 | string ans = "{\n"; 71 | for(int i = 0; i < this->rows(); ++i) { 72 | ans += "["; 73 | for(int j = 0; j < this->cols(); ++j) { 74 | stringstream st; 75 | string app = (j==0?"":" "); 76 | st << app; 77 | st << (*this)[i][j]; 78 | ans += st.str(); 79 | } 80 | ans += "]\n"; 81 | } 82 | ans += "}"; 83 | return ans; 84 | } 85 | // for inverse of matrix 86 | void setRow(int ra, int rb, T a, T b) { 87 | for (int j = 0; j < M; ++j) { 88 | MAT[ra * M + j] = a * MAT[ra * M + j] + b * MAT[rb * M + j]; 89 | } 90 | } 91 | void swapRow(int ra, int rb) { 92 | for (int j = 0; j < M; ++j) { 93 | swap(MAT[ra * M + j], MAT[rb * M + j]); 94 | } 95 | } 96 | Matrix inverse() const { 97 | Matrix inv = identity(N); 98 | Matrix sel = (*this); 99 | for (int i = 0; i < N; ++i) { 100 | if (sel[i][i] == 0) { 101 | for (int j = i; j < M; ++j) { 102 | if (!(sel[j][i] == 0)) { 103 | sel.swapRow(i, j); 104 | inv.swapRow(i, j); 105 | break; 106 | } 107 | } 108 | } 109 | { 110 | T t = sel[i][i]; 111 | inv.setRow(i, i, T(1) / t, 0); 112 | sel.setRow(i, i, T(1) / t, 0); 113 | } 114 | for (int j = i+1; j < N; ++j) { 115 | T t = sel[j][i]; 116 | inv.setRow(j, i, 1, -t); 117 | sel.setRow(j, i, 1, -t); 118 | } 119 | } 120 | for (int i = N-1; i >= 0; --i) { 121 | for (int j = i-1; j >= 0; --j) { 122 | T t = sel[j][i]; 123 | inv.setRow(j, i, 1, -t); 124 | sel.setRow(j, i, 1, -t); 125 | } 126 | } 127 | return inv; 128 | } 129 | }; 130 | -------------------------------------------------------------------------------- /Codes/Math/LinearCongruence.cpp: -------------------------------------------------------------------------------- 1 | // https://www.johndcook.com/blog/2008/12/10/solving-linear-congruences/ 2 | // a*x = b (mod m) 3 | // -1 (no solution if gcd(a, m) dont divide b) or x (a solution) 4 | // there exist gcd(a, m) solutions all of which are x + m/gcd(a,m)*[0...gcd-1] 5 | int solveLinearCongruence(int a, int b, int m) { // ~2M per second 6 | if (b == 0 || b == m) return 0; 7 | if (a == 0) return -1; 8 | int y = solveLinearCongruence(m % a, -b % a + a, a); 9 | return y < 0 ? y : (1LL*m*y+b) / a; 10 | } 11 | -------------------------------------------------------------------------------- /Codes/Math/LinearSieve.cpp: -------------------------------------------------------------------------------- 1 | struct LinearSieve { 2 | VI primes, primeFactor; 3 | LinearSieve(int L): primeFactor(L+1) { 4 | for (int i = 2; i < primeFactor.size(); ++i) { 5 | if (primeFactor[i] == 0) primes.push_back (primeFactor[i] = i); 6 | for (int j=0; j < primes.size() && primes[j]<=primeFactor[i] && i*primes[j]<=L; ++j) 7 | primeFactor[i * primes[j]] = primes[j]; 8 | } 9 | } 10 | VI factors(int n) { 11 | VI F; 12 | while (n > 1) F.push_back(primeFactor[n]), n /= primeFactor[n]; 13 | return F; 14 | } 15 | void rec(vector &V, int tp, int id, int c, VI &A) { 16 | if (id == V.size()) { 17 | A.push_back(c); 18 | } else { 19 | rec(V, 0, id+1, c, A); 20 | if (tp == 1 || V[id] != V[id-1]) 21 | rec(V, 1, id+1, c * V[id], A); 22 | } 23 | } 24 | VI divisors(int n) { 25 | VI f = factors(n), R; 26 | rec(f, 1, 0, 1, R); 27 | sort(R.begin(), R.end()); 28 | return R; 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /Codes/Math/Matrix.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | struct Matrix 6 | { 7 | #define MOD 1000000007 8 | vector > MAT; 9 | Matrix(int N,int M) 10 | { 11 | MAT = vector >(N, vector(M,0)); 12 | } 13 | static Matrix identity(int N) 14 | { 15 | Matrix A(N,N); 16 | for(int i = 0; i < N; ++i) 17 | A[i][i] = 1; 18 | return A; 19 | } 20 | Matrix operator+(const Matrix &M)const 21 | { 22 | Matrix A(this->rows() , M.cols()); 23 | for(int i = 0; i < this->rows(); ++i) 24 | { 25 | for(int j = 0; j < this->cols(); ++j) 26 | { 27 | A[i][j] = (MAT[i][j] + M.MAT[i][j]) % MOD; 28 | } 29 | } 30 | return A; 31 | } 32 | Matrix operator*(const Matrix &M)const 33 | { 34 | Matrix A(this->rows() , M.cols()); 35 | if(this->cols() != M.rows())return A; 36 | for(int i = 0; i < this->rows(); ++i) 37 | { 38 | for(int j = 0; j < M.cols(); ++j) 39 | { 40 | A[i][j] = 0; 41 | for(int k = 0; k < this->cols(); ++k) 42 | { 43 | Long m = 1LL*MAT[i][k] * M.MAT[k][j]; 44 | m %= MOD; 45 | if(m < 0)m += MOD; 46 | A[i][j] = (A[i][j] + m) % MOD; 47 | } 48 | } 49 | } 50 | return A; 51 | } 52 | Matrix operator*(int &n) 53 | { 54 | Matrix A(this->rows() , this->cols()); 55 | for(int i = 0; i < this->rows(); ++i) 56 | { 57 | for(int j = 0; j < this->cols(); ++j) 58 | { 59 | A[i][j] = (1LL * n * (*this)[i][j]) % MOD; 60 | } 61 | } 62 | return A; 63 | } 64 | Matrix transponse()const{ 65 | Matrix r(cols(), rows()); 66 | for(int i = 0; i < rows(); ++i) 67 | for(int j = 0; j < cols(); ++j) 68 | r[j][i] = MAT[i][j]; 69 | return r; 70 | } 71 | Matrix pow(long long n) 72 | { 73 | Matrix A = identity((*this).rows()); 74 | long long hb = 1; 75 | while(hb < n)hb <<= 1; 76 | for(long long b = hb; b >= 1; b>>=1) 77 | { 78 | A = A * A; 79 | if (b & n) A = A * (*this); 80 | } 81 | return A; 82 | } 83 | vector& operator[](int i){return MAT[i];} 84 | int rows()const{return MAT.size();} 85 | int cols()const{return MAT[0].size();} 86 | string toString() 87 | { 88 | string ans = "{\n"; 89 | for(int i = 0; i < this->rows(); ++i) 90 | { 91 | ans += "["; 92 | for(int j = 0; j < this->cols(); ++j) 93 | { 94 | char arr[30]; 95 | string app = (j==0?"":" "); 96 | sprintf(arr,"%d",(*this)[i][j]); 97 | app += arr; 98 | ans += app; 99 | } 100 | ans += "]\n"; 101 | } 102 | ans += "}"; 103 | return ans; 104 | } 105 | #undef MOD 106 | }; -------------------------------------------------------------------------------- /Codes/Math/ModInt.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct ModInt { 3 | int n; 4 | ModInt(const ModInt &v):n(v.n){ } 5 | ModInt():n(0){} 6 | ModInt(Long nn){ 7 | if(nn < -MOD || nn >= MOD)nn %= MOD; 8 | if(nn < 0)nn += MOD; 9 | n = nn; 10 | } 11 | ModInt operator+(const ModInt &M)const{ 12 | int r = (n + M.n); 13 | if(r >= MOD)r -= MOD; 14 | return ModInt::safe(r); 15 | } 16 | ModInt operator-(const ModInt &M)const{ 17 | int r = (n - M.n); 18 | if(r < 0)r += MOD; 19 | return ModInt::safe(r); 20 | } 21 | ModInt operator*(const ModInt &M)const{ 22 | return ModInt::safe(((Long)n * M.n) % MOD); 23 | } 24 | ModInt operator+=(const ModInt &M){ 25 | return ModInt::safe(n = ((*this)+(M)).n); 26 | } 27 | ModInt operator-=(const ModInt &M){ 28 | return ModInt::safe(n = ((*this)-(M)).n); 29 | } 30 | ModInt operator/(const ModInt &B)const 31 | { 32 | Long a = B.n, b = MOD; 33 | Long r = a , o_r = b; 34 | Long s = 0 , o_s = 1; 35 | Long t = 1 , o_t = 0; 36 | while(r != 0) 37 | { 38 | Long q = o_r / r; 39 | Long tem; 40 | 41 | tem = r; 42 | r = o_r - r * q; 43 | o_r = tem; 44 | 45 | tem = o_s; 46 | o_s = o_s - s * q; 47 | o_s = tem; 48 | 49 | tem = t; 50 | t = o_t - t * q; 51 | o_t = tem; 52 | } 53 | return (*this) * ModInt(o_t); 54 | } 55 | ModInt power(const ModInt &B){ 56 | if(B.n == 0)return 1; 57 | ModInt sq = power(B.n/2); 58 | sq = sq * sq; 59 | if(B.n & 1)sq = sq * (*this); 60 | return sq; 61 | } 62 | inline static ModInt safe(Long n){ 63 | ModInt m; 64 | m.n = n; 65 | return m; 66 | } 67 | friend ostream &operator<<(ostream& o, const ModInt &m) { 68 | return o << m.n; 69 | } 70 | }; 71 | typedef ModInt<1000000007> mint; 72 | -------------------------------------------------------------------------------- /Codes/Math/ModIntShort.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct ModInt { 3 | int n; 4 | ModInt(const ModInt &v):n(v.n){ } 5 | ModInt():n(0){} 6 | ModInt(Long nn){ 7 | if(nn < -MOD || nn >= MOD)nn %= MOD; 8 | if(nn < 0)nn += MOD; 9 | n = nn; 10 | } 11 | ModInt operator+(const ModInt &M)const{ 12 | return ModInt::safe(n + M.n >= MOD ? (n + M.n - MOD) : (n + M.n)); 13 | } 14 | ModInt operator-(const ModInt &M)const{ 15 | return ModInt::safe(n >= M.n ? (n - M.n) : (n - M.n + MOD)); 16 | } 17 | ModInt operator*(const ModInt &M)const{ 18 | return ModInt::safe(((Long)n * M.n) % MOD); 19 | } 20 | ModInt operator+=(const ModInt &M) { 21 | return ModInt::safe(n = ((*this)+(M)).n); 22 | } 23 | ModInt operator-=(const ModInt &M) { 24 | return ModInt::safe(n = ((*this)-(M)).n); 25 | } 26 | ModInt operator*=(const ModInt &M) { 27 | return ModInt::safe(n = ((*this)*(M)).n); 28 | } 29 | inline static ModInt safe(int n) { 30 | ModInt m; 31 | m.n = n; 32 | return m; 33 | } 34 | friend ostream &operator<<(ostream& o, const ModInt &m) { 35 | return o << m.n; 36 | } 37 | }; 38 | typedef ModInt<1000000007> mint; 39 | -------------------------------------------------------------------------------- /Codes/Math/NCR.cpp: -------------------------------------------------------------------------------- 1 | struct Math 2 | { 3 | typedef long long Long; 4 | static int egcd(int a, int b){ 5 | int x,y; 6 | return egcd(a,b,x,y); 7 | } 8 | // ax + by = c 9 | static int egcd(int a,int b, int &x, int &y) { 10 | x = 1, y = 0; 11 | int nx = 0, ny = 1; 12 | int nr = b, r = a; 13 | while(nr != 0) { 14 | int q = r / nr; 15 | tie(r, nr) = make_tuple(nr, r - q*nr); 16 | tie(x, nx) = make_tuple(nx, x - q*nx); 17 | tie(y, ny) = make_tuple(ny, y - q*ny); 18 | } 19 | // bezout = x , y 20 | // gcd = o_r 21 | return r; 22 | } 23 | static int MOD; 24 | static Long modInv(Long a, Long b) 25 | { 26 | int x,y; egcd(a,b,x,y); 27 | return x < 0 ? x + b : x; 28 | } 29 | static Long divide(Long a, Long b) 30 | { 31 | return a * modInv(b, MOD) % MOD; 32 | } 33 | static int fact(int n) 34 | { 35 | static vector F; 36 | if(F.size() <= n) 37 | { 38 | int oSZ = F.size(); 39 | F.resize(n+1); 40 | if(oSZ == 0)F[0] = 1 , oSZ++; 41 | for(int i = oSZ; i <= n; ++i) 42 | F[i] = (1LL * F[i-1] * i) % MOD; 43 | } 44 | return F[n]; 45 | } 46 | static int catalan(int n) 47 | { 48 | return divide(ncr(2*n,n), n+1); 49 | } 50 | static int ncr(int n,int k) 51 | { 52 | if(k < 0 || n < 0 || n < k)return 0; 53 | return divide(fact(n) , (1LL * fact(k) * fact(n-k)) % MOD); 54 | } 55 | static int mul(int a,int b){ 56 | return (1LL*(a%MOD)*(b%MOD))%MOD; 57 | } 58 | static int mul(int a,int b,int c){ 59 | return (1LL*mul(a,b)*(c%MOD))%MOD; 60 | } 61 | static int mul(int a,int b,int c,int d){ 62 | return (1LL*mul(a,b)*mul(c,d))%MOD; 63 | } 64 | static bool solveDiophantine(int a, int b, int c, int &x, int &y) { 65 | int gc = egcd(a,b,x,y); 66 | if(c % gc != 0)return false; 67 | int d = c / gc; 68 | x *= d; 69 | y *= d; 70 | return true; 71 | } 72 | static void moveBezout(int a,int b, int c, int &x, int &y, int pos = 1){ 73 | int gc = egcd(a,b); 74 | b /= gc; 75 | a /= gc; 76 | x += b * pos; 77 | y -= a * pos; 78 | } 79 | }; 80 | int Math::MOD = 1000000007; -------------------------------------------------------------------------------- /Codes/Math/NTT.cpp: -------------------------------------------------------------------------------- 1 | namespace NTT{ 2 | struct NTTMod { 3 | int mod, root, root_1, root_pw; 4 | }; 5 | static int modPow(int b, int e, int m){ 6 | if(e == 0)return 1; 7 | int sq = modPow(b,e>>1,m); 8 | sq = (1LL*sq*sq) % m; 9 | if(e&1)sq = (1LL*sq*b)%m; 10 | return sq; 11 | } 12 | static int modInv(int b,int m){ 13 | return modPow(b,m-2,m); 14 | } 15 | static const NTTMod suggested_fft_mods[5] = { 16 | { 7340033, 5, 4404020, 1 << 20 }, 17 | { 415236097, 73362476, 247718523, 1<<22 }, 18 | { 463470593, 428228038, 182429, 1<<21}, 19 | { 998244353, 15311432, 469870224, 1 << 23 }, 20 | { 918552577, 86995699, 324602258, 1 << 22 } 21 | }; 22 | static void ntt (vector & a, bool invert, const NTTMod &mod) { 23 | int n = (int) a.size(); 24 | for (int i=1, j=0; i> 1; 26 | for (; j>=bit; bit>>=1) 27 | j -= bit; 28 | j += bit; 29 | if (i < j) 30 | swap (a[i], a[j]); 31 | } 32 | for (int len=2; len<=n; len<<=1) { 33 | int wlen = invert ? mod.root_1 : mod.root; 34 | for (int i=len; i= 0 ? u-v : u-v+mod.mod; 42 | w = int (w * 1ll * wlen % mod.mod); 43 | } 44 | } 45 | } 46 | if (invert) { 47 | int nrev = modInv(n, mod.mod); 48 | for (int i=0; i means { value, smallMod } 54 | static long long crt(const std::vector< std::pair >& a, int mod) { 55 | long long res = 0; 56 | long long mult = 1; 57 | 58 | int SZ = a.size(); 59 | std::vector x(SZ); 60 | for (int i = 0; i ntt_mult(const vector& left, const vector& right, const NTTMod& mod_data) { 78 | vector left1 = left, right1 = right; 79 | ntt(left1, false, mod_data); 80 | ntt(right1, false, mod_data); 81 | 82 | for (int i = 0; i < left.size(); i++) { 83 | left1[i] = (left1[i] * 1ll * right1[i]) % mod_data.mod; 84 | } 85 | 86 | ntt(left1, true, mod_data); 87 | return left1; 88 | } 89 | static vector mult(vector& left, vector& right, int mod) { 90 | int ssss = left.size() + right.size() - 1; 91 | if (ssss <= 1024) { 92 | vector bf(ssss); 93 | for(int i = 0; i < left.size(); ++i){ 94 | for(int j = 0; j < right.size(); ++j){ 95 | bf[i+j] = (bf[i+j] + 1LL*left[i]*right[j])%mod; 96 | } 97 | } 98 | return bf; 99 | } 100 | 101 | int pot2 , fsz = left.size() + right.size() - 1; 102 | for (pot2 = 1; pot2 < ssss; pot2 <<= 1); 103 | 104 | left.resize(pot2); 105 | right.resize(pot2); 106 | 107 | vector res[3]; 108 | for (int i = 0; i < 3; i++) { 109 | res[i] = ntt_mult(left, right, suggested_fft_mods[i]); 110 | } 111 | 112 | vector ret(pot2); 113 | for (int i = 0; i < pot2; i++) { 114 | vector< pair > mod_results; 115 | for (int j = 0; j < 3; j++) { 116 | mod_results.emplace_back(res[j][i], suggested_fft_mods[j].mod); 117 | } 118 | ret[i] = crt(mod_results, mod); 119 | } 120 | ret.resize(fsz); 121 | return ret; 122 | } 123 | }; 124 | -------------------------------------------------------------------------------- /Codes/Math/NaiveCycleFinding.cpp: -------------------------------------------------------------------------------- 1 | struct Cycle { 2 | function func; 3 | vector seq, pos; 4 | int cycleSize, offset; 5 | vector freq; 6 | Cycle(int domain, int st, function func):func(func),pos(domain,-1),freq(domain){ 7 | do{ 8 | pos[st] = seq.size(); 9 | seq.push_back(st); 10 | st = func(st); 11 | }while(pos[st] == -1); 12 | cycleSize = seq.size() - pos[st]; 13 | offset = seq.size() - cycleSize; 14 | } 15 | int get(int n) { // zero-based 16 | if(n < offset)return seq[n]; 17 | n -= offset; 18 | n %= cycleSize; 19 | return seq[n + offset]; 20 | } 21 | void computeTo(int n) { 22 | for(int i = 0; i < min(n, offset); ++i) { 23 | freq[seq[i]]++; 24 | } 25 | if(n < offset)return; 26 | n -= offset; 27 | int comp = n / cycleSize; 28 | int res = n % cycleSize; 29 | for(int i = offset; i < cycleSize + offset; ++i) { 30 | freq[seq[i]] = comp; 31 | if(res > (i-offset)) 32 | freq[seq[i]]++; 33 | } 34 | for (int i = 1; i < freq.size(); ++i) { 35 | freq[i] += freq[i-1]; 36 | } 37 | } 38 | }; -------------------------------------------------------------------------------- /Codes/Math/Polinomial.cpp: -------------------------------------------------------------------------------- 1 | struct Polinomial 2 | { 3 | vector V; 4 | Polinomial(int deg) 5 | { 6 | V = vector(deg+1,0); 7 | } 8 | Polinomial(vector V){ 9 | this->V = V; 10 | } 11 | 12 | int degree() const { 13 | return int(V.size()) - 1; 14 | } 15 | double getC(int p) const { 16 | return p >= int(V.size()) ? 0 : V[p]; 17 | } 18 | 19 | Polinomial operator+(const Polinomial &P)const{ 20 | Polinomial ret(max(degree() , P.degree())); 21 | for(int i = 0; i <= ret.degree(); ++i) 22 | ret.V[i] = getC(i) + P.getC(i); 23 | return ret; 24 | } 25 | Polinomial operator-(const Polinomial &P)const{ 26 | Polinomial ret(max(degree() , P.degree())); 27 | for(int i = 0; i <= ret.degree(); ++i) 28 | ret.V[i] = getC(i) - P.getC(i); 29 | return ret; 30 | } 31 | 32 | Polinomial derivate()const{ 33 | Polinomial ret(degree()-1); 34 | for(int i = 0; i <= ret.degree(); ++i) 35 | ret.V[i] = (i+1) * V[i+1]; 36 | return ret; 37 | } 38 | Polinomial integrate()const{ 39 | Polinomial ret(degree()+1); 40 | for(int i = 1; i <= ret.degree(); ++i) 41 | ret.V[i] = V[i-1] / i; 42 | return ret; 43 | } 44 | 45 | double eval(double x) 46 | { 47 | double ret = 0; 48 | for(int i = degree(); i >= 0; i--) 49 | ret = ret * x + V[i]; 50 | return ret; 51 | } 52 | 53 | vector getZeros() 54 | { 55 | if(degree() == 0)return vector(); 56 | Polinomial D = this->derivate(); 57 | vector Z = D.getZeros(); 58 | vector R; 59 | for(int i = 0; i <= Z.size(); ++i) 60 | { 61 | double l = i == 0 ? -1e9 : Z[i-1]; 62 | double r = i == Z.size() ? 1e9 : Z[i]; 63 | double x = (l + r) / 2; 64 | for(int k = 0; k < 60; ++k){ 65 | x = x - eval(x) / D.eval(x); 66 | } 67 | double fe = eval(x); 68 | if( -1e-6 <= fe && fe <= 1e-6 ) 69 | R.push_back(x); 70 | } 71 | sort(R.begin(),R.end()); 72 | vector RET; 73 | for(int i = 0; i < R.size(); ++i) 74 | { 75 | if(i == 0 || R[i]-R[i-1] >= 1e-6 ) 76 | RET.push_back(R[i]); 77 | } 78 | return RET; 79 | } 80 | }; -------------------------------------------------------------------------------- /Codes/Math/PrimitiveRoot.cpp: -------------------------------------------------------------------------------- 1 | // https://math.stackexchange.com/questions/124408/finding-a-primitive-root-of-a-prime-number 2 | int modPow(int b, int e, int m) { 3 | if (e == 0) return 1; 4 | int sq = modPow(b, e >> 1, m); 5 | sq = 1LL * sq * sq % m; 6 | return (e & 1) ? (sq * 1LL * b % m) : sq; 7 | } 8 | vector getPrimeFactors(int x) { 9 | vector PRIMES; 10 | for (int i = 2; i * i <= x; ++i) { 11 | if (x % i == 0) { 12 | PRIMES.push_back(i); 13 | while (x % i == 0) x /= i; 14 | } 15 | } 16 | if (x > 1) PRIMES.push_back(x); 17 | return PRIMES; 18 | } 19 | int phi(int x) { 20 | auto pr = getPrimeFactors(x); 21 | int n = x; 22 | for (int p : pr) { 23 | n = n / p * (p-1); 24 | } 25 | return n; 26 | } 27 | int getPrimitiveRoot(int x) { 28 | if (x <= 4) { 29 | vector ans = {-1, 0, 1, 2, 3}; 30 | return ans[x]; 31 | } 32 | auto pr = getPrimeFactors((x & 1) ? x : (x / 2)); 33 | if (pr.size() > 1 || pr[0] == 2) { 34 | return -1; 35 | } 36 | int s = phi(x); 37 | vector PRIMES = getPrimeFactors(s); 38 | // it should randomly find a primitive root since probability is high 39 | for (int i = 0; i < 100; ++i) { 40 | int r = rand() % (x - 1) + 1; 41 | bool ok = 1; 42 | if (__gcd(r, x) != 1) ok = 0; 43 | for (int j = 0; ok && j < PRIMES.size(); ++j) { 44 | if (modPow(r, s / PRIMES[j], x) == 1) { 45 | ok = 0; 46 | } 47 | } 48 | if (ok) return r; 49 | } 50 | assert(false); 51 | return -1; 52 | } 53 | vector getAllPrimitiveRoots(int x) { 54 | int s = phi(x); 55 | int r = getPrimitiveRoot(x); 56 | if (r == -1) return {}; 57 | vector R; 58 | for (int i = 1; i <= s; ++i) { 59 | if (__gcd(i, s) == 1) { 60 | R.push_back(modPow(r, i, x)); 61 | } 62 | } 63 | sort(R.begin(), R.end()); 64 | return R; 65 | } 66 | -------------------------------------------------------------------------------- /Codes/String/AhoCorasick.cpp: -------------------------------------------------------------------------------- 1 | /// Offline structure to find multiple strings inside a 2 | /// long text in O(N+M) where N = |text|, M = sum(|strings|) 3 | struct Node 4 | { 5 | int parent , fail , output , letter, str , id; 6 | map childs; 7 | Node(char letter, int id): letter(letter), id(id) { 8 | str = parent = fail = output = -1; 9 | } 10 | }; 11 | struct AhoCorasik { 12 | static const int ROOT = 0; 13 | static const int NONE = -1; 14 | vector nodes; 15 | vector words; 16 | void create(vector &V) { 17 | nodes = vector(1,Node('*', 0)); 18 | for(string S : V) { 19 | int v = ROOT; 20 | for(int p : S){ 21 | if(!nodes[v].childs.count(p)){ 22 | nodes[v].childs[p] = nodes.size(); 23 | nodes.push_back(Node(p, nodes.size())); 24 | nodes.back().parent = v; 25 | } 26 | v = nodes[v].childs[p]; 27 | } 28 | nodes[v].str = words.size(); 29 | words.push_back(S); 30 | } 31 | queue Q; 32 | for(auto ch : nodes[ROOT].childs) { 33 | Node &n = nodes[ch.second]; 34 | n.fail = ROOT; 35 | for(auto ch2 : n.childs) 36 | Q.push(ch2.second); 37 | } 38 | while(!Q.empty()) { 39 | int u = Q.front(); Q.pop(); 40 | int p = nodes[nodes[u].parent].fail; 41 | int letter = nodes[u].letter; 42 | while(p != ROOT && !nodes[p].childs.count(letter)) 43 | p = nodes[p].fail; 44 | nodes[u].fail = !nodes[p].childs.count(letter) ? p : nodes[p].childs[letter]; 45 | nodes[u].output = nodes[nodes[u].fail].str == NONE ? nodes[nodes[u].fail].output : nodes[u].fail; 46 | for(auto ch2 : nodes[u].childs) 47 | Q.push(ch2.second); 48 | } 49 | } 50 | /// @param STR: text to find all the strings 51 | /// @return map of found ids and index where it occurred 52 | /// @note if word is repeated you will only get the last index 53 | map< int , vector > find(const string &STR) { 54 | map< int , vector > RET; 55 | int u = ROOT; 56 | for(int i = 0; i < STR.size(); ++i) { 57 | int p = STR[i]; 58 | while(u != ROOT && !nodes[u].childs.count(p)) 59 | u = nodes[u].fail; 60 | if(nodes[u].childs.count(p)) 61 | u = nodes[u].childs[p]; 62 | for(int outP = u ; outP != NONE ; outP = nodes[outP].output) { 63 | if(nodes[outP].str != NONE) { 64 | int &S = nodes[outP].str; 65 | RET[S].push_back(i-words[S].size()+1); 66 | } 67 | } 68 | } 69 | return RET; 70 | } 71 | void print(int v = ROOT, int LVL = 0) 72 | { 73 | Node &n = nodes[v]; 74 | Node &f = nodes[v].fail == NONE ? nodes[v] : nodes[nodes[v].fail]; 75 | printf("%s%c|%d,%d\n" , string(LVL,'\t').c_str() , n.letter, n.id, f.id); 76 | for(auto ch : nodes[v].childs) 77 | print(ch.second , LVL+1); 78 | } 79 | }; 80 | -------------------------------------------------------------------------------- /Codes/String/CompressedTrie.cpp: -------------------------------------------------------------------------------- 1 | struct CompressedTrie { 2 | vector S; 3 | struct Node{ 4 | int i,j,sz; 5 | int child[26], w; 6 | Node(int i=0,int j=0,int sz=0):i(i),j(j),sz(sz){ 7 | w = 0; 8 | memset(child,-1,sizeof(child)); 9 | } 10 | }; 11 | vector V; 12 | int createNode(int i,int j, int sz){ 13 | int id = V.size(); 14 | V.push_back(Node(i,j,sz)); 15 | V[id].w++; 16 | return id; 17 | } 18 | CompressedTrie():S(1,""),V(1){ } 19 | void insert(const string &s){ 20 | S.push_back(s); 21 | insert(S.size()-1,0,0); 22 | } 23 | int insert(int i, int j, int v){ 24 | if(v == -1){ 25 | return createNode(i, j, S[i].size()-j); 26 | }else{ 27 | Node &av = V[v]; 28 | int k = 0; 29 | while(k < av.sz && j+k < S[i].size() && S[av.i][av.j+k] == S[i][j+k]) 30 | k++; 31 | if(k < av.sz){ 32 | int old = v; 33 | v = createNode(av.i,av.j,k); 34 | int p = S[av.i][av.j+k] - 'a'; 35 | V[v].child[p] = old; 36 | V[old].sz -= k; 37 | V[old].j += k; 38 | } 39 | if(j+k < S[i].size()){ 40 | int p = S[i][j+k]-'a'; 41 | V[v].child[p] = insert(i, j+k, V[v].child[p]); 42 | }else{ 43 | V[v].w++; 44 | } 45 | return v; 46 | } 47 | } 48 | int search(string s){ 49 | Node *v = &V[0]; 50 | for(int i = 0; i < s.size(); ){ 51 | int p = s[i] - 'a'; 52 | if(v->child[p] == -1)return 0; 53 | v = &V[v->child[p]]; 54 | int j = 0; 55 | while(i < s.size() && j < v->sz && s[i]==S[v->i][v->j+j]){ 56 | j++;i++; 57 | } 58 | if(i == s.size() && j == v->sz){ 59 | cout << v->w << endl; 60 | return v->w; 61 | }else if(i == s.size()){ 62 | return 0; 63 | } 64 | } 65 | } 66 | void print(int v = 0,int LVL = 0){ 67 | Node &av = V[v]; 68 | cout << string(LVL,'\t')<< "'" << S[av.i].substr(av.j,av.sz) << "'" << endl; 69 | for(int i = 0; i < 26; ++i){ 70 | if(V[v].child[i] != -1) 71 | print(V[v].child[i], LVL+1); 72 | } 73 | } 74 | }; -------------------------------------------------------------------------------- /Codes/String/Hash.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct Hash { 3 | ModInt m; 4 | int sz; 5 | Hash():sz(0){} 6 | void push_back(const int &c){ 7 | m = m*FAC + c; 8 | sz++; 9 | } 10 | void pop_back(const int &c){ 11 | m = (m - c) / FAC; 12 | } 13 | void push_front(const int &c){ 14 | ModInt t = FAC; 15 | t = t.power(sz); 16 | t = t * c; 17 | m += t; 18 | sz++; 19 | } 20 | void pop_front(const int &c){ 21 | sz--; 22 | ModInt t = FAC; 23 | t = t.power(sz); 24 | t = t * c; 25 | m -= t; 26 | } 27 | bool operator==(const Hash &H)const{ 28 | return m.n == H.m.n; 29 | } 30 | }; -------------------------------------------------------------------------------- /Codes/String/KMP.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | struct KMP 6 | { 7 | string needle; 8 | vector T; 9 | KMP(const string needle) { 10 | this->needle = needle; 11 | T = vector(needle.size() + 1); 12 | int i = 0 , j = -1; 13 | T[0] = -1; 14 | while(i < needle.size()) { 15 | while(j >= 0 && needle[i] != needle[j])j = T[j]; 16 | T[++i] = ++j; 17 | } 18 | } 19 | vector match(const string hay) { 20 | vector V; 21 | int i = 0 , j = 0; 22 | while(i < hay.size()) { 23 | while(j >= 0 && hay[i] != needle[j])j = T[j]; 24 | ++i;++j; 25 | if(j == needle.size()) { 26 | V.push_back(i - j); 27 | j = T[j]; 28 | } 29 | } 30 | return V; 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /Codes/String/Manachers.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | vector manachers(const string &A) { 7 | vector S; 8 | for (int i = 0; i < A.size(); ++i) { 9 | S.push_back(128); 10 | S.push_back(A[i]); 11 | } 12 | S.push_back(128); 13 | vector P(S.size()); 14 | int ma = 0; 15 | P[0] = 0; 16 | for (int i = 1; i < P.size(); ++i) { 17 | if (P[ma] + ma >= i) 18 | P[i] = min(P[2 * ma - i], 2 * ma - i - (ma - P[ma])); 19 | int lo = i - P[i] - 1, hi = i + P[i] + 1; 20 | while (lo >= 0 && hi < P.size() && S[lo] == S[hi]) 21 | P[i]++, lo--, hi++; 22 | if (P[ma] + ma < P[i] + i) 23 | ma = i; 24 | } 25 | return P; 26 | } 27 | 28 | // get palindrom range when passed a Manacher index. 29 | PII palinRange(const VI &MAN, int i) { 30 | return PII(i / 2 - MAN[i] / 2, i / 2 + MAN[i] / 2 - (i%2 == 0)); 31 | }; 32 | -------------------------------------------------------------------------------- /Codes/String/NextLetter.cpp: -------------------------------------------------------------------------------- 1 | 2 | struct NextLetter { 3 | vector> NEXT; 4 | static int serialize(char n){ 5 | if('0' <= n && n <= '9')return n - '0'; 6 | if('a' <= n && n <= 'z')return n - 'a' + 10; 7 | if('A' <= n && n <= 'Z')return n - 'A' + 36; 8 | return 0; 9 | } 10 | NextLetter(const string &s) { 11 | string ts; 12 | for (int i = 0; i < s.size(); ++i) { 13 | if('0' <= s[i] && s[i] <= '9') 14 | ts += s[i]; 15 | } 16 | NEXT = vector>(ts.size()+1, vector(10, -1)); 17 | vector L(10, -1); 18 | for (int i = ts.size()-1; i >= 0; --i) { 19 | L[serialize(ts[i])] = i; 20 | for(int j = 0; j < 10; ++j) { 21 | NEXT[i][j] = L[j]; 22 | } 23 | } 24 | } 25 | bool search(const string &s) { 26 | int id = 0; 27 | for(char c : s){ 28 | id = NEXT[id][serialize(c)]; 29 | if(id == -1)return false; 30 | id++; 31 | } 32 | return true; 33 | } 34 | }; -------------------------------------------------------------------------------- /Codes/String/RawHash.cpp: -------------------------------------------------------------------------------- 1 | #define HASH_COUNT 1 2 | Long PR[] = {31, 63}; 3 | Long MO[] = {1000000007, 1000000009}; 4 | VI po[] = { 5 | VI(1,1),VI(1,1) 6 | }; 7 | struct Hash{ 8 | int v[HASH_COUNT]; 9 | Hash(){ 10 | memset(v,0,sizeof(int)*HASH_COUNT); 11 | } 12 | Hash up(int p){ 13 | Hash r(*this); 14 | for (int i = 0; i < HASH_COUNT; ++i) { 15 | while(po[i].size() <= p){ 16 | po[i].push_back( po[i].back() * PR[i] % MO[i] ); 17 | } 18 | r.v[i] = (1LL * r.v[i] * po[i][p]) % MO[i]; 19 | } 20 | return r; 21 | } 22 | Hash push(int e){ 23 | Hash r = up(1); 24 | for (int i = 0; i < HASH_COUNT; ++i) { 25 | r.v[i] = (r.v[i] + e) % MO[i]; 26 | } 27 | return r; 28 | } 29 | Hash operator+(const Hash h)const{ 30 | Hash r = (*this); 31 | for (int i = 0; i < HASH_COUNT; ++i) { 32 | r.v[i] = (r.v[i] + h.v[i]); 33 | if(r.v[i] > MO[i])r.v[i] -= MO[i]; 34 | } 35 | return r; 36 | } 37 | Hash operator-(const Hash h)const{ 38 | Hash r = (*this); 39 | for (int i = 0; i < HASH_COUNT; ++i) { 40 | r.v[i] = (r.v[i] - h.v[i]); 41 | if(r.v[i] < 0)r.v[i] += MO[i]; 42 | } 43 | return r; 44 | } 45 | bool operator<(const Hash &other)const{ 46 | for (int i = 0; i < HASH_COUNT; ++i) { 47 | if(v[i] != other.v[i]){ 48 | return v[i] < other.v[i]; 49 | } 50 | } 51 | return false; 52 | } 53 | }; 54 | ostream& operator<<(ostream &out, const Hash &H){ 55 | out << "{ "; 56 | for (int i = 0; i < HASH_COUNT; ++i) { 57 | out << H.v[i] << " "; 58 | } 59 | out << "}"; 60 | return out; 61 | } -------------------------------------------------------------------------------- /Codes/String/StringUtils.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | struct StringUtils 7 | { 8 | static string getRandString(int maxSize = 0) 9 | { 10 | if(maxSize == 0)maxSize = 100; 11 | string ret = ""; 12 | int sz = rand() % maxSize + 1; 13 | for(int i = 0; i < sz; ++i) 14 | ret += rand()%26 + 'a'; 15 | return ret; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /Codes/String/SubstringHash.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct Hash { 3 | VI PH, SH, PO; 4 | int N; 5 | #define add(a, b) ((a)+(b) >= MOD ? ((a)+(b)-MOD) ? (a)+(b)) 6 | #define mul(a, b) int((1LL * (a) * (b)) % MOD) 7 | #define sub(a, b) ((a)>=(b) ? (a)-(b) : (a)-(b) + MOD) 8 | Hash(const vector &s) : PH(s.size()), SH(s.size()), N((int) s.size()), PO(s.size()) { 9 | for (int i = 0; i < N; ++i) { 10 | PH[i] = add(mul(i == 0 ? 0 : PH[i-1], PR), s[i]); 11 | } 12 | for (int i = N-1; i >= 0; --i) { 13 | SH[i] = add(mul(i+1==N ? 0 : SH[i+1], PR), s[i]); 14 | } 15 | PO[0] = 1; 16 | for (int i = 1; i < N; ++i) { 17 | PO[i] = mul(PO[i-1], PR); 18 | } 19 | } 20 | int fh(int i, int j) { 21 | if (i == 0) return PH[j]; 22 | return sub(PH[j], mul(PH[i-1], PO[j - i + 1])); 23 | } 24 | int rh(int i, int j) { 25 | if (j+1==N) return SH[i]; 26 | return sub(SH[i], mul(SH[j+1], PO[j - i + 1])); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /Codes/String/SuffixArray(NlogN).cpp: -------------------------------------------------------------------------------- 1 | const int MAXN = 200010; 2 | struct SuffixArray 3 | { 4 | string A; 5 | int N; 6 | int SA[MAXN] , RA[MAXN] , LCP[MAXN]; 7 | SuffixArray(string &B) 8 | { 9 | A = B; N = A.size(); 10 | for(int i = 0; i < N; ++i) 11 | SA[i] = i , RA[i] = A[i]; 12 | } 13 | void countingSort(int H) 14 | { 15 | int maxn = max(N,300)+N; 16 | int freq[MAXN*2+300] , nSA[N]; memset(freq,0,sizeof(freq)); 17 | for(int i = 0; i < N; ++i) 18 | freq[ SA[i]+H= N || SA[i]+H >= N)rank++; 36 | else if(RA[ SA[i]+H ] != RA[ SA[i-1]+H ])rank++; 37 | nRA[ SA[i] ] = rank; 38 | } 39 | memcpy(RA,nRA,sizeof(nRA)); 40 | } 41 | } 42 | void BuildLCP() 43 | { 44 | int PLCP[MAXN]; 45 | int PHI[MAXN]; 46 | PHI[ SA[0] ] = -1; 47 | for(int i = 1; i < N; ++i) 48 | PHI[ SA[i] ] = SA[i-1]; 49 | for(int i = 0, L = 0; i < N; ++i) 50 | { 51 | if(PHI[i]==-1){PLCP[i] = 0;continue;} 52 | while(PHI[i]+L < N && i+L < N && A[i+L] == A[ PHI[i]+L ])L++; 53 | PLCP[i] = L; 54 | L = max(L-1 , 0); 55 | } 56 | for(int i = 1; i < N; ++i) 57 | LCP[i] = PLCP[ SA[i] ]; 58 | } 59 | pair Match(string &B) 60 | { 61 | int lo = 0, hi = N-1; 62 | for(int idx = 0; idx < B.size(); ++idx) 63 | { 64 | while(SA[lo]+idx>=N || A[SA[lo]+idx] idx-1)lo++; 67 | else break; 68 | } 69 | while(SA[hi]+idx>=N || A[SA[hi]+idx]>B[idx]) 70 | { 71 | if(hi>0 && LCP[hi] > idx-1)hi--; 72 | else break; 73 | } 74 | } 75 | return pair(lo,hi); 76 | } 77 | }; 78 | -------------------------------------------------------------------------------- /Codes/String/SuffixAutomaton.cpp: -------------------------------------------------------------------------------- 1 | struct SuffixAutomaton { 2 | struct Node { 3 | int link; 4 | map next; 5 | int len; 6 | int dp_num_of_substr, dp_len_of_substr; 7 | int cnt; 8 | Node() { 9 | dp_num_of_substr = dp_len_of_substr = -1; 10 | link = -1; 11 | next = map(); 12 | len = cnt = 0; 13 | } 14 | }; 15 | vector V; 16 | SuffixAutomaton(const string &S) { 17 | // cout <<"----> "<< S << endl; 18 | V.clear(); 19 | V.push_back(Node()); 20 | Node tmp; 21 | int last = 0; 22 | for (int i = 0; i < S.size(); ++i) { 23 | char c = S[i]; 24 | int curr = V.size(); 25 | V.push_back(Node()); 26 | V.back().cnt = 1; 27 | V[curr].len = V[last].len + 1; 28 | int p; 29 | for (p = last; p != -1 && !V[p].next.count(c); p = V[p].link) 30 | V[p].next[c] = curr; 31 | if (p == -1) { 32 | V[curr].link = 0; 33 | } else { 34 | int q = V[p].next[c]; 35 | if (V[p].len + 1 == V[q].len) { 36 | V[curr].link = q; 37 | } else { 38 | int clone = V.size(); 39 | V.push_back(Node()); 40 | V[clone].len = V[p].len + 1; 41 | V[clone].next = V[q].next; 42 | V[clone].link = V[q].link; 43 | for (; p != -1 && V[p].next[c] == q; p = V[p].link) 44 | V[p].next[c] = clone; 45 | V[q].link = V[curr].link = clone; 46 | } 47 | } 48 | last = curr; 49 | } 50 | } 51 | void computeOcurrences() { 52 | int ma = 0; 53 | for (int i = 0; i < V.size(); ++i) 54 | ma = max(ma, V[i].len); 55 | vector > TEMP(ma + 1, vector()); 56 | for (int i = 0; i < V.size(); ++i) 57 | TEMP[V[i].len].push_back(i); 58 | for (int i = ma; i >= 1; --i) 59 | for (int j = 0; j < TEMP[i].size(); ++j) 60 | V[V[TEMP[i][j]].link].cnt += V[TEMP[i][j]].cnt; 61 | } 62 | bool check(const string &P) { 63 | int v = 0; 64 | for (int i = 0; i < P.size(); ++i) { 65 | if (V[v].next.count(P[i]) == 0) 66 | return false; 67 | else 68 | v = V[v].next[P[i]]; 69 | } 70 | return true; 71 | } 72 | int numberOfSubstrings(int v = 0) { 73 | if (V[v].next.size() == 0) 74 | return 1; 75 | if (V[v].dp_num_of_substr != -1) 76 | return V[v].dp_num_of_substr; 77 | int w = v != 0; 78 | for (map::iterator it = V[v].next.begin(); 79 | it != V[v].next.end(); ++it) 80 | w += numberOfSubstrings(it->second); 81 | return V[v].dp_num_of_substr = w; 82 | } 83 | int totalLengthOfSubstrings(int v = 0, int l = 0) { 84 | if (V[v].next.size() == 0) 85 | return 0; 86 | if (V[v].dp_len_of_substr != -1) 87 | return V[v].dp_len_of_substr; 88 | int w = 0; 89 | for(map::iterator it = V[v].next.begin(); 90 | it != V[v].next.end(); ++it) 91 | w += totalLengthOfSubstrings(it->second) + numberOfSubstrings(it->second); 92 | return V[v].dp_len_of_substr = w; 93 | } 94 | int numberOfOcurrences(const string &P) { 95 | int v = 0; 96 | for (int i = 0; i < P.size(); ++i) 97 | if (V[v].next.count(P[i]) == 0) 98 | return 0; 99 | else 100 | v = V[v].next[P[i]]; 101 | return V[v].cnt; 102 | } 103 | int numberRotationOcurrences(const string &P) { 104 | string P2 = P + P; 105 | int v = 0; 106 | for (int i = 0; i < P.size(); ++i) 107 | if (V[v].next.count(P[i]) == 0) 108 | return 0; 109 | else 110 | v = V[v].next[P[i]]; 111 | return V[v].cnt; 112 | } 113 | }; -------------------------------------------------------------------------------- /Codes/String/SuffixTree(uses SuffixArray).cpp: -------------------------------------------------------------------------------- 1 | struct SuffixTree { 2 | struct Node { 3 | Node* child[26]; 4 | Node* parent; 5 | int st, en; 6 | Node(int st, int en):st(st),en(en){ 7 | memset(child, 0, 26 * sizeof(Node*)); 8 | parent = NULL; 9 | } 10 | int size(){ 11 | return en - st + 1; 12 | } 13 | }; 14 | Node* root; 15 | string S; 16 | int N; 17 | #define decode(ch) (ch=='$' ? 0 : (ch-'a' + 1)) 18 | SuffixTree(const string &str):S(str + "$"){ 19 | N = S.size(); 20 | root = new Node(0, -1); 21 | SuffixArray SA(S); 22 | SA.BuildLCP(); 23 | Node* act = root; 24 | for(int i = 0; i < SA.N; ++i){ 25 | int st = SA.SA[i]; 26 | int en = SA.N-1; 27 | Node* newNode = new Node(st, en); 28 | if(i > 0){ 29 | int skip = (N - SA.SA[i-1]) - SA.LCP[i]; 30 | newNode->st += SA.LCP[i]; 31 | while(skip > 0 && skip >= act->size()){ 32 | skip -= act->size(); 33 | act = act->parent; 34 | } 35 | if(skip > 0){ 36 | int sp = act->size() - skip; 37 | act = split(act, sp); 38 | } 39 | } 40 | join(act, newNode); 41 | act = newNode; 42 | } 43 | } 44 | Node* split(Node *v , int sz){ 45 | int newEnd = v->st + sz - 1; 46 | int newStart = newEnd + 1; 47 | Node* newNode = new Node(v->st, newEnd); 48 | v->st = newStart; 49 | join(v->parent, newNode); 50 | join(newNode, v); 51 | return newNode; 52 | } 53 | void join(Node* parent, Node* child){ 54 | parent->child[ decode(S[child->st]) ] = child; 55 | child->parent = parent; 56 | } 57 | void print(ostream &out){ 58 | print(out, root); 59 | } 60 | void print(ostream &out, Node *v, int LVL = 0){ 61 | out << string(LVL, '\t') << S.substr(v->st, v->size()) << endl; 62 | for (int i = 0; i < 26; ++i) { 63 | if(v->child[i]) 64 | print(out, v->child[i], LVL+1); 65 | } 66 | } 67 | #undef decode 68 | }; -------------------------------------------------------------------------------- /Codes/String/Trie.cpp: -------------------------------------------------------------------------------- 1 | struct Trie { 2 | struct Node { 3 | int childs[26] , cnt; 4 | Node(){ 5 | cnt = 0; 6 | memset(childs , -1, sizeof(childs)); 7 | } 8 | }; 9 | vector V; 10 | Trie(int reserved = 0) { 11 | V = vector(); 12 | V.reserve(reserved); 13 | V.push_back(Node()); 14 | } 15 | void insert(const string &S) { 16 | int v = 0; 17 | V[v].cnt++; 18 | for(int i = 0; i < S.size(); ++i) { 19 | int p = S[i] - 'a'; 20 | if(V[v].childs[p] == -1){ 21 | V[v].childs[p] = V.size(); 22 | V.push_back(Node()); 23 | } 24 | v = V[v].childs[p]; 25 | V[v].cnt++; 26 | } 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /Codes/Trees/BalancedTrees/VectorTreap.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct VectorTreap { 3 | struct Node{ 4 | int y, sz; 5 | T x, sum; 6 | Node *l, *r; 7 | Node(T x):x(x),sum(x){ y = rand(); sz = 1; l = r = NULL; } 8 | void update(){ 9 | sz = 1 + (r?r->sz:0) + (l?l->sz:0); 10 | sum= x + (r?r->sum:T()) + (l?l->sum:T()); 11 | } 12 | int lsz(){ return (l?l->sz:0); } 13 | }; 14 | Node *root; 15 | VectorTreap(){ root = NULL; } 16 | void split (Node *t, int sz, Node *&l, Node *&r) { 17 | if (!t)l = r = NULL; 18 | else if ( sz <= t->lsz() ) split (t->l, sz, l, t->l), r = t; 19 | else split (t->r, sz-t->lsz()-1, t->r, r), l = t; 20 | if(t)t->update(); 21 | } 22 | void insertAt(int pos, T x){ insertAt(pos, root, new Node(x)); } 23 | void insertAt (int sz, Node *&t, Node *it) { 24 | if(!t)t = it; 25 | else if(it->y > t->y) split(t, sz, it->l, it->r), t = it; 26 | else if(sz <= t->lsz()) insertAt(sz, t->l, it); 27 | else insertAt(sz - t->lsz() - 1, t->r, it); 28 | t->update(); 29 | } 30 | void eraseAt(int pos){ if(root) eraseAt(pos, root); } 31 | void eraseAt(int sz, Node *&t){ 32 | if(sz == t->lsz()) delete merge(t, t->l, t->r); 33 | else if(sz < t->lsz()) eraseAt(sz, t->l); 34 | else eraseAt(sz - t->lsz()-1, sz, t->r); 35 | if(t)t->update(); 36 | } 37 | Node* merge (Node *&t, Node *l, Node *r) { 38 | Node *old = t; 39 | if (!l || ! r) t = l? l: r; 40 | else if (l->y > r->y) merge (l->r, l->r, r), t = l; 41 | else merge (r->l, l, r->l), t = r; 42 | if(t)t->update(); 43 | return old; 44 | } 45 | int size(){ return root?root->sz:0; } 46 | T range(int b, int e){ 47 | Node *l, *m, *r; 48 | split(root, e+1, l, r); split(l, b, l, m); 49 | T cnt = m ? m->sum : T(); 50 | merge(l, l, m); merge(root, l, r); 51 | return cnt; 52 | } 53 | void clear(){ clear(root);} 54 | void clear(Node *&t){ 55 | if(!t)return; 56 | clear(t->l); clear(t->r); 57 | delete t; t = NULL; 58 | } 59 | void print(bool asArray = false){ 60 | if(root)asArray ? printArray(root) : printTree(root); 61 | cout << endl; 62 | } 63 | void printArray(Node *p, int LVL = 0){ 64 | if(p->l)printArray(p->l, LVL+1); 65 | cout << (p->x) << " "; 66 | if(p->r)printArray(p->r, LVL+1); 67 | } 68 | void printTree(Node *p, int LVL = 0){ 69 | if(p->r)printTree(p->r, LVL+1); 70 | cout <x) << "\n"; 71 | if(p->l)printTree(p->l, LVL+1); 72 | } 73 | }; -------------------------------------------------------------------------------- /Codes/Trees/BalancedTrees/VectorTreapUpdate.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct VectorTreap { 3 | struct Node{ 4 | int y, sz; 5 | T x, sum; 6 | U carry; 7 | Node *l, *r; 8 | Node(T x):x(x),sum(x){ y = rand(); sz = 1; l = r = NULL; } 9 | void update(){ 10 | sz = 1 + (r?r->sz:0) + (l?l->sz:0); 11 | sum= x + (r?r->sum:T()) + (l?l->sum:T()); 12 | } 13 | void apply(U u){ 14 | carry += u; 15 | u.apply(x, sum, sz); 16 | } 17 | void push(){ 18 | if(l)l->apply(carry); 19 | if(r)r->apply(carry); 20 | carry = U(); 21 | } 22 | int lsz(){ return (l?l->sz:0); } 23 | }; 24 | Node *root; 25 | VectorTreap(){ root = NULL; } 26 | void split (Node *t, int sz, Node *&l, Node *&r) { 27 | if(t)t->push(); 28 | if (!t)l = r = NULL; 29 | else if ( sz <= t->lsz() ) split (t->l, sz, l, t->l), r = t; 30 | else split (t->r, sz-t->lsz()-1, t->r, r), l = t; 31 | if(t)t->update(); 32 | } 33 | void insertAt(int pos, T x){ insertAt(pos, root, new Node(x)); } 34 | void insertAt (int sz, Node *&t, Node *it) { 35 | if(t)t->push(); 36 | if(!t)t = it; 37 | else if(it->y > t->y) split(t, sz, it->l, it->r), t = it; 38 | else if(sz <= t->lsz()) insertAt(sz, t->l, it); 39 | else insertAt(sz - t->lsz() - 1, t->r, it); 40 | if(t)t->update(); 41 | } 42 | void eraseAt(int pos){ if(root) eraseAt(pos, root); } 43 | void eraseAt(int sz, Node *&t){ 44 | if(t)t->push(); 45 | if(sz == t->lsz()) delete merge(t, t->l, t->r); 46 | else if(sz < t->lsz()) eraseAt(sz, t->l); 47 | else eraseAt(sz - t->lsz()-1, sz, t->r); 48 | if(t)t->update(); 49 | } 50 | Node* merge (Node *&t, Node *l, Node *r) { 51 | if(l)l->push(); 52 | if(r)r->push(); 53 | Node *old = t; 54 | if (!l || ! r) t = l? l: r; 55 | else if (l->y > r->y) merge (l->r, l->r, r), t = l; 56 | else merge (r->l, l, r->l), t = r; 57 | if(t)t->update(); 58 | return old; 59 | } 60 | int size(){ return root?root->sz:0; } 61 | T range(int b, int e){ 62 | Node *l, *m, *r; 63 | split(root, e+1, l, r); split(l, b, l, m); 64 | T cnt = m ? m->sum : T(); 65 | merge(l, l, m); merge(root, l, r); 66 | return cnt; 67 | } 68 | void apply(int b, int e, U u){ 69 | Node *l, *m, *r; 70 | split(root, e+1, l, r); split(l, b, l, m); 71 | if(m)m->apply(u); 72 | merge(l, l, m); merge(root, l, r); 73 | } 74 | void clear(){ clear(root);} 75 | void clear(Node *&t){ 76 | if(!t)return; 77 | clear(t->l); clear(t->r); 78 | delete t; t = NULL; 79 | } 80 | void print(bool asArray = false)const{ 81 | if(root)asArray ? printArray(root) : printTree(root); 82 | cout << endl; 83 | } 84 | void printArray(Node *p, int LVL = 0)const{ 85 | p->push(); 86 | if(p->l)printArray(p->l, LVL+1); 87 | cout << (p->x) << " "; 88 | if(p->r)printArray(p->r, LVL+1); 89 | } 90 | void printTree(Node *p, int LVL = 0)const{ 91 | p->push(); 92 | if(p->r)printTree(p->r, LVL+1); 93 | cout <x) << "\n"; 94 | if(p->l)printTree(p->l, LVL+1); 95 | } 96 | }; 97 | template 98 | struct NOP { 99 | void apply(T &x, T &sum, int sz){ } 100 | NOP operator+=(const NOP &N)const{ return NOP(); } 101 | }; 102 | struct Add { 103 | int val = 0; 104 | void apply(int &x, int &sum, int sz){ 105 | x += val; 106 | sum += val * sz; 107 | } 108 | void operator+=(const Add &N){ 109 | val += N.val; 110 | } 111 | }; -------------------------------------------------------------------------------- /Codes/Trees/BlockedFenwick2D.cpp: -------------------------------------------------------------------------------- 1 | /// This fenwick is used when N^2 is too big to fit in memory. 2 | /// For efficiency it is required that point are never heavily-clustered in a block 3 | /// Complexity is: 4 | /// Query: (MAX_CLUSTER + log(N/BSIZE)^2) 5 | /// Update: log(N/BSIZE)^2 6 | struct Fenwick2D { 7 | const int BSIZE = 300; 8 | struct Update { 9 | int x,y,v; 10 | }; 11 | int N; 12 | VVI F; 13 | vector> X; 14 | vector> Y; 15 | Fenwick2D(int n):N(n / BSIZE+2), F(n / BSIZE+2, VI(n / BSIZE+2)), X(n / BSIZE+2), Y(n / BSIZE+2){} 16 | void ins(int x, int y, int v){ 17 | _ins(x / BSIZE, y / BSIZE, v); 18 | addOrRemove(X[x/BSIZE], {x, y, v}); 19 | addOrRemove(Y[y/BSIZE], {x, y, v}); 20 | } 21 | void addOrRemove(vector &V, Update u) { 22 | for (int i = 0; i < V.size(); ++i) { 23 | if (V[i].x == u.x && V[i].y == u.y && V[i].v == -u.v) { 24 | V.erase(V.begin() + i); 25 | return; 26 | } 27 | } 28 | V.push_back(u); 29 | } 30 | void _ins(int x, int y, int v){ 31 | for (int i = x+1; i < N; i += i & -i) { 32 | for (int j = y+1; j < N; j += j & -j) { 33 | F[i][j] += v; 34 | } 35 | } 36 | } 37 | int get(int x, int y){ 38 | int r = _get(x / BSIZE, y / BSIZE); 39 | for(Update u : X[x / BSIZE]) if(u.y/BSIZE <= y/BSIZE && u.x > x) r -= u.v; 40 | for(Update u : Y[y / BSIZE]) if(u.x <= x && u.y > y) r -= u.v; 41 | return r; 42 | } 43 | int _get(int x, int y){ 44 | int r = 0; 45 | for (int i = x+1; i > 0; i -= i & -i) { 46 | for (int j = y+1; j > 0; j -= j & -j) { 47 | r += F[i][j]; 48 | } 49 | } 50 | return r; 51 | } 52 | }; 53 | -------------------------------------------------------------------------------- /Codes/Trees/CentroidDecompShort.cpp: -------------------------------------------------------------------------------- 1 | struct Centroid { 2 | struct Edge { int u, v, w; }; 3 | vector> adj; 4 | vector> centAdj; 5 | 6 | vector SZ; // size of the nodes in centered at u 7 | vector L; // level in the centroid tree 8 | vector P; // parent in the centroid tree 9 | int root; 10 | Centroid(int N): adj(N), centAdj(N), SZ(N), L(N, -1), P(N, -1), root(-1){ } 11 | void addEdge(int u,int v, int w) { 12 | adj[u].push_back((Edge){u, v, w}); 13 | adj[v].push_back((Edge){v, u, w}); 14 | } 15 | int dfsSz(int u, int p = -1) { 16 | SZ[u] = 1; 17 | for (Edge &e : adj[u]) 18 | if (e.v != p && L[e.v] == -1) 19 | SZ[u] += dfsSz(e.v, u); 20 | return SZ[u]; 21 | } 22 | int getCentroid(int u, int sz, int p = -1) { 23 | for (Edge &e : adj[u]) 24 | if (e.v != p && L[e.v] == -1 && SZ[e.v] > sz / 2) 25 | return getCentroid(e.v, sz, u); 26 | return u; 27 | } 28 | void computeCentroid(int root = 0, int prev = -1, int lvl = 0){ 29 | int cent = getCentroid(root, dfsSz(root)); 30 | L[cent] = lvl; P[cent] = prev; SZ[cent] = SZ[root]; 31 | if(prev == -1) this->root = cent; else centAdj[prev].push_back(cent); 32 | for(Edge &e : adj[cent]) 33 | if (L[e.v] == -1) 34 | computeCentroid(e.v, cent, lvl + 1); 35 | } 36 | int lca(int u, int v){ 37 | while(L[u] > L[v])u = P[u]; 38 | while(L[v] > L[u])v = P[v]; 39 | while(u != v)u = P[u], v = P[v]; 40 | return u; 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /Codes/Trees/CentroidDecomposition.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | using namespace std; 13 | typedef long long Long; 14 | 15 | 16 | typedef vector VI; 17 | typedef vector VVI; 18 | typedef pair PII; 19 | typedef pair PPI; 20 | 21 | struct CentroidDecomp { 22 | VVI adj; 23 | VI P, DI, SSZ; 24 | int N; 25 | 26 | // temp arrays 27 | VI V , SZ, BL; 28 | int TC; 29 | CentroidDecomp(int N):N(N){ 30 | adj = VVI(N); 31 | TC = 0; 32 | } 33 | void addEdge(int u,int v){ 34 | adj[u].push_back(v); 35 | adj[v].push_back(u); 36 | } 37 | void doneAddingEdges(){ 38 | for(int i = 0; i < N; ++i){ 39 | sort(adj[i].begin(), adj[i].end()); 40 | } 41 | } 42 | int getCentroid(int u, int sz){ 43 | V[u] = TC; 44 | SZ[u] = 1; 45 | int ma = 0, ans = -1; 46 | for(int i = 0; i < adj[u].size(); ++i){ 47 | int v = adj[u][i]; 48 | if(V[v] == TC || BL[v])continue; 49 | int t = getCentroid(v, sz); 50 | if(t != -1 && ans == -1) 51 | ans = t; 52 | SZ[u] += SZ[v]; 53 | ma = max(ma, SZ[v]); 54 | } 55 | ma = max(ma, sz-SZ[u]); 56 | 57 | 58 | if(2*ma <= sz) return u; 59 | if(ans != -1) return ans; 60 | return -1; 61 | 62 | } 63 | void dfs(int u, int &ma, int &maId,int LVL = 0){ 64 | V[u] = TC; 65 | if(LVL > ma){ 66 | maId = u; 67 | ma = LVL; 68 | } 69 | for(int i = 0; i < adj[u].size(); ++i){ 70 | int v = adj[u][i]; 71 | if(V[v] == TC || BL[v])continue; 72 | dfs(v,ma,maId,LVL + 1); 73 | } 74 | } 75 | int getHeight(int u){ 76 | TC++; 77 | int ma = -1, maId = -1; 78 | dfs(u, ma, maId); 79 | return ma; 80 | } 81 | void getCentroids(){ 82 | stack STK; 83 | STK.push(PPI(PII(0,-1),N)); // start , forbidden , size of tree 84 | V = vector(N); 85 | SZ = vector(N); 86 | BL = vector(N); 87 | P = vector(N); 88 | DI = vector(N); 89 | SSZ= vector(N); 90 | 91 | 92 | while(STK.size()){ 93 | PPI c = STK.top(); STK.pop(); 94 | TC++; 95 | int cent = getCentroid(c.first.first, c.second); 96 | DI[cent] = getHeight(cent); 97 | SSZ[cent]= c.second; 98 | P[cent] = c.first.second; 99 | if(cent < 0)return; 100 | BL[cent] = 1; 101 | for(int i = 0; i < adj[cent].size(); ++i){ 102 | int v = adj[cent][i]; 103 | if(BL[v])continue; 104 | if(SZ[v] > SZ[cent]){ 105 | STK.push(PPI(PII(v,cent),c.second - SZ[cent])); 106 | }else{ 107 | STK.push(PPI(PII(v,cent),SZ[v])); 108 | } 109 | } 110 | cout << endl; 111 | } 112 | 113 | for (int i = 0; i < N; ++i) { 114 | cout << P[i] << ":" << DI[i] << ":" << SSZ[i] << " "; 115 | } 116 | cout << endl; 117 | 118 | } 119 | void decompose(){ 120 | vector SZ(N,0); 121 | vector V(N,0); 122 | 123 | } 124 | }; 125 | 126 | 127 | int main() 128 | { 129 | int N,M; 130 | cin >> N >> M; 131 | CentroidDecomp CD(N); 132 | for (int i = 0; i < N-1; ++i) { 133 | int u,v; 134 | cin >> u >> v; 135 | u--;v--; 136 | CD.addEdge(u,v); 137 | } 138 | CD.getCentroids(); 139 | } 140 | /* 141 | 142 | 6 6 143 | 2 4 144 | 1 2 145 | 3 1 146 | 2 5 147 | 5 6 148 | 149 | 1 2 6 150 | 3 1 2 151 | 1 0 5 152 | 4 3 7 153 | 154 | 155 | */ 156 | -------------------------------------------------------------------------------- /Codes/Trees/CompressedFenwick2D.cpp: -------------------------------------------------------------------------------- 1 | // http://codeforces.com/blog/entry/13813?#comment-187855 2 | struct Fenwick2D { 3 | struct Point { 4 | int x, y; 5 | }; 6 | int N; 7 | VVI F; 8 | VVI order; 9 | VI X; 10 | void build(vector P) 11 | { 12 | X.reserve(P.size()); 13 | for(Point p : P)X.push_back(p.x); 14 | sort(X.begin(), X.end()); 15 | X.erase(unique(X.begin(), X.end()), X.end()); 16 | N = X.size() + 1; 17 | F.resize(N); 18 | order.resize(N); 19 | for(Point &p : P){ 20 | p.x = upper_bound(X.begin(), X.end(), p.x) - X.begin(); 21 | } 22 | sort(P.begin(), P.end(), [](const Point &a, const Point &b){ return a.y < b.y; }); 23 | for(Point p : P){ 24 | for (int x = p.x; x < N; x += x & -x) { 25 | order[x].push_back(p.y); 26 | } 27 | } 28 | for(int i = 0; i < N; ++i){ 29 | F[i].resize(order[i].size() + 1); 30 | } 31 | } 32 | int getIndex(int x, VI &O){ return upper_bound(O.begin(), O.end(), x) - O.begin(); } 33 | int get(int x, int y){ 34 | int ans = 0; 35 | for (int i = getIndex(x, X); i > 0; i -= i & -i) { 36 | for(int j = getIndex(y, order[i]); j > 0; j -= j & -j){ 37 | ans += F[i][j]; 38 | } 39 | } 40 | return ans; 41 | } 42 | void add(int x, int y, int v){ 43 | for (int i = getIndex(x, X); i < F.size(); i += (i & -i)) { 44 | for(int j = getIndex(y, order[i]); j < F[i].size(); j += (j & -j)){ 45 | F[i][j] += v; 46 | } 47 | } 48 | } 49 | }; -------------------------------------------------------------------------------- /Codes/Trees/DinamycReversibleSegmentTree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | struct SplayTree { 8 | struct Node { 9 | Node *p, *r, *l; 10 | int sz,gid, id,rev; 11 | int val , pending , ma , carr; 12 | Node() { 13 | static int IDX = 0; 14 | p = r = l = NULL; 15 | gid = IDX++; 16 | rev = 0; 17 | id = 0; 18 | sz = 1; 19 | val = pending = ma = carr = 0; 20 | } 21 | bool isRoot() { 22 | return p == NULL; 23 | } 24 | void pushDown() { 25 | if(rev){ 26 | swap(r,l); 27 | if(r)r->rev ^= 1; 28 | if(l)l->rev ^= 1; 29 | rev = 0; 30 | } 31 | if(pending){ 32 | if(r)r->applyChange(carr); 33 | if(l)l->applyChange(carr); 34 | pending = 0; 35 | carr = 0; 36 | } 37 | } 38 | void applyChange(int v){ 39 | val += v; 40 | carr += v; 41 | ma += sz * v; 42 | pending = 1; 43 | } 44 | void update() { 45 | sz = 1 + (r?r->sz:0) + (l?l->sz:0); 46 | ma = val; 47 | if(r)ma += r->ma; 48 | if(l)ma += l->ma; 49 | } 50 | }; 51 | Node* root; 52 | vector V; 53 | int N; 54 | SplayTree(int N) : 55 | N(N) { 56 | V = vector(N); 57 | root = &V[0]; 58 | for (int i = 0; i < N; ++i){ 59 | V[i].id = i; 60 | V[i].sz = N-i; 61 | if(i+1p) 69 | return; 70 | Node *p = v->p; 71 | p->pushDown(); 72 | v->pushDown(); 73 | Node *g = p->p; 74 | p->p = v; v->p = g; 75 | if (p->l == v) { p->l = v->r; v->r = p; if (p->l) p->l->p = p; } 76 | else { p->r = v->l; v->l = p; if (p->r) p->r->p = p; } 77 | if (g && (g->l == p || g->r == p)) 78 | (g->l == p ? g->l : g->r) = v; 79 | else root = v; 80 | p->update(); 81 | v->update(); 82 | } 83 | void splay(Node *v) { 84 | v->pushDown(); 85 | while (!v->isRoot()) 86 | moveUp(v); 87 | } 88 | Node* operator[](int k){ 89 | Node *v = root; 90 | v->pushDown(); 91 | while(k != (v->l?v->l->sz:0)){ 92 | if(k < (v->l?v->l->sz:0)){ 93 | v = v->l; 94 | }else{ 95 | k -= (v->l?v->l->sz:0)+1; 96 | v = v->r; 97 | } 98 | v->pushDown(); 99 | } 100 | splay(v); 101 | return v; 102 | } 103 | void applyChange(int i,int j,int v){ 104 | Node* J = (*this)[j]; 105 | if(J->r)(*this)[j+1]; 106 | if(i != 0)(*this)[i-1]; 107 | J->applyChange(v); 108 | } 109 | void reverseB(Node *B){ 110 | splay(B); 111 | B->pushDown(); 112 | if(B->r) { 113 | Node *r = B->r; r->pushDown(); 114 | while(r->l){ 115 | r = r->l; r->pushDown(); 116 | } 117 | splay(r); 118 | } 119 | B->rev ^= 1; 120 | } 121 | void reverse(int i,int j){ 122 | if(i == 0){ 123 | Node* J = (*this)[j]; 124 | reverseB(J); 125 | }else{ 126 | Node* J = (*this)[j]; 127 | reverseB(J); 128 | Node* I = (*this)[j-i]; 129 | reverseB(I); 130 | J = (*this)[j]; 131 | reverseB(J); 132 | } 133 | } 134 | void print(Node* v, int LVL = 0){ 135 | v->pushDown(); 136 | if(v->r)print(v->r,LVL+1); 137 | cout <id << "|" << v->sz << endl; 138 | if(v->l)print(v->l,LVL+1); 139 | } 140 | void print(){ print(root); } 141 | }; 142 | 143 | int main(){ 144 | SplayTree V(80); 145 | V.applyChange(10,20,3); 146 | V.applyChange(15,30,7); 147 | V.reverse(0,79); 148 | V.applyChange(0,79,2); 149 | for(int i = 0; i < 80; ++i) 150 | cout << V[i]->val << " "; 151 | cout << endl; 152 | } 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /Codes/Trees/DisjointSet.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | struct DisjointSet 5 | { 6 | vector P; // if < 0 then negative size, else parentId 7 | DisjointSet(int N) : P(N, -1) {} 8 | int find(int x) { 9 | return P[x] < 0 ? x : (P[x] = find(P[x])); 10 | } 11 | bool join(int x,int y) { 12 | if((x = find(x)) == (y = find(y))) return false; 13 | if(P[y] < P[x]) swap(x,y); 14 | P[x] += P[y]; 15 | P[y] = x; 16 | return true; 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /Codes/Trees/DynamicTrees/EulerTree.cpp: -------------------------------------------------------------------------------- 1 | struct EulerTree { 2 | struct Node { 3 | Node *p,*r,*l; 4 | int sz,gid,id; 5 | Node(){ 6 | static int IDX = 0; 7 | p = r = l = NULL; 8 | sz = 1; gid = IDX++; id=0; 9 | } 10 | void pushDown(){ } 11 | void update(){ 12 | sz = 1 + (l?l->sz:0) + (r?r->sz:0); 13 | } 14 | }; 15 | vector ST, EN; int N = 0; 16 | EulerTree(int N) { 17 | for (int i = 0; i < N; ++i) 18 | createNode(); 19 | } 20 | void createNode(){ 21 | Node *s = new Node(), *e = new Node(); 22 | e->id = s->id = N++; 23 | s->r = e; e->p = s; 24 | s->update(); 25 | ST.push_back(s); EN.push_back(e); 26 | } 27 | void moveUp(Node *v){ 28 | if(!v->p)return; 29 | Node *p = v->p; 30 | p->pushDown(); v->pushDown(); 31 | Node *g = p->p; 32 | p->p = v; v->p = g; 33 | if(p->l == v){ p->l = v->r; v->r = p; if(p->l)p->l->p = p; } 34 | else { p->r = v->l; v->l = p; if(p->r)p->r->p = p; } 35 | if(g && (g->l == p || g->r == p))(g->l == p ? g->l : g->r) = v; 36 | p->update();v->update(); 37 | } 38 | void splay(Node *v){ 39 | while(v->p) moveUp(v); 40 | } 41 | void link(int u, int v){ 42 | Node *su = ST[u], *ev = EN[v]; 43 | splay(su); su->pushDown(); 44 | splay(ev); ev->pushDown(); 45 | if(!ev->r){ 46 | Node *m = ST[u]->r; 47 | su->r = ev; ev->p = su; 48 | m->p = ev; ev->r = m; 49 | ev->update(); su->update(); 50 | } 51 | } 52 | void cut(int v){ 53 | Node *sv = ST[v], *ev = EN[v]; 54 | splay(ev); splay(sv); 55 | if(sv->l){ 56 | Node *le = sv->l, *ri = ev->r; 57 | while(le->r) le = le->r; 58 | while(ri->l) ri = ri->l; 59 | splay(ri); splay(le); 60 | ri->l = NULL; sv->p = NULL; // s->p == ri->l 61 | ri->update(); le->update(); 62 | } 63 | } 64 | void print(bool asArray = false){ 65 | for(int i = 0; i < N; ++i) 66 | if(!ST[i]->p || !EN[i]->p){ 67 | Node *tp = !ST[i]->p ? ST[i] : EN[i]; 68 | !asArray ? printTree(tp) : printArray(tp); 69 | if(!asArray)cout << "-----------------------" << endl; 70 | else cout << endl; 71 | } 72 | } 73 | void printTree(Node *v, int LVL = 0){ 74 | if(v->r)printTree(v->r,LVL+1); 75 | cout << string(LVL,'\t') << v->id << "| " << v->sz << " " << (v->p ? v->p->gid : -1) << endl; 76 | if(v->l)printTree(v->l,LVL+1); 77 | } 78 | void printArray(Node *v, int LVL = 0){ 79 | if(v->l)printArray(v->l,LVL+1); 80 | cout << v->id << " "; 81 | if(v->r)printArray(v->r,LVL+1); 82 | } 83 | }; -------------------------------------------------------------------------------- /Codes/Trees/DynamicTrees/LinkCutTree.cpp: -------------------------------------------------------------------------------- 1 | struct LinkCutTree 2 | { 3 | struct Node 4 | { 5 | Node *p,*r,*l; 6 | int sz,gid,id,csz; 7 | Node(){ 8 | static int IDX = 0; 9 | p = r = l = NULL; 10 | sz = 1; gid = IDX++; id=0; 11 | csz = 0; 12 | } 13 | bool isLocalRoot(){ 14 | return p == NULL || (p->r != this && p->l != this); 15 | } 16 | void pushDown(){ 17 | if(l)l->addSize(csz); 18 | if(r)r->addSize(csz); 19 | csz = 0; 20 | } 21 | void update(){ 22 | } 23 | void addSize(int sz){ 24 | csz += sz; 25 | this->sz += sz; 26 | } 27 | }; 28 | vector V; int N; 29 | LinkCutTree(int N) : N(N){ 30 | V = vector(N); 31 | for (int i = 0; i < N; ++i) 32 | V[i].id = i; 33 | } 34 | void moveUp(Node *v){ 35 | if(!v->p)return; 36 | Node *p = v->p; 37 | p->pushDown(); v->pushDown(); 38 | Node *g = p->p; 39 | p->p = v; 40 | v->p = g; 41 | if(p->l == v){ p->l = v->r; v->r = p; if(p->l)p->l->p = p; } 42 | else { p->r = v->l; v->l = p; if(p->r)p->r->p = p; } 43 | if(g && (g->l == p || g->r == p))(g->l == p ? g->l : g->r) = v; 44 | p->update();v->update(); 45 | } 46 | void splay(Node *v){ 47 | while(!v->isLocalRoot()) 48 | moveUp(v); 49 | } 50 | void expose(int v){ _expose(&V[v]); } 51 | Node* _expose(Node *v){ 52 | Node* last = NULL; 53 | for(Node *x = v; x ; x = x->p){ 54 | splay(x); 55 | x->pushDown(); 56 | x->r = last; 57 | x->update(); 58 | last = x; 59 | } 60 | splay(v); 61 | return last; 62 | } 63 | void link(int u,int v){ if(findRoot(u) != findRoot(v))_link(&V[u],&V[v]); } 64 | void _link(Node *u,Node *v){ 65 | _expose(v); 66 | if (!v->l) { 67 | v->p = u; 68 | _expose(v); 69 | v->l->addSize(v->sz); 70 | v->update(); 71 | } 72 | } 73 | void cut(int v){ _cut(&V[v]); } 74 | void _cut(Node *v) { 75 | _expose(v); 76 | if (v->l) { 77 | v->l->addSize(-v->sz); 78 | v->l->p = NULL; 79 | v->l = NULL; 80 | v->update(); 81 | } 82 | } 83 | int findRoot(int v){ return _findRoot(&V[v])->id; } 84 | Node* _findRoot(Node* v) { 85 | _expose(v); 86 | while (v->l) 87 | v = v->l; 88 | splay(v); 89 | return v; 90 | } 91 | int findLCA(int u,int v) { Node* lc = _findLCA(&V[u],&V[v]); return lc==NULL ? -1 : lc->id; } 92 | Node* _findLCA(Node* u, Node* v) 93 | { 94 | if (_findRoot(u) != _findRoot(v))return NULL; 95 | _expose(u); 96 | return _expose(v); 97 | } 98 | void print(){ 99 | for(int i = 0; i < N; ++i) 100 | if(V[i].isLocalRoot()){ 101 | print(&V[i]); 102 | cout << "-----------------------" << endl; 103 | } 104 | } 105 | void print(Node *v, int LVL = 0){ 106 | if(v->r)print(v->r,LVL+1); 107 | cout << string(LVL,'\t') << v->id << "| " << v->sz << " " << (v->p ? v->p->id : -1) << " " << v->csz << endl; 108 | if(v->l)print(v->l,LVL+1); 109 | } 110 | }; -------------------------------------------------------------------------------- /Codes/Trees/FEDisjointSet: -------------------------------------------------------------------------------- 1 | struct FEDisjointSet { 2 | VI P, E; 3 | FEDisjointSet(int N) : P(N, -1), E(N, -1) { } 4 | int find(int x) { 5 | return P[x] < 0 ? x : find(P[x]); 6 | } 7 | bool joinFriend(int x, int y) { 8 | x = find(x); y = find(y); 9 | if (x == y) return true; 10 | if (P[y] < P[x]) swap(x, y); 11 | P[x] += P[y]; 12 | P[y] = x; 13 | if (E[x] != -1 && E[y] != -1) joinFriend(E[x], E[y]); 14 | if (E[y] != -1) E[x] = find(E[x]); 15 | return true; 16 | } 17 | bool joinEnemy(int x, int y) { 18 | x = find(x); y = find(y); 19 | if (x == y) return false; 20 | if (E[x] != -1) joinFriend(E[x], y); // my enemy is the friend of my enemy 21 | if (E[y] != -1) joinFriend(E[y], x); // the enemy of my enemy is my friend 22 | E[x] = find(y); 23 | E[y] = find(x); 24 | return true; 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /Codes/Trees/FenwickTree.cpp: -------------------------------------------------------------------------------- 1 | struct Fenwick { 2 | vector V; 3 | int hb; 4 | Fenwick(int N) : V(N+10) { 5 | hb = 1; 6 | while (hb*2 < V.size()) hb <<= 1; 7 | } 8 | void add(int x, Long v) { 9 | for (int i = x + 1; i < V.size(); i += (i & -i)) { 10 | V[i] += v; 11 | } 12 | } 13 | Long get(int x) { 14 | Long r = 0; 15 | for (int i = x + 1; i > 0; i -= (i & -i)) { 16 | r += V[i]; 17 | } 18 | return r; 19 | } 20 | // V.size() - 1 if not found 21 | Long lowerBound(Long val) { 22 | int ans = 0; 23 | for (int i = hb; i > 0; i >>= 1) { 24 | int nans = ans | i; 25 | if (nans < V.size() && V[nans] < val) { 26 | ans = nans; 27 | val -= V[ans]; 28 | } 29 | } 30 | return ans; 31 | } 32 | Long segSum(int i, int j) { 33 | return get(j) - get(i-1); 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /Codes/Trees/HLD.cpp: -------------------------------------------------------------------------------- 1 | struct HLD { 2 | int N; 3 | VI SZ, P, ST, EN, TOP, LVL, PERM; 4 | VVI adj; 5 | HLD(int N) : N(N), adj(N), PERM(N), SZ(N), P(N), ST(N), EN(N), TOP(N), LVL(N) {} 6 | void addEdge(int u, int v) { 7 | adj[u].push_back(v); 8 | adj[v].push_back(u); 9 | } 10 | int dfsSZ(int u, int p = -1, int lvl = 0) { 11 | SZ[u] = 1; P[u] = p; LVL[u] = lvl; int bi = -1; 12 | for (int i = 0; i < adj[u].size(); ++i) { 13 | int v = adj[u][i]; 14 | if (v == p) continue; 15 | SZ[u] += dfsSZ(v, u, lvl + 1); 16 | if (bi == -1 || SZ[adj[u][bi]] < SZ[v]) 17 | bi = i; 18 | } 19 | while (bi > 0) swap(adj[u][bi-1], adj[u][bi]), bi--; // put favorite child in first position 20 | return SZ[u]; 21 | } 22 | void dfsDiscovery(int u, int top, int &idx, int p = -1) { 23 | PERM[idx] = u; ST[u] = idx++; TOP[u] = top; 24 | for (int v : adj[u]) 25 | if (v != p) 26 | dfsDiscovery(v, (v == adj[u][0]) ? top : v, idx, u); 27 | EN[u] = idx - 1; 28 | } 29 | void build() { 30 | for (int i = 0, idx = 0; i < N; ++i) 31 | if (!SZ[i]) 32 | dfsSZ(i), dfsDiscovery(i, i, idx); 33 | } 34 | int lca(int u, int v) { 35 | while (u != -1 && v != -1) { 36 | if (TOP[u] == TOP[v]) return LVL[u] <= LVL[v] ? u : v; 37 | else if (LVL[TOP[u]] > LVL[TOP[v]]) u = P[TOP[u]]; 38 | else v = P[TOP[v]]; 39 | } 40 | return -1; 41 | } 42 | // note: need to reverse in the second leg if legs are not commutative 43 | vector> lift(int u, int p, bool includeP = true) { 44 | vector> o; 45 | while (true) { 46 | if (TOP[u] == TOP[p]) { 47 | if (ST[p] + (includeP ? 0 : 1) <= ST[u]) 48 | o.emplace_back(ST[p] + (includeP ? 0 : 1), ST[u]); 49 | break; 50 | } else o.emplace_back(ST[TOP[u]], ST[u]); 51 | u = P[TOP[u]]; 52 | } 53 | return o; 54 | }; 55 | }; 56 | -------------------------------------------------------------------------------- /Codes/Trees/HeavyLightDecomposition.cpp: -------------------------------------------------------------------------------- 1 | typedef vector VI; 2 | typedef vector VVI; 3 | struct HLD 4 | { 5 | typedef vector VI; 6 | typedef vector VVI; 7 | VI P , LVL , SZ , PC; 8 | VVI adj; 9 | VVI groups; 10 | VI groupId; 11 | VI groupPos; 12 | int N; 13 | HLD(VVI adj) { 14 | N = adj.size(); 15 | P = PC = VI(N , -1); 16 | LVL = SZ = groupId = groupPos = VI(N , 0); 17 | this->adj = adj; 18 | for(int i = 0; i < N; ++i) 19 | { 20 | if(SZ[i] == 0) 21 | { 22 | initDfs(i); 23 | groups.push_back(VI()); 24 | for(int j = i; j != -1; j = PC[j]) 25 | groups.back().push_back(j) , 26 | groupId[j] = groups.size() - 1 , 27 | groupPos[j] = groups.back().size()-1; 28 | } 29 | } 30 | } 31 | void initDfs(int u,int level = 0) 32 | { 33 | LVL[u] = level; 34 | SZ[u] = 1; 35 | for(int i = 0; i < adj[u].size(); ++i) 36 | { 37 | int v = adj[u][i]; 38 | if(SZ[v])continue; 39 | P[v] = u; 40 | initDfs(v,level + 1); 41 | SZ[u] += SZ[v]; 42 | } 43 | for(int i = 0; i < adj[u].size(); ++i) 44 | { 45 | int v = adj[u][i]; 46 | if(v == P[u])continue; 47 | if(2*SZ[v] > SZ[u]-1){ 48 | PC[u] = v; 49 | } 50 | else 51 | { 52 | groups.push_back(VI()); 53 | for(int j = v; j != -1; j = PC[j]) 54 | groups.back().push_back(j) , 55 | groupId[j] = groups.size() - 1 , 56 | groupPos[j] = groups.back().size()-1; 57 | } 58 | } 59 | } 60 | int LCA(int u,int v) 61 | { 62 | while(u != v && u != -1 && v != -1) 63 | { 64 | if(LVL[v] < LVL[u])swap(u,v); 65 | if(groupId[u] == groupId[v])return u; 66 | bool vGoesUp = LVL[groups[groupId[u]][0]] < LVL[groups[groupId[v]][0]]; 67 | (vGoesUp ? v : u) = P[ groups[groupId[(vGoesUp ? v : u)]][0] ]; 68 | } 69 | return u == v ? v : -1; 70 | } 71 | }; -------------------------------------------------------------------------------- /Codes/Trees/ImplicitLazyPersistentSegmentTree.cpp: -------------------------------------------------------------------------------- 1 | struct Node { 2 | Node *l, *r; 3 | bool hasChild, lazy; 4 | int b,e; 5 | int sum, carry; 6 | Node(int b, int e):l(NULL),r(NULL),hasChild(false),lazy(false),b(b),e(e){ 7 | sum = carry = 0; 8 | } 9 | Node* clone(){ 10 | Node *n = new Node(*this); 11 | n->hasChild = false; 12 | return n; 13 | } 14 | void push(){ 15 | if(!hasChild){ 16 | l = l ? l->clone() : new Node(b, (b+e)/2); 17 | r = r ? r->clone() : new Node((b+e)/2+1, e); 18 | hasChild = true; 19 | } 20 | if(lazy){ 21 | l->update(carry); r->update(carry); 22 | lazy = carry = 0; 23 | } 24 | } 25 | Node* update(int val){ 26 | lazy = 1; 27 | carry += val; 28 | sum += val * (e - b + 1); 29 | return this; 30 | } 31 | void update(){ 32 | sum = (l?l->sum:0) + (r?r->sum:0); 33 | } 34 | Node operator+(const Node &n)const{ 35 | Node r(b, n.e); 36 | r.sum = sum + n.sum; 37 | return r; 38 | } 39 | }; 40 | 41 | Node* create(int N){ 42 | return new Node(0, N-1); 43 | } 44 | Node* update(Node *v, int i, int j, int val){ 45 | if(i <= v->b && v->e <= j){ 46 | return v->clone()->update(val); 47 | }else{ 48 | int m = (v->b+v->e)/2; 49 | v->push(); 50 | Node* n = v->clone(); 51 | if(m >= i) n->l = update(v->l, i, j, val); 52 | if(m < j) n->r = update(v->r, i, j, val); 53 | n->update(); 54 | return n; 55 | } 56 | } 57 | Node query(Node *v, int i, int j){ 58 | if(i <= v->b && v->e <= j){ 59 | return *v; 60 | }else{ 61 | int m = (v->b+v->e)/2; 62 | v->push(); 63 | if(m >= j) return query(v->l, i, j); 64 | if(m < i) return query(v->r, i, j); 65 | return query(v->l, i, j) + query(v->r, i, j); 66 | } 67 | } -------------------------------------------------------------------------------- /Codes/Trees/ImplicitTree2D.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct ImplicitTree{ 3 | struct Query { 4 | int i, j; 5 | Q q; 6 | }; 7 | struct Update { 8 | int i, j; 9 | U u; 10 | Update operator*(const int v)const{ 11 | Update nu = *this; 12 | nu.u = nu.u * v; 13 | return nu; 14 | } 15 | }; 16 | ImplicitTree *l, *r; 17 | int b, e; 18 | T val; 19 | ImplicitTree(int b = 0, int e = 200000):b(b),e(e){ 20 | l = r = NULL; 21 | val = T(); 22 | } 23 | void update(const Update &u){ 24 | if(u.i <= b && e <= u.j) val.update(u.u * (e-b+1)); 25 | else if(u.j < b || e < u.i)return; 26 | else{ 27 | int m = (b+e)/2; 28 | (l ? l : (l = new ImplicitTree(b, m )))->update(u); 29 | (r ? r : (r = new ImplicitTree(m+1, e)))->update(u); 30 | val.update(u.u * (min(e, u.j) - max(b, u.i) + 1)); 31 | } 32 | } 33 | O query(const Query &q){ 34 | if(q.i <= b && e <= q.j) return val.query(q.q); 35 | else if(q.j < b || e < q.i) O(); 36 | else{ 37 | int m = (b+e)/2; 38 | if(q.j <= m)return l ? l->query(q) : O(); 39 | if(m < q.i)return r ? r->query(q) : O(); 40 | return (l?l->query(q):O()) + (r?r->query(q):O()); 41 | } 42 | } 43 | void print(int lvl = 0){ 44 | if(l)l->print(lvl+1); 45 | cout << string(lvl*3,' ')<< "(" << b << "," << e << ")"; 46 | val.print(lvl); 47 | if(r)r->print(lvl+1); 48 | } 49 | }; 50 | 51 | struct Val { 52 | int val; 53 | void update(int v){ 54 | val += v; 55 | } 56 | int query(int v){ 57 | return val; 58 | } 59 | void print(int lvl){ 60 | cout << val << endl; 61 | } 62 | }; 63 | 64 | 65 | int main() { 66 | 67 | typedef ImplicitTree ITV; 68 | ImplicitTree t; 69 | } -------------------------------------------------------------------------------- /Codes/Trees/LCA.cpp: -------------------------------------------------------------------------------- 1 | Long D[100010]; // this distance is optional 2 | struct BinaryLifting { 3 | VVI adj, T; 4 | VI L; 5 | int N; 6 | BinaryLifting(int N) : N(N), adj(N), T(20, VI(N, -1)), L(N) { } 7 | void addEdge(int u, int v) { 8 | adj[u].push_back(v); 9 | adj[v].push_back(u); 10 | } 11 | void build(int root = 0) { 12 | dfs(root); 13 | for (int i = 1; i < 20; ++i) 14 | for (int j = 0; j < N; ++j) 15 | if (T[i-1][j] != -1) 16 | T[i][j] = T[i-1][ T[i-1][j] ]; 17 | } 18 | void dfs(int u, int p = -1, int lvl = 0, Long v = 0) { 19 | T[0][u] = p; L[u] = lvl; 20 | D[u] += v; // add distance from root to have sum([v, root]) 21 | for (int v : adj[u]) if (v != p) dfs(v, u, lvl+1, D[u]); 22 | } 23 | int lca(int u, int v) { 24 | if (L[u] < L[v]) swap(u, v); 25 | for (int i = 19; i >= 0; --i) 26 | if (L[u] - (1<= L[v]) 27 | u = T[i][u]; 28 | if (u == v) return u; 29 | for (int i = 19; i >= 0; --i) 30 | if (T[i][u] != T[i][v]) 31 | u = T[i][u], v = T[i][v]; 32 | return T[0][u]; 33 | } 34 | Long cost(int u, int p) { // from [u, p) 35 | return D[u] - (p == -1 ? 0 : D[p]); 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /Codes/Trees/LinkCutTreeLab.cpp: -------------------------------------------------------------------------------- 1 | struct LinkCutTree 2 | { 3 | struct Node 4 | { 5 | Node *p,*r,*l; 6 | int sz,gid,id; 7 | int edgeCost , upCost; 8 | Node(){ 9 | static int IDX = 0; 10 | p = r = l = NULL; 11 | sz = 1; gid = IDX++; id=0; edgeCost = 0 , upCost = 0; 12 | } 13 | bool isLocalRoot(){ 14 | return p == NULL || (p->r != this && p->l != this); 15 | } 16 | void pushDown(){ 17 | if(r)r->upCost = upCost + edgeCost; 18 | } 19 | void update(){ 20 | 21 | } 22 | int getCost(){ return upCost + edgeCost; } 23 | }; 24 | vector V; int N; 25 | LinkCutTree(int N) : N(N){ 26 | V = vector(N); 27 | for (int i = 0; i < N; ++i) 28 | V[i].id = i; 29 | } 30 | void moveUp(Node *v){ 31 | if(!v->p)return; 32 | Node *p = v->p; 33 | p->pushDown(); v->pushDown(); 34 | Node *g = p->p; 35 | p->p = v; 36 | v->p = g; 37 | if(p->l == v){ p->l = v->r; v->r = p; if(p->l)p->l->p = p; } 38 | else { p->r = v->l; v->l = p; if(p->r)p->r->p = p; } 39 | if(g && (g->l == p || g->r == p))(g->l == p ? g->l : g->r) = v; 40 | p->update();v->update(); 41 | } 42 | void splay(Node *v){ 43 | while(!v->isLocalRoot()) 44 | moveUp(v); 45 | } 46 | void expose(int v){ _expose(&V[v]); } 47 | void _expose(Node *v){ 48 | for(Node *x = v, *y = NULL; x ; x = x->p){ 49 | splay(x); 50 | x->r = y; 51 | x->update(); 52 | y = x; 53 | } 54 | splay(v); 55 | } 56 | void link(int u,int v,int w){ if(findRoot(u) != findRoot(v))_link(&V[u],&V[v],w); } 57 | void _link(Node *u,Node *v, int w){ 58 | _expose(v); 59 | if (!v->l) { 60 | v->p = u; 61 | v->edgeCost = w; 62 | v->update(); 63 | } 64 | } 65 | void cut(int v){ _cut(&V[v]); } 66 | void _cut(Node *v) { 67 | _expose(v); 68 | if (v->l) { 69 | v->l->p = NULL; 70 | v->l = NULL; 71 | v->upCost = 0; 72 | v->edgeCost = 0; 73 | v->update(); 74 | } 75 | } 76 | int findRoot(int v){ return _findRoot(&V[v])->id; } 77 | int findRootCost(int v) { return _findRoot(&V[v])->getCost(); } 78 | Node* _findRoot(Node* v) { 79 | _expose(v); 80 | while (v->l) 81 | v = v->l; 82 | splay(v); 83 | return v; 84 | } 85 | void print(){ 86 | for(int i = 0; i < N; ++i) 87 | if(V[i].isLocalRoot()){ 88 | print(&V[i]); 89 | cout << "-----------------------" << endl; 90 | } 91 | } 92 | void print(Node *v, int LVL = 0){ 93 | if(v->r)print(v->r,LVL+1); 94 | cout << string(LVL,'\t') << v->id << "|" << (v->p ? v->p->id : -1) << endl; 95 | if(v->l)print(v->l,LVL+1); 96 | } 97 | }; 98 | struct BruteForceTree 99 | { 100 | vector P; 101 | vector C; 102 | int N; 103 | BruteForceTree(int N) : N(N) { 104 | P = vector(N , -1); 105 | C = vector(N , 0); 106 | } 107 | void link(int u,int v, int w){ 108 | if(P[v] != -1 || findRoot(u) == findRoot(v))return; 109 | P[v] = u; 110 | C[v] = w; 111 | } 112 | void cut(int v){ 113 | P[v] = -1; 114 | } 115 | int findRoot(int v){ 116 | while(P[v] != -1)v = P[v]; 117 | return v; 118 | } 119 | int findCostRoot(int v){ 120 | int c = 0; 121 | while(P[v] != -1)c += C[v], v = P[v]; 122 | return c; 123 | } 124 | void print(){ 125 | for (int i = 0; i < N; ++i) { 126 | cout << P[i] << " "; 127 | } 128 | cout << endl; 129 | } 130 | }; 131 | int main() 132 | { 133 | LinkCutTree LT(10000); 134 | BruteForceTree BF(10000); 135 | for(int i = 0; i < 200000; ++i) 136 | { 137 | int c = rand() % 4; 138 | if(c == 0){ 139 | int u = rand() % 10 , v = rand() % 10 , c = rand() % 10 + 1; 140 | LT.link(u,v,c); 141 | BF.link(u,v,c); 142 | // cout << "LINK " << u << " " << v << endl; 143 | } 144 | else if(c == 1){ 145 | int u = rand() % 10; 146 | LT.cut(u); 147 | BF.cut(u); 148 | // cout << "CUT " << u << endl; 149 | } 150 | else if(c == 2){ 151 | int u = rand() % 10; 152 | int a1 = LT.findRoot(u); 153 | int a2 = BF.findRoot(u); 154 | if(a1 != a2) 155 | { 156 | BF.print(); 157 | LT.print(); 158 | cout << "Answers: " << u << " a1=" << a1 << " " << "a2=" << a2 << endl; 159 | cout << endl << endl << endl; 160 | } 161 | } 162 | else 163 | { 164 | int u = rand() % 10; 165 | int a1 = LT.findRoot(u); 166 | int a2 = BF.findRoot(u); 167 | if(a1 != a2) 168 | { 169 | BF.print(); 170 | LT.print(); 171 | cout << "Answers: " << u << " a1=" << a1 << " " << "a2=" << a2 << endl; 172 | cout << endl << endl << endl; 173 | } 174 | } 175 | } 176 | cout << "OK" << endl; 177 | } -------------------------------------------------------------------------------- /Codes/Trees/Persistent/PersistentArray.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct PersistentArray { 3 | static VI L, R; 4 | static vector V; 5 | int root, b, e; 6 | static int createLeafNode(const T &v) { 7 | V.push_back(v); 8 | return V.size() - 1; 9 | } 10 | static int createInternalNode(int l, int r) { 11 | L.push_back(l); 12 | R.push_back(r); 13 | return L.size() - 1; 14 | } 15 | PersistentArray(int root, int b, int e) : root(root), b(b), e(e) { } 16 | PersistentArray(const vector &vals, int b = 0, int e = -1) : b(b), e(e) { 17 | if (e == -1) e = vals.size() - 1; 18 | this->e = e; 19 | if (b == e) { 20 | root = createLeafNode(vals[0]); 21 | } else { 22 | int m = (b + e) / 2; 23 | root = createInternalNode(PersistentArray(vals, b, m).root, PersistentArray(vals, m+1, e).root); 24 | } 25 | } 26 | T get(int i) const { 27 | return get(root, b, e, i); 28 | } 29 | T get (int v, int b, int e, int i) const { 30 | if (b == e) return V[v]; 31 | int m = (b+e)/2; 32 | return i <= m ? get(L[v], b, m, i) : get(R[v], m+1, e, i); 33 | } 34 | PersistentArray set(int i, const T &nv) { 35 | return set(root, b, e, i, nv); 36 | } 37 | PersistentArray set (int v, int b, int e, int i, const T &nv) { 38 | if (b == e) return PersistentArray(createLeafNode(nv), b, e); 39 | int m = (b+e)/2; 40 | int l = i <= m ? set(L[v], b, m, i, nv).root : L[v]; 41 | int r = i > m ? set(R[v], m+1, e, i, nv).root : R[v]; 42 | return PersistentArray(createInternalNode(l, r), b, e); 43 | } 44 | int size() const { 45 | return e - b + 1; 46 | } 47 | }; 48 | template vector PersistentArray::V = vector(); 49 | template vector PersistentArray::L = vector(); 50 | template vector PersistentArray::R = vector(); 51 | -------------------------------------------------------------------------------- /Codes/Trees/Persistent/PersistentFenwick.cpp: -------------------------------------------------------------------------------- 1 | struct PersistentFenwick { 2 | struct ValVer{ 3 | int val, ver; 4 | ValVer(int v = 0, int ver = 0):val(v),ver(ver){} 5 | ValVer operator+(const ValVer &o)const{ 6 | return ValVer(val + o.val , max(ver, o.ver)); 7 | } 8 | struct IsBefore{ 9 | bool operator()(const ValVer &v, const int &ver){ 10 | return v.ver < ver; 11 | } 12 | }; 13 | }; 14 | int cv; 15 | vector> V; 16 | PersistentFenwick(int N) : cv(0), V(N+2, vector(1, {0, 0})){} 17 | void add(int x, int v){ 18 | cv++; 19 | for(int i = x+1; i < V.size(); i += i & -i){ 20 | V[i].push_back(V[i].back() + ValVer(v, cv)); 21 | } 22 | } 23 | int get(int x, int ver){ 24 | int r = 0; 25 | for(int i = x+1; i > 0; i -= i & -i){ 26 | r += getX(i, ver); 27 | } 28 | return r; 29 | } 30 | int getX(int x, int ver){ 31 | int p = lower_bound(V[x].begin(), V[x].end(), ver+1, ValVer::IsBefore()) - V[x].begin(); 32 | p--; 33 | return V[x][p].val; 34 | } 35 | 36 | void print(){ 37 | for(vector V : V){ 38 | for(ValVer v : V){ 39 | cout << v.val << ":" << v.ver << " "; 40 | } 41 | cout << endl; 42 | } 43 | } 44 | }; -------------------------------------------------------------------------------- /Codes/Trees/Persistent/PersistentTrie.cpp: -------------------------------------------------------------------------------- 1 | struct PTrie { 2 | static const int DEPTH = 2; 3 | static const int BITS = 2; 4 | static const int MAXN = 1<<(DEPTH * BITS); // exclusive 5 | static const int MASK = (1<sum += x; 17 | for(int i = 0; i < DEPTH; ++i){ 18 | int p = (v >> ((DEPTH-1-i) * BITS)) & MASK; 19 | if(r->child[p] == NULL){ 20 | r->child[p] = new PTrie(); 21 | }else{ 22 | r->child[p] = r->child[p]->clone(); 23 | } 24 | r = r->child[p]; 25 | r->sum += x; 26 | } 27 | return ret; 28 | } 29 | void print(int lvl = 0){ 30 | for(int i = 0; i < CHILDS/2; ++i){ 31 | if(child[i])child[i]->print(lvl+1); 32 | } 33 | cout << string(lvl, '\t') << sum << endl; 34 | for(int i = CHILDS/2; i < CHILDS; ++i){ 35 | if(child[i])child[i]->print(lvl+1); 36 | } 37 | } 38 | void sorted(int p = 0, int lvl = 0){ 39 | if(lvl == DEPTH)cout << p << " " << sum << endl; 40 | for (int i = 0; i < CHILDS; ++i) { 41 | if(child[i]){ 42 | // cout << string(lvl+1, '-') << i << endl; 43 | child[i]->sorted((p << BITS) | i, lvl+1); 44 | } 45 | } 46 | } 47 | int countLess(int v){ 48 | PTrie *r = *this; 49 | int cnt = 0; 50 | for(int i = 0; i < DEPTH; ++i){ 51 | int p = (v >> ((DEPTH-1-i) * BITS)) & MASK; 52 | for(int j = 0; j < p; ++j) 53 | if(r->child[j]) 54 | cnt += r->child[j]->sum; 55 | if(r->child[p] == NULL)break; 56 | r = r->child[p]; 57 | } 58 | return cnt; 59 | } 60 | }; -------------------------------------------------------------------------------- /Codes/Trees/PersistentSegmentTree.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct SegmentTree { 3 | struct Node { 4 | Node *l, *r; 5 | int b,e; 6 | Data data; 7 | Node(int i, int v):l(NULL),r(NULL),b(i),e(i),data(v){} 8 | Node(Node *l, Node *r):l(l),r(r),b(l->b),e(r->e){ 9 | data = l->data + r->data; 10 | } 11 | Node *copy(){ 12 | return new Node(*this); 13 | } 14 | void print(int L=0){ 15 | if(l)l->print(L+1); 16 | cout << string(L,'\t'); data.print(); cout << endl; 17 | if(r)r->print(L+1); 18 | } 19 | }; 20 | struct Iterator { 21 | Node *v; 22 | Iterator(Node *v):v(v){} 23 | Data& operator*(){ 24 | return v->data; 25 | } 26 | Data* operator->(){ 27 | return &v->data; 28 | } 29 | int size(){ 30 | return v->e - v->b + 1; 31 | } 32 | Iterator& left(){ 33 | if(v->l) v = v->l; 34 | return *this; 35 | } 36 | Iterator& right(){ 37 | if(v->r) v = v->r; 38 | return *this; 39 | } 40 | }; 41 | vector V; 42 | int N; 43 | SegmentTree(int N):N(N){} 44 | template 45 | Node* build(Iterator &T){ 46 | V.push_back(build(T,0,N-1)); 47 | } 48 | template 49 | Node* build(Iterator &T, int b, int e){ 50 | if(b == e)return new Node(b, T[b]); 51 | int m = (b+e)>>1; 52 | return new Node(build(T,b,m) , build(T,m+1,e)); 53 | } 54 | Node* update(int x, int v, int ver = -1){ 55 | Node *nv = update(ver==-1 ? V.back() : V[ver], x, v); 56 | V.push_back(nv); 57 | return nv; 58 | } 59 | Data query(int i, int j, int ver = -1){ 60 | return query(ver==-1 ? V.back() : V[ver], i, j); 61 | } 62 | Node* root(int ver = -1){ 63 | return ver == -1 ? V.back() : V[ver]; 64 | } 65 | Node* update(Node *n, int x, int v){ 66 | int b = n->b, e = n->e; 67 | if(b == e){ 68 | Node* c = n->copy(); 69 | c->data.update(v); 70 | return c; 71 | }else{ 72 | int m = (b+e)>>1; 73 | if(x <= m)return new Node(update(n->l,x,v),n->r); 74 | else return new Node(n->l,update(n->r,x,v)); 75 | } 76 | } 77 | Data query(Node *n, int i, int j){ 78 | int b = n->b, e = n->e; 79 | if(i <= b && e <= j)return n->data; 80 | int m = (b+e)>>1; 81 | if(j <= m)return query(n->l, i, j); 82 | if(m < i)return query(n->r, i, j); 83 | return query(n->l, i, j) + query(n->r, i, j); 84 | } 85 | int size(){ 86 | return V.size(); 87 | } 88 | void print(int ver = -1){ 89 | if(ver == -1){ 90 | V.back()->print(); 91 | }else{ 92 | V[ver]->print(); 93 | } 94 | } 95 | }; 96 | 97 | 98 | 99 | struct Data{ 100 | int tot, left; 101 | Data(int v=0):tot(tot),left(0){} 102 | Data operator+(const Data &D)const{ 103 | Data d; 104 | d.tot = tot + D.tot; 105 | d.left= tot; 106 | return d; 107 | } 108 | void print(){ 109 | cout << left; 110 | } 111 | void update(int v){ 112 | tot += v; 113 | } 114 | }; -------------------------------------------------------------------------------- /Codes/Trees/RangeTrees.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct SegmentTree { 3 | struct Node { 4 | int sz = 1; 5 | bool hasCarry = 0; 6 | U carry = U(); T val = T(); 7 | Node(){ } 8 | void join(const Node &l, const Node &r){ 9 | sz = l.sz + r.sz; 10 | val = l.val + r.val; 11 | carry = U(); 12 | } 13 | void update(U u){ 14 | carry += u; 15 | val += u * sz; 16 | hasCarry = 1; 17 | } 18 | void pushDown(Node &l, Node &r){ 19 | if(!hasCarry)return; 20 | l.update(carry); 21 | r.update(carry); 22 | // r.update(carry << l.sz); // shift the update, for sequences query 23 | carry = U(); 24 | hasCarry = 0; 25 | } 26 | }; 27 | vector V; 28 | int N; 29 | SegmentTree(int N) : V(4*N), N(N){ } 30 | template 31 | void create(const vector &VEC, int n = 1, int b = 0, int e = -1) { 32 | if(e == -1) e = N-1; 33 | if (b == e) { 34 | V[n].val = T(VEC[b]); 35 | } else { 36 | create(VEC, 2 * n, b, (e + b) / 2); 37 | create(VEC, 2 * n + 1, (e + b) / 2 + 1, e); 38 | V[n].join(V[2*n], V[2*n+1]); 39 | } 40 | } 41 | T query(int i, int j, int n = 1, int b = 0, int e = -1) { 42 | if(e == -1) e = N-1; 43 | if (i <= b && e <= j) 44 | return V[n].val; 45 | else { 46 | V[n].pushDown(V[2*n], V[2*n+1]); 47 | int mid = (b + e) / 2; 48 | if (i > mid) return query(i, j, 2 * n + 1, mid + 1, e); 49 | if (j <= mid) return query(i, j, 2 * n, b, mid); 50 | return query(i, j, 2 * n, b, mid) 51 | + query(i, j, 2 * n + 1, mid + 1, e); 52 | } 53 | } 54 | void update(int i, int j, U v, int n = 1, int b = 0, int e = -1) { 55 | if(e == -1) e = N-1; 56 | if (i <= b && e <= j) { 57 | V[n].update(v); 58 | } else if (i > e || j < b) 59 | return; 60 | else { 61 | V[n].pushDown(V[2*n], V[2*n+1]); 62 | int mid = (b + e) / 2; 63 | update(i, j, v, 2 * n, b, mid); 64 | update(i, j, v, 2 * n + 1, mid + 1, e); 65 | V[n].join(V[2*n], V[2*n+1]); 66 | } 67 | } 68 | }; 69 | struct Add { 70 | int v; 71 | Add(int v=0):v(v){} // empty update 72 | Add& operator*(const int sz){ // apply update to range 73 | return *this; 74 | } 75 | void operator+=(const Add &a){ // acumulate updates 76 | v += a.v; 77 | } 78 | }; 79 | struct Max { 80 | int v = 0; 81 | Max(int v=0):v(v){} // default 82 | Max operator+(const Max &a)const{ // join 83 | return (Max){ max(v, a.v) }; 84 | } 85 | void operator+=(const Add &a){ // apply update 86 | v += a.v; 87 | } 88 | }; -------------------------------------------------------------------------------- /Codes/Trees/SegmentTree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | struct SegmentNode{ 6 | int sz = 1; 7 | bool HasCarry = 0; 8 | void join(const SegmentNode &l, const SegmentNode &r){ 9 | sz = l.sz + r.sz; 10 | } 11 | void update(){ HasCarry = 1; } 12 | void clear(){ HasCarry = 0; } 13 | }; 14 | template 15 | struct SegmentTree 16 | { 17 | vector V; 18 | int N; 19 | SegmentTree(int N) : V(4*N), N(N) {} 20 | void create(const vector &VEC,int n = 1,int b = 0,int e = -1) 21 | { 22 | if (e == -1) e = N - 1; 23 | if (b == e) V[n] = T(VEC[b]); 24 | else { 25 | create(VEC,2*n,b,(e+b)/2); 26 | create(VEC,2*n+1,(e+b)/2+1,e); 27 | V[n] = V[2*n] + V[2*n+1]; 28 | } 29 | } 30 | T query(int i,int j, int n = 1,int b = 0,int e = -1) 31 | { 32 | if (e == -1)e = N - 1; 33 | if (i <= b && e <= j) return V[n]; 34 | else { 35 | if(V[n].HasCarry) { 36 | V[2*n ].update(V[n].carry); 37 | V[2*n+1].update(V[n].carry); 38 | V[n].clear(); 39 | } 40 | int mid = (b+e)/2; 41 | if(i > mid)return query(i,j,2*n+1,mid+1,e); 42 | if(j <=mid)return query(i,j,2*n,b,mid); 43 | return query(i,j,2*n,b,mid) + query(i,j,2*n+1,mid+1,e); 44 | } 45 | } 46 | void update(int i,int j,int v,int n = 1,int b=0,int e=-1) 47 | { 48 | if (e == -1) e = N - 1; 49 | if (i <= b && e <= j) V[n].update(v); 50 | else if (i > e || j < b) return; 51 | else { 52 | if(V[n].HasCarry) { 53 | V[2*n ].update(V[n].carry); 54 | V[2*n+1].update(V[n].carry); 55 | V[n].clear(); 56 | } 57 | int mid = (b+e)/2; 58 | update(i,j,v,2*n,b,mid); 59 | update(i,j,v,2*n+1,mid+1,e); 60 | V[n] = V[2*n] + V[2*n+1]; 61 | } 62 | } 63 | int findLastIndex( bool (*isOk)(T) ){ // almost never needed 64 | int n = 1; 65 | T acum; 66 | acum.sz = 0; 67 | while(V[n].sz > 1){ 68 | int l = 2*n , r = 2*n+1; 69 | T newAcum = (acum.sz == 0 ? V[r] : (V[r] + acum)); 70 | if(isOk(newAcum)){ 71 | n = r; 72 | }else{ 73 | acum = newAcum; 74 | n = l; 75 | } 76 | } 77 | return N - acum.sz - 1; 78 | } 79 | }; 80 | 81 | #define NONE 0 82 | #define OPEN 1 83 | #define CLOSE 2 84 | struct OpenBrackets : SegmentNode 85 | { 86 | struct Init { // type to send to the create 87 | int val; 88 | Init(int val=NONE):val(val){ } 89 | }; 90 | int open, close; 91 | int carry; 92 | OpenBrackets() : SegmentNode(){ // default initialization if create not called 93 | open = close = carry = 0; 94 | } 95 | OpenBrackets(Init n) : SegmentNode() { // initialization with create called 96 | open = (n.val == OPEN); 97 | close = (n.val == CLOSE); 98 | carry = 0; 99 | } 100 | OpenBrackets operator+(const OpenBrackets &N)const { // join 101 | OpenBrackets ret; ret.join( *this , N ); 102 | 103 | int cancel = min(open, N.close); 104 | ret.open = open + N.open - cancel; 105 | ret.close= close + N.close - cancel; 106 | 107 | return ret; 108 | } 109 | void update(int val) { // update node 110 | SegmentNode::update(); 111 | if (val == OPEN) { 112 | close = 0; 113 | open = sz; 114 | } else if(val == CLOSE) { 115 | close = sz; 116 | open = 0; 117 | } else { 118 | open = 0; 119 | close = 0; 120 | } 121 | } 122 | }; 123 | 124 | int main() { 125 | int N = 6; 126 | SegmentTree ST(N); 127 | ST.create(vector(N, OPEN)); 128 | cout << ST.query(0, N-1).open << endl; 129 | } 130 | -------------------------------------------------------------------------------- /Codes/Trees/SegmentTrees/DynamicWavelet.cpp: -------------------------------------------------------------------------------- 1 | // Unfinished 2 | struct WaveletTree { 3 | int lo,hi; 4 | vector A; 5 | VectorTreap T; 6 | WaveletTree *l, *r; 7 | #define get(i) (i<0?0:A[i]) 8 | WaveletTree(vector V) 9 | :WaveletTree(V.begin(), V.end(), 10 | *min_element(V.begin(), V.end()), 11 | *max_element(V.begin(), V.end())){} 12 | template 13 | WaveletTree(IT b, IT e, int lo, int hi, int lvl = 0):lo(lo),hi(hi),l(NULL),r(NULL) { 14 | int mi = (lo+hi)>>1; 15 | function isLeft = [mi](int x) { return x <= mi; }; 16 | A.reserve(e - b); 17 | for(IT i = b; i != e; ++i) { 18 | T.insertAt(T.size(), isLeft(*i)); 19 | A.push_back(isLeft(*i) + (i==b?0:A.back())); 20 | } 21 | IT ps = stable_partition(b, e, isLeft); 22 | if(lo == hi || b == e)return; 23 | l = new WaveletTree(b, ps, lo, mi, lvl+1); 24 | r = new WaveletTree(ps, e, mi+1, hi, lvl+1); 25 | } 26 | void getWithMore(int i, int j, int w, const function &emit){ 27 | if(j-i+1 < w)return; 28 | if(lo == hi) { emit(lo); return; } 29 | int ai = get(i-1), aj = A[j]; 30 | l->getWithMore( ai, aj-1, w, emit); 31 | r->getWithMore(i-ai, j-aj, w, emit); 32 | } 33 | int getFreq(int i, int j, int a, int b) { // count elements from a to b 34 | if(j < i)return 0; 35 | if(a <= lo && hi <= b) return j-i+1; 36 | if(b < lo || hi < a) return 0; 37 | int ai = get(i-1), aj = A[j]; 38 | return l->getFreq( ai, aj-1, a, b) + 39 | r->getFreq(i-ai, j-aj, a, b); 40 | } 41 | int getKth(int i, int j, int k) { // 0-based 42 | if(lo == hi) return lo; 43 | int ai = get(i-1), aj = A[j]; 44 | assert(ai == T.range(0, i-1)); 45 | assert(aj == T.range(0, j)); 46 | int cntL = aj-ai; 47 | if(cntL > k) return l->getKth( ai, aj-1, k); 48 | else return r->getKth(i-ai, j-aj, k-cntL); 49 | } 50 | void swap(int i){ // i and i+1 51 | if(lo == hi)return; 52 | int ai = get(i-1); 53 | int f = A[i] - ai, s = A[i+1] - A[i]; 54 | if(f != s) A[i] += s-f; 55 | else if(f == 1) l->swap( ai); 56 | else r->swap(i-ai); 57 | } 58 | /// countDistinct(i, j) 59 | /// buildWavelet using array of next appearance: 60 | /// NEXT[i] = next position of element ARR[i] == ARR[i] 61 | /// then build WaveletTree(NEXT) and do "t.getFreq(i, j, j+1, t.hi)" 62 | void print(int lvl = 0){ 63 | if(l)l->print(lvl+1); 64 | cout << string(lvl, '\t'); 65 | for (int i = 0; i < A.size(); ++i) 66 | cout << get(i) - get(i-1); 67 | cout << endl; 68 | if(r)r->print(lvl+1); 69 | } 70 | #undef get 71 | }; -------------------------------------------------------------------------------- /Codes/Trees/SegmentTrees/FastPersitenceSegmentTree.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct Node { 3 | int l, r; 4 | T val; 5 | Node() : l(-1), r(-1), val() {} 6 | }; 7 | 8 | template 9 | struct PersistentSegmentTree { 10 | vector> nodes; 11 | int B, E; 12 | PersistentSegmentTree(int B, int E) : B(B), E(E) {} 13 | int setMaxMemory(int maxMemory) { 14 | nodes.reserve(max((int)(maxMemory / sizeof(Node)), 20)); 15 | } 16 | int newNode() { 17 | int id = nodes.size(); 18 | nodes.push_back(Node()); 19 | return id; 20 | } 21 | int create() { return create(B, E); } 22 | int create(int b, int e) { 23 | int id = newNode(); 24 | if (b == e) return id; 25 | int m = (b+e)/2; 26 | int nl = create(b, m); nodes[id].l = nl; // we assign to a variable first since the vector mutates and it may be harmful. 27 | int nr = create(m+1, e); nodes[id].r = nr; 28 | return id; 29 | } 30 | int update(int oid, int i, int j, const U &u) { return update(oid, i, j, u, B, E); } 31 | int update(int oid, int i, int j, const U &u, int b, int e) { 32 | int id = newNode(); 33 | nodes[id] = nodes[oid]; 34 | if (b == e) { 35 | u(nodes[id].val); 36 | } else { 37 | int m = (b + e) / 2, nl = nodes[id].l, nr = nodes[id].r; 38 | if (j <= m) nl = update(nodes[oid].l, i, j, u, b, m); 39 | if (m < i) nr = update(nodes[oid].r, i, j, u, m + 1, e); 40 | nodes[id].l = nl; nodes[id].r = nr; 41 | nodes[id].val = nodes[nodes[id].l].val + nodes[nodes[id].r].val; 42 | } 43 | return id; 44 | } 45 | T query(int id, int i, int j) { return query(id, i, j, B, E); } 46 | T query(int id, int i, int j, int b, int e) { 47 | if (i <= b && e <= j) { 48 | return nodes[id].val; 49 | } else { 50 | int m = (b + e) / 2; 51 | if (j <= m) return query(nodes[id].l, i, j, b, m); 52 | if (m < i) return query(nodes[id].r, i, j, m + 1, e); 53 | return query(nodes[id].l, i, j, b, m) + query(nodes[id].r, i, j, m+1, e); 54 | } 55 | } 56 | }; 57 | -------------------------------------------------------------------------------- /Codes/Trees/SegmentTrees/ISegmentTree.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct ISegmentTree { 3 | struct Node { 4 | bool hasCarry = 0; 5 | U carry = U(); T val = T(); 6 | Node(){ } 7 | void join(const Node &l, const Node &r){ 8 | if(hasCarry)return; 9 | val = l.val + r.val; 10 | } 11 | void update(const U &u){ 12 | carry += u; 13 | val += u; 14 | hasCarry = 1; 15 | } 16 | void pushDown(Node &l, Node &r){ 17 | if(!hasCarry)return; 18 | l.update(carry); 19 | r.update(carry); 20 | carry = U(); 21 | hasCarry = 0; 22 | } 23 | }; 24 | int N, H; 25 | vector V; 26 | ISegmentTree(int N): N(N), H(sizeof(int) * 8 - __builtin_clz(N)), V(2*N){ } 27 | template 28 | void create(const vector &VEC) { 29 | for (int i = 0; i < N; ++i) 30 | V[i+N].val = T(VEC[i]); 31 | for (int i = N - 1; i > 0; --i) 32 | V[i].join(V[i<<1], V[i<<1|1]); 33 | } 34 | void push(int p) { 35 | for (int s = H; s > 0; --s) { 36 | int i = p >> s; 37 | V[i].pushDown(V[i << 1], V[i << 1 | 1]); 38 | } 39 | } 40 | void build(int p) { 41 | while (p > 1) 42 | p >>= 1, V[p].join(V[p << 1], V[p << 1 | 1]); 43 | } 44 | T query(int i, int j) { 45 | i += N, j += N+1; 46 | push(i); push(j-1); 47 | T a,b; 48 | for (int l = i, r = j; l < r; l >>= 1, r >>= 1) { 49 | if (l & 1) a = a + V[l++].val; 50 | if (r & 1) b = V[--r].val + b; 51 | } 52 | return a + b; 53 | } 54 | void update(int i, int j, const U &v) { 55 | i += N, j += N+1; 56 | push(i); push(j-1); 57 | for (int l = i, r = j; l < r; l >>= 1, r >>= 1) { 58 | if (l&1) V[l++].update(v); 59 | if (r&1) V[--r].update(v); 60 | } 61 | build(i); build(j-1); 62 | } 63 | }; -------------------------------------------------------------------------------- /Codes/Trees/SegmentTrees/ISegmentTreeTrim.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct ISegmentTree { 3 | struct Node { 4 | bool hasCarry = 0; 5 | U carry = U(); T val = T(); 6 | int s,e; 7 | Node(){ } 8 | void join(const Node &l, const Node &r){ 9 | if(hasCarry)return; 10 | val = l.val + r.val; 11 | s = l.s; 12 | e = r.e; 13 | } 14 | void update(const U &u){ 15 | carry += u; 16 | u(val); 17 | hasCarry = 1; 18 | } 19 | void pushDown(Node &l, Node &r){ 20 | if(!hasCarry)return; 21 | l.update(carry.trim(0, r.e-r.s+1)); 22 | r.update(carry.trim(l.e-l.s+1, 0)); 23 | carry = U(); 24 | hasCarry = 0; 25 | } 26 | }; 27 | int N, H; 28 | vector V; 29 | ISegmentTree(int N): N(N), H(sizeof(int) * 8 - __builtin_clz(N)), V(2*N){ } 30 | template 31 | void create(const vector &VEC) { 32 | for (int i = 0; i < N; ++i) 33 | V[i+N].val = T(VEC[i]), V[i+N].s = i, V[i+N].e = i; 34 | for (int i = N - 1; i > 0; --i) 35 | V[i].join(V[i<<1], V[i<<1|1]); 36 | } 37 | void push(int p) { 38 | for (int s = H; s > 0; --s) { 39 | int i = p >> s; 40 | V[i].pushDown(V[i << 1], V[i << 1 | 1]); 41 | } 42 | } 43 | void build(int p) { 44 | while (p > 1) 45 | p >>= 1, V[p].join(V[p << 1], V[p << 1 | 1]); 46 | } 47 | T query(int i, int j) { 48 | i += N, j += N+1; 49 | push(i); push(j-1); 50 | T a,b; 51 | for (int l = i, r = j; l < r; l >>= 1, r >>= 1) { 52 | if (l & 1) a = a + V[l++].val; 53 | if (r & 1) b = V[--r].val + b; 54 | } 55 | return a + b; 56 | } 57 | void update(int i, int j, const U &v) { 58 | i += N, j += N+1; 59 | push(i); push(j-1); 60 | for (int l = i, r = j; l < r; l >>= 1, r >>= 1) { 61 | if (l&1) { 62 | int shL = max(V[l].s - i + N, 0); 63 | int shR = max(j-N-1 - V[l].e, 0); 64 | V[l++].update(v.trim(shL, shR)); 65 | } 66 | if (r&1){ 67 | int shL = max(V[r-1].s - i + N, 0); 68 | int shR = max(j-N-1 - V[r-1].e, 0); 69 | V[--r].update(v.trim(shL, shR)); 70 | } 71 | } 72 | build(i); build(j-1); 73 | } 74 | }; 75 | typedef long long Long; 76 | struct String { 77 | int f[26]; 78 | int sz; 79 | String(){ 80 | fill(f, f+26, 0); 81 | sz = 0; 82 | } 83 | String(char c){ 84 | fill(f, f+26, 0); 85 | f[c - 'a']++; 86 | sz = 1; 87 | } 88 | String operator+(const String &a)const{ 89 | String r; 90 | r.sz = sz + a.sz; 91 | for (int i = 0; i < 26; ++i) { 92 | r.f[i] = f[i] + a.f[i]; 93 | } 94 | return r; 95 | } 96 | bool isPal(){ 97 | int o = 0; 98 | for (int i = 0; i < 26; ++i) { 99 | o += f[i] & 1; 100 | } 101 | return o <= 1; 102 | } 103 | char get(){ 104 | return find(f, f+26, 1) - f + 'a'; 105 | } 106 | }; 107 | struct Set { 108 | int v; 109 | Set(){} 110 | Set(int c):v(c){ } 111 | Set trim(int l, int r)const{ 112 | return *this; 113 | } 114 | void operator+=(const Set &s){ 115 | v = s.v; 116 | } 117 | void operator()(const String &a)const{ 118 | fill(a.f, a.f+26, 0); 119 | a.f[v] = a.sz; 120 | } 121 | }; -------------------------------------------------------------------------------- /Codes/Trees/SegmentTrees/PersistentSegmentTree.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct Node { 3 | Node *l, *r; 4 | int b,e; 5 | T sum; 6 | Node(int b, int e):l(NULL),r(NULL),b(b),e(e), sum() { } 7 | Node* clone() { 8 | Node *n = new Node(*this); 9 | return n; 10 | } 11 | Node operator+(const Node &n) const { 12 | Node r(b, n.e); 13 | r.sum = sum + n.sum; 14 | return r; 15 | } 16 | static Node* create(int b, int e) { 17 | Node *r = new Node(b, e); 18 | if (b == e) return r; 19 | r->l = create(b, (b+e)/2); 20 | r->r = create((b+e)/2+1, e); 21 | return r; 22 | } 23 | Node* update(int i, int j, U val) { 24 | Node* n = clone(); 25 | if(i <= b && e <= j){ 26 | n->sum += val; 27 | return n; 28 | }else{ 29 | int m = (b+e)/2; 30 | if(m >= i) n->l = l->update(i, j, val); 31 | if(m < j) n->r = r->update(i, j, val); 32 | n->sum = n->l->sum + n->r->sum; 33 | return n; 34 | } 35 | } 36 | T query(int i, int j) { 37 | if(i <= b && e <= j){ 38 | return sum; 39 | }else{ 40 | int m = (b+e)/2; 41 | if(m >= j) return l->query(i, j); 42 | if(m < i) return r->query(i, j); 43 | return l->query(i, j) + r->query(i, j); 44 | } 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /Codes/Trees/SortedSplayTree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | struct SortedSplayTree { 8 | struct Node { 9 | Node *p, *r, *l; 10 | int sz,gid; 11 | int val; 12 | Node(int v) { 13 | static int IDX = 0; 14 | p = r = l = NULL; 15 | gid = IDX++; 16 | sz = 1; 17 | val = v; 18 | } 19 | bool isRoot() { 20 | return p == NULL; 21 | } 22 | void update() { 23 | sz = 1 + (r?r->sz:0) + (l?l->sz:0); 24 | } 25 | inline int leftSize(){ return l ? l->sz : 0; } 26 | }; 27 | Node* root; 28 | SortedSplayTree(){ root = NULL; } 29 | int size(){ return root == NULL ? 0 : root->sz; } 30 | void moveUp(Node *v) { 31 | if (!v->p) 32 | return; 33 | Node *p = v->p; 34 | Node *g = p->p; 35 | p->p = v; v->p = g; 36 | if (p->l == v) { p->l = v->r; v->r = p; if (p->l) p->l->p = p; } 37 | else { p->r = v->l; v->l = p; if (p->r) p->r->p = p; } 38 | if (g && (g->l == p || g->r == p)) 39 | (g->l == p ? g->l : g->r) = v; 40 | else root = v; 41 | p->update(); 42 | v->update(); 43 | } 44 | void splay(Node *v) { 45 | while (!v->isRoot()) 46 | moveUp(v); 47 | } 48 | Node* operator[](int k){ 49 | Node *v = root; 50 | while(k != v->leftSize()){ 51 | if(k < v->leftSize()){ 52 | v = v->l; 53 | }else{ 54 | k -= v->leftSize() + 1; 55 | v = v->r; 56 | } 57 | } 58 | splay(v); 59 | return v; 60 | } 61 | int countL(int v){ 62 | Node *r = root , *p = NULL; 63 | int cnt = 0; 64 | while( r != NULL ){ 65 | p = r; 66 | if(r->val >= v) r = r->l; 67 | else { 68 | cnt += r->leftSize() + 1; 69 | r = r->r; 70 | } 71 | } 72 | if(p)splay(p); 73 | return cnt; 74 | } 75 | void insert(int v){ 76 | Node* nn = new Node(v); 77 | if(root == NULL){ 78 | root = nn; return; 79 | } 80 | Node *r = root , *p = NULL; 81 | while( r != NULL ){ 82 | p = r; p->sz++; 83 | if(r->val >= v) r = r->l; 84 | else r = r->r; 85 | } 86 | (p->val >= v ? p->l : p->r) = nn; 87 | nn->p = p; 88 | splay(nn); 89 | } 90 | void print(Node* v, int LVL = 0){ 91 | if(v->r)print(v->r,LVL+1); 92 | cout <gid << "|" << v->sz << endl; 93 | if(v->l)print(v->l,LVL+1); 94 | } 95 | void print(){ print(root); } 96 | }; 97 | 98 | int main(){ 99 | SortedSplayTree SST; 100 | SST.insert(20); 101 | SST.insert(10); 102 | SST.insert(20); 103 | cout << SST.countL(10) << endl; 104 | SST.print(); 105 | } -------------------------------------------------------------------------------- /Codes/Trees/SparseTable.cpp: -------------------------------------------------------------------------------- 1 | #define dlog2(n) (31-__builtin_clz(n)) 2 | template 3 | struct SparseTable { 4 | int N, L; 5 | vector> table; 6 | SparseTable(const vector &V): 7 | N(V.size()), L(dlog2(N)+1), table(L, vector(N)){ 8 | table[0] = V; 9 | for(int sz = 1; sz < L; ++sz){ 10 | for (int i = 0; i < N; ++i) { 11 | if(i + (1< N)break; 12 | table[sz][i] = min(table[sz-1][i], table[sz-1][i+(1<<(sz-1))]); 13 | } 14 | } 15 | } 16 | T get(int i, int j){ 17 | int d = dlog2(j-i+1); 18 | return min(table[d][i], table[d][j-(1<rev ^= 1; 20 | if(l)l->rev ^= 1; 21 | rev = 0; 22 | } 23 | } 24 | void update() { 25 | sz = 1 + (r?r->sz:0) + (l?l->sz:0); 26 | } 27 | }; 28 | Node* root; 29 | vector V; 30 | int N; 31 | LinkCutTree(int N) : 32 | N(N) { 33 | V = vector(N); 34 | root = &V[0]; 35 | for (int i = 0; i < N; ++i){ 36 | V[i].id = i; 37 | V[i].sz = N-i; 38 | if(i+1p) 46 | return; 47 | Node *p = v->p; 48 | p->pushDown(); 49 | v->pushDown(); 50 | Node *g = p->p; 51 | p->p = v; 52 | v->p = g; 53 | if (p->l == v) { 54 | p->l = v->r; 55 | v->r = p; 56 | if (p->l) 57 | p->l->p = p; 58 | } else { 59 | p->r = v->l; 60 | v->l = p; 61 | if (p->r) 62 | p->r->p = p; 63 | } 64 | if (g && (g->l == p || g->r == p)) 65 | (g->l == p ? g->l : g->r) = v; 66 | else{ 67 | root = v; 68 | } 69 | p->update(); 70 | v->update(); 71 | } 72 | void splay(Node *v) { 73 | v->pushDown(); 74 | while (!v->isRoot()) 75 | moveUp(v); 76 | } 77 | Node* operator[](int k){ 78 | Node *v = root; 79 | v->pushDown(); 80 | while(k != (v->l?v->l->sz:0)){ 81 | if(k < (v->l?v->l->sz:0)){ 82 | v = v->l; 83 | }else{ 84 | k -= (v->l?v->l->sz:0)+1; 85 | v = v->r; 86 | } 87 | v->pushDown(); 88 | } 89 | splay(v); 90 | return v; 91 | } 92 | void print(Node* v, int LVL = 0){ 93 | v->pushDown(); 94 | if(v->r)print(v->r,LVL+1); 95 | cout <id << "|" << v->sz << endl; 96 | if(v->l)print(v->l,LVL+1); 97 | } 98 | void print(){ print(root); } 99 | void reverseB(Node *B){ 100 | splay(B); 101 | B->pushDown(); 102 | if(B->r) 103 | { 104 | Node *r = B->r; 105 | r->pushDown(); 106 | while(r->l){ 107 | r = r->l; 108 | r->pushDown(); 109 | } 110 | splay(r); 111 | } 112 | B->rev ^= 1; 113 | } 114 | void reverse(int i,int j){ 115 | if(i == 0){ 116 | Node* J = (*this)[j]; 117 | reverseB(J); 118 | }else{ 119 | Node* J = (*this)[j]; 120 | // cout << " -- " << J->id << endl; 121 | reverseB(J); 122 | Node* I = (*this)[j-i]; 123 | // cout << " -- " << I->id << endl; 124 | reverseB(I); 125 | J = (*this)[j]; 126 | // cout << " -- " << J->id << endl; 127 | reverseB(J); 128 | // print(); 129 | } 130 | 131 | } 132 | }; -------------------------------------------------------------------------------- /Codes/Trees/SquareRootOptimization.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | struct Node{ 8 | int val; 9 | Node(int val = 0){ 10 | this->val = val; 11 | } 12 | void update(int v){ 13 | val += v; 14 | } 15 | Node operator+(const Node &N){ 16 | return Node(max(val,N.val)); 17 | } 18 | }; 19 | struct Group { 20 | Node *V; 21 | int SIZE; 22 | int ma, carry; 23 | Group(){ carry = -1; } 24 | ~Group(){ delete[] V; } 25 | int size(){ return SIZE; } 26 | void create(vector V){ 27 | this->V = new Node[SIZE = V.size()]; 28 | for(int i = 0; i < SIZE; ++i) 29 | this->V[i] = Node(V[i]); 30 | } 31 | void pushDown(){ 32 | if(carry == -1)return; 33 | for(int i = 0; i < SIZE; ++i) 34 | V[i].update(carry); 35 | carry = -1; 36 | } 37 | void rebuild(){ 38 | ma = 0; 39 | for(int i = 0; i < SIZE; ++i) 40 | ma = max(ma , V[i].val); 41 | } 42 | void update(int v){ 43 | ma = max(v , ma); 44 | carry = v; 45 | } 46 | void update(int i, int v){ 47 | V[i].update(v); 48 | } 49 | Node query(){ 50 | return Node(ma); 51 | } 52 | Node query(int i){ 53 | return V[i]; 54 | } 55 | }; 56 | struct SqrtOptimization 57 | { 58 | #define GSIZE 1000 59 | Group *GS; 60 | int N; 61 | SqrtOptimization(int N){ 62 | this->N = N; 63 | int GCNT = N / GSIZE + (N % GSIZE != 0); 64 | GS = new Group[GCNT]; 65 | this->create(vector(N,0)); 66 | } 67 | ~SqrtOptimization(){ delete[] GS; } 68 | void create(const vector &V){ 69 | int GCNT = N / GSIZE + (N % GSIZE != 0); 70 | for (int i = 0; i < GCNT; ++i) { 71 | vector SUB_V(V.begin()+i*GSIZE, V.begin()+min((i+1)*GSIZE,N)); 72 | GS[i].create(SUB_V); 73 | } 74 | } 75 | void update(int i,int j,int v){ 76 | int gi = i/GSIZE , gj = j/GSIZE, pi = i % GSIZE, pj = j % GSIZE; 77 | GS[gi].pushDown(); GS[gj].pushDown(); 78 | while(pi && pi < GSIZE && gi < gj) 79 | GS[gi].update(pi++,v) , i++; 80 | GS[gi].rebuild(); 81 | gi = i/GSIZE; 82 | while(gi < gj) 83 | GS[gi++].update(v) , i += GSIZE; 84 | pi = i % GSIZE; 85 | while(pi<= pj) 86 | GS[gi].update(pi++,v) , i++; 87 | GS[gj].rebuild(); 88 | } 89 | Node query(int i,int j){ 90 | int gi = i/GSIZE , gj = j/GSIZE, pi = i % GSIZE, pj = j % GSIZE; 91 | GS[gi].pushDown(); GS[gj].pushDown(); 92 | vector TV; TV.reserve(2*GSIZE); 93 | while(pi && pi < GSIZE && gi < gj) 94 | TV.push_back(GS[gi].query(pi++)) , i++; 95 | gi = i/GSIZE; 96 | while(gi < gj) 97 | TV.push_back(GS[gi++].query()) , i += GSIZE; 98 | pi = i % GSIZE; 99 | while(pi<= pj) 100 | TV.push_back(GS[gi].query(pi++)) , i++; 101 | Node ret = TV[0]; 102 | for(int g = 1; g < TV.size(); ++g) ret = ret + TV[g]; 103 | return ret; 104 | } 105 | }; 106 | 107 | int main(){ 108 | SqrtOptimization S(100); 109 | for(int i = 0; i < 10; ++i){ 110 | S.update(0,i*5,1); 111 | for(int j = 0; j < 50; ++j){ 112 | cout << S.query(j,j).val << " "; 113 | } 114 | cout << ": " << S.query(10,99).val << endl; 115 | } 116 | for(int i = 9; i >= 0; --i){ 117 | S.update(0,i*5,-1); 118 | for(int j = 0; j < 50; ++j){ 119 | cout << S.query(j,j).val << " "; 120 | } 121 | cout << ": " << S.query(10,99).val << endl; 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /Codes/Trees/TreapSet.cpp: -------------------------------------------------------------------------------- 1 | template 2 | class Treap { 3 | struct Node{ 4 | int y,sz; 5 | T x; 6 | Node *l, *r; 7 | Node(T x):x(x){ 8 | y = rand(); 9 | sz = 1; 10 | l = r = NULL; 11 | } 12 | void update(){ 13 | sz = 1 + (r?r->sz:0) + (l?l->sz:0); 14 | } 15 | }; 16 | Node *root; 17 | void split (Node *t, const function &goLeft, Node *&l, Node *&r) { 18 | if (!t)l = r = NULL; 19 | else if ( goLeft(t) ) 20 | split (t->l, goLeft, l, t->l), r = t; 21 | else 22 | split (t->r, goLeft, t->r, r), l = t; 23 | if(t)t->update(); 24 | } 25 | void split (Node *t, const T &x, Node *&l, Node *&r) { 26 | return split(t, [x](const Node *t) { return x < t->x; }, l, r); 27 | } 28 | 29 | void insert (Node *&t, Node *it) { 30 | if(!t)t = it; 31 | else if(it->y > t->y){ 32 | split(t, it->x, it->l, it->r), t = it; 33 | }else{ 34 | insert(it->x < t->x ? t->l : t->r, it); 35 | } 36 | t->update(); 37 | } 38 | void erase(Node *&t, T x){ 39 | if(t->x == x){ 40 | Node *old = t; 41 | merge(t, t->l, t->r); 42 | delete old; 43 | }else 44 | erase(x < t->x ? t->l : t->r, x); 45 | if(t)t->update(); 46 | } 47 | void merge (Node *&t, Node *l, Node *r) { 48 | if (!l || ! r){ 49 | t = l? l: r; 50 | }else if (l->y > r->y){ 51 | merge (l->r, l->r, r); 52 | t = l; 53 | }else{ 54 | merge (r->l, l, r->l); 55 | t = r; 56 | } 57 | if(t)t->update(); 58 | } 59 | T end(Node *t) { 60 | while (t->r) t = t->r; return t->x; 61 | } 62 | public: 63 | Treap(){ 64 | root = NULL; 65 | } 66 | void clear(){ clear(root);} 67 | int size() { 68 | return root == NULL ? 0 : root->sz; 69 | } 70 | void clear(Node *&t){ 71 | if(!t)return; 72 | clear(t->l); 73 | clear(t->r); 74 | delete t; 75 | t = NULL; 76 | } 77 | void insert(T x){ 78 | Node *nn = new Node(x); 79 | insert(root, nn); 80 | } 81 | void erase(T x){ 82 | if(!root)return; 83 | erase(root, x); 84 | } 85 | T operator[](int i) { 86 | Node *l, *r; 87 | auto splitLeft = [&i](const Node *t) { 88 | int lsz = t->l ? t->l->sz : 0; 89 | if (lsz > i) return true; 90 | i -= lsz + 1; 91 | return false; 92 | }; 93 | split(root, splitLeft, l, r); 94 | T ret = end(l); 95 | merge(root, l, r); 96 | return ret; 97 | } 98 | int lowerBound(const function gte) { 99 | Node *l, *r; 100 | auto splitLeft = [>e](const Node *t) { 101 | if (gte(t->x)) return true; 102 | return false; 103 | }; 104 | split(root, splitLeft, l, r); 105 | int c = (l ? l->sz : 0); 106 | merge(root, l, r); 107 | return c; 108 | } 109 | int countLowerEqual(T x){ 110 | if(!root)return 0; 111 | Node *l, *r; 112 | split(root, x, l, r); 113 | int cnt = l?l->sz:0; 114 | merge(root, l, r); 115 | return cnt; 116 | } 117 | void print(bool asArray = false){ 118 | if(asArray)printArray(root); 119 | else printTree(root); 120 | cout << endl; 121 | } 122 | void printArray(Node *p, int LVL = 0){ 123 | if(!p)return; 124 | printArray(p->l, LVL+1); 125 | cout << (p->x) << " "; 126 | printArray(p->r, LVL+1); 127 | } 128 | void printTree(Node *p, int LVL = 0){ 129 | if(!p)return; 130 | printTree(p->r, LVL+1); 131 | cout <x) << endl; 132 | printTree(p->l, LVL+1); 133 | } 134 | }; 135 | -------------------------------------------------------------------------------- /Codes/Trees/Treap_SegmentTree.cpp: -------------------------------------------------------------------------------- 1 | #define WHITE 3 2 | #define BLACK 2 3 | #define FLIP 1 4 | #define NONE 0 5 | struct Node{ 6 | int y,sz,rev; 7 | int id, white, black, carr, color; 8 | bool pending; 9 | Node *l, *r; 10 | Node(){ 11 | y = rand() % 1000000000; 12 | sz = 1; 13 | l = r = NULL; 14 | rev = 0; 15 | y = 0; 16 | id = 0; 17 | white = 1; 18 | black = 0; 19 | color = WHITE; 20 | carr = 0; 21 | pending = false; 22 | } 23 | int x(){ 24 | return (l?l->sz:0); 25 | } 26 | void push(){ 27 | if(rev){ 28 | swap(r,l); 29 | if(r)r->rev ^= 1; 30 | if(l)l->rev ^= 1; 31 | rev = 0; 32 | } 33 | if(pending){ 34 | if(r)r->applyChange(carr); 35 | if(l)l->applyChange(carr); 36 | pending = false; 37 | carr = NONE; 38 | } 39 | } 40 | void update(){ 41 | sz = 1 + (r?r->sz:0) + (l?l->sz:0); 42 | white = (color == WHITE) + (l?l->white:0) + (r?r->white:0); 43 | black = sz - white; 44 | } 45 | void applyChange(int v){ 46 | if(v == WHITE){ 47 | white = sz; 48 | black = 0; 49 | carr = WHITE; 50 | color = WHITE; 51 | pending = true; 52 | } else if(v == BLACK){ 53 | black = sz; 54 | white = 0; 55 | carr = BLACK; 56 | color = BLACK; 57 | pending = true; 58 | } else if(v == FLIP){ 59 | swap(black, white); 60 | color = (color == WHITE) ? BLACK : WHITE; 61 | switch(carr){ 62 | case NONE: 63 | carr = v; 64 | break; 65 | case WHITE: 66 | carr = BLACK; 67 | break; 68 | case BLACK: 69 | carr = WHITE; 70 | break; 71 | case FLIP: 72 | carr = NONE; 73 | break; 74 | } 75 | pending = true; 76 | } 77 | } 78 | }; 79 | struct Treap { 80 | typedef pair PNN; 81 | vector V; 82 | Node *root; 83 | Treap(int N){ 84 | root = NULL; 85 | V = vector(N); 86 | build(root, V, 0, N-1); 87 | 88 | } 89 | int build(Node *&t, vector &V, int i, int j){ 90 | if(jy = 1; 96 | }else{ 97 | int m = (i+j)/2; 98 | t = &V[m]; 99 | t->y = 1 + max(build(t->l, V,i,m-1),build(t->r, V,m+1,j)); 100 | } 101 | t->update(); 102 | return t->y; 103 | } 104 | void split (Node *t, int x, Node *&l, Node *&r) { 105 | if(t)t->push(); 106 | if (!t)l = r = NULL; 107 | else if ( x < t->x() ) 108 | split (t->l, x, l, t->l), r = t; 109 | else 110 | split (t->r, x - t->x() - 1, t->r, r), l = t; 111 | if(t)t->update(); 112 | } 113 | // 114 | void insert (Node *&t, int x, Node *it) { 115 | Node *t1, *t2; 116 | split(t, x, t1, t2); 117 | merge(t1, t1, it); 118 | merge(t, t1, t2); 119 | } 120 | void merge (Node *&t, Node *l, Node *r) { 121 | if(l)l->push(); 122 | if(r)r->push(); 123 | if (!l || ! r){ 124 | t = l? l: r; 125 | }else if (l->y > r->y){ 126 | merge (l->r, l->r, r); 127 | t = l; 128 | }else{ 129 | merge (r->l, l, r->l); 130 | t = r; 131 | } 132 | if(t)t->update(); 133 | } 134 | void reverse(int i, int j){ 135 | Node *l, *m, *r; 136 | split(root, j, l, r); 137 | split(l, i-1, l, m); 138 | m->rev ^= 1; 139 | merge(l, l, m); 140 | merge(root, l, r); 141 | } 142 | void applyChange(int i, int j, int v){ 143 | Node *l, *m, *r; 144 | split(root, j, l, r); 145 | split(l, i-1, l, m); 146 | m->applyChange(v); 147 | merge(l, l, m); 148 | merge(root, l, r); 149 | } 150 | Node query(int i, int j){ 151 | Node *l, *m, *r, q; 152 | split(root, j, l, r); 153 | split(l, i-1, l, m); 154 | q = *m; 155 | merge(l, l, m); 156 | merge(root, l, r); 157 | return q; 158 | } 159 | void print(){ 160 | print(root); 161 | cout << endl; 162 | } 163 | void print(Node *p, int LVL = 0){ 164 | if(!p)return; 165 | p->push(); 166 | print(p->r, LVL+1); 167 | cout << (p->color == WHITE) << " "; 168 | print(p->l, LVL+1); 169 | } 170 | }; -------------------------------------------------------------------------------- /Codes/Trees/UniqueTreeEncoding.cpp: -------------------------------------------------------------------------------- 1 | vector byHeight[3010]; 2 | int NODE_H[3010], RANK[3010]; 3 | int dfs(int u, int p, VVI &adj, VVI &nadj) { 4 | int h = 0; 5 | for (int v : adj[u]) { 6 | if (v == p) continue; 7 | nadj[u].push_back(v); 8 | h = max(h, 1 + dfs(v, u, adj, nadj)); 9 | } 10 | byHeight[h].push_back(u); 11 | return NODE_H[u] = h; 12 | } 13 | 14 | struct Comparator { 15 | int ch; 16 | VVI &adj; 17 | int operator()(int a, int b) { 18 | if (NODE_H[a] != NODE_H[b]) return NODE_H[a] > NODE_H[b]; 19 | if (NODE_H[a] != ch) return RANK[a] < RANK[b]; 20 | int mn = min(adj[a].size(), adj[b].size()); 21 | for (int j = 0; j < mn; ++j) { 22 | if (RANK[adj[a][j]] != RANK[adj[b][j]]) 23 | return RANK[adj[a][j]] < RANK[adj[b][j]]; 24 | } 25 | return adj[a].size() > adj[b].size(); // if A has more it will be lexicografically smaller 26 | } 27 | }; 28 | 29 | void build(int u, string &S, VVI &adj) { 30 | S += "("; 31 | for (int v : adj[u]) 32 | build(v, S, adj); 33 | S += ")"; 34 | } 35 | 36 | string encodeTree(int cent, VVI &adj) { 37 | int N = adj.size(); 38 | VVI nadj(N); 39 | int currRank = N; 40 | for (int t = 0; t < N; ++t) byHeight[t].clear(); 41 | int H = dfs(cent, -1, adj, nadj); 42 | for (int h = 0; h <= H; ++h) { 43 | Comparator cmp = {h, nadj}; 44 | VI &L = byHeight[h]; 45 | if (h == 0) { 46 | for (int u : L) RANK[u] = currRank-1; 47 | currRank--; 48 | continue; 49 | } 50 | for (int u : L) sort(nadj[u].begin(), nadj[u].end(), cmp); 51 | sort(L.begin(), L.end(), cmp); 52 | for (int i = int(L.size())-1; i >= 0; --i) { 53 | if (i +1 == L.size()) { 54 | RANK[L[i]] = --currRank; 55 | } else if (cmp(L[i], L[i+1]) == cmp(L[i+1], L[i])) { 56 | RANK[L[i]] = currRank; 57 | } else { 58 | RANK[L[i]] = --currRank; 59 | } 60 | } 61 | } 62 | string S; 63 | build(cent, S, nadj); 64 | return S; 65 | } 66 | -------------------------------------------------------------------------------- /Codes/Trees/WaveletTree.cpp: -------------------------------------------------------------------------------- 1 | struct WaveletTree { 2 | int lo,hi; 3 | vector A; 4 | WaveletTree *l, *r; 5 | #define get(i) (i<0?0:A[i]) 6 | WaveletTree(vector V) 7 | :WaveletTree(V.begin(), V.end(), 8 | *min_element(V.begin(), V.end()), 9 | *max_element(V.begin(), V.end())){} 10 | template 11 | WaveletTree(IT b, IT e, int lo, int hi, int lvl = 0):lo(lo),hi(hi),l(NULL),r(NULL) { 12 | int mi = (lo+hi)>>1; 13 | function isLeft = [mi](int x) { return x <= mi; }; 14 | A.reserve(e - b); 15 | for(IT i = b; i != e; ++i) 16 | A.push_back(isLeft(*i) + (i==b?0:A.back())); 17 | IT ps = stable_partition(b, e, isLeft); 18 | if(lo == hi || b == e)return; 19 | l = new WaveletTree(b, ps, lo, mi, lvl+1); 20 | r = new WaveletTree(ps, e, mi+1, hi, lvl+1); 21 | } 22 | void getWithMore(int i, int j, int w, const function &emit){ 23 | if(j-i+1 < w)return; 24 | if(lo == hi) { emit(lo); return; } 25 | int ai = get(i-1), aj = A[j]; 26 | l->getWithMore( ai, aj-1, w, emit); 27 | r->getWithMore(i-ai, j-aj, w, emit); 28 | } 29 | int getFreq(int i, int j, int a, int b) { // count elements from a to b 30 | if(j < i)return 0; 31 | if(a <= lo && hi <= b) return j-i+1; 32 | if(b < lo || hi < a) return 0; 33 | int ai = get(i-1), aj = A[j]; 34 | return l->getFreq( ai, aj-1, a, b) + 35 | r->getFreq(i-ai, j-aj, a, b); 36 | } 37 | int getKth(int i, int j, int k) { // 0-based 38 | if(lo == hi) return lo; 39 | int ai = get(i-1), aj = A[j]; 40 | int cntL = aj-ai; 41 | if(cntL > k) return l->getKth( ai, aj-1, k); 42 | else return r->getKth(i-ai, j-aj, k-cntL); 43 | } 44 | void swap(int i){ // i and i+1 45 | if(lo == hi)return; 46 | int ai = get(i-1); 47 | int f = A[i] - ai, s = A[i+1] - A[i]; 48 | if(f != s) A[i] += s-f; 49 | else if(f == 1) l->swap( ai); 50 | else r->swap(i-ai); 51 | } 52 | /// countDistinct(i, j) 53 | /// buildWavelet using array of next appearance: 54 | /// NEXT[i] = next position of element ARR[i] == ARR[i] 55 | /// then build WaveletTree(NEXT) and do "t.getFreq(i, j, j+1, t.hi)" 56 | void print(int lvl = 0){ 57 | if(l)l->print(lvl+1); 58 | cout << string(lvl, '\t'); 59 | for (int i = 0; i < A.size(); ++i) 60 | cout << get(i) - get(i-1); 61 | cout << endl; 62 | if(r)r->print(lvl+1); 63 | } 64 | #undef get 65 | }; -------------------------------------------------------------------------------- /Codes/Utils/Printer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | struct Printer 7 | { 8 | template 9 | static void print(pair P) 10 | { 11 | printf("(%d,%d)",P.first,P.second); 12 | } 13 | static void print(int n) 14 | { 15 | printf("%d",n); 16 | } 17 | template 18 | static void print(vector V) 19 | { 20 | printf("{"); 21 | for(int i = 0; i < V.size(); ++i){ 22 | if(i > 0)printf(", "); 23 | print(V[i]); 24 | } 25 | printf("}\n"); 26 | 27 | } 28 | template 29 | static void print(vector > V) 30 | { 31 | printf("{\n"); 32 | for(int i = 0; i < V.size(); ++i){ 33 | printf(" [%d]\t",i); 34 | print(V[i]); 35 | } 36 | printf("}\n"); 37 | } 38 | template 39 | static void print(ITERATOR begin, ITERATOR end) 40 | { 41 | printf("{\n"); 42 | while(begin != end) 43 | { 44 | print(*begin); 45 | printf(", "); 46 | begin++; 47 | } 48 | printf("}\n"); 49 | } 50 | }; 51 | -------------------------------------------------------------------------------- /Codes/Utils/Random.cpp: -------------------------------------------------------------------------------- 1 | struct Rand { 2 | mt19937 gen; 3 | Rand(int SEED = 1234567):gen(SEED){} 4 | Rand(mt19937 gen):gen(gen){} 5 | 6 | int getInt(int mn, int mx){ 7 | uniform_int_distribution uDist(mn, mx); 8 | return uDist(gen); 9 | } 10 | double getNormal(double mean, double deviation){ 11 | normal_distribution nDist(mean, deviation); 12 | return nDist(gen); 13 | } 14 | }; -------------------------------------------------------------------------------- /Codes/Utils/SidePrinter.cpp: -------------------------------------------------------------------------------- 1 | struct SidePrinter : stringstream { 2 | int cursor; 3 | int width; 4 | vector streams; 5 | SidePrinter(): cursor(0), width(0) { 6 | streams.push_back(stringstream()); 7 | } 8 | ~SidePrinter() { 9 | flush(); 10 | } 11 | 12 | void endLine() { 13 | cursor++; 14 | while (cursor >= streams.size()) { 15 | streams.push_back(stringstream()); 16 | streams.back() << string(width, ' '); 17 | } 18 | } 19 | 20 | void flush() { 21 | for (auto &ss : streams) { 22 | cout << ss.str() << endl; 23 | } 24 | streams.clear(); 25 | width = 0; 26 | cursor = -1; 27 | endLine(); 28 | } 29 | 30 | void reset() { 31 | cursor = 0; 32 | for (auto &ss : streams) { 33 | width = max(width, int(ss.str().size())); 34 | } 35 | for (auto &&ss : streams) { 36 | int rem = width - int(ss.str().size()); 37 | ss << string(rem, ' '); 38 | } 39 | } 40 | 41 | SidePrinter& operator<<(bool s) { streams[cursor] << s; return *this; } 42 | SidePrinter& operator<<(int s) { streams[cursor] << s; return *this; } 43 | SidePrinter& operator<<(long long s) { streams[cursor] << s; return *this; } 44 | SidePrinter& operator<<(double s) { streams[cursor] << s; return *this; } 45 | SidePrinter& operator<<(char s) { 46 | if (s == '\n') endLine(); 47 | else streams[cursor] << s; 48 | return *this; 49 | } 50 | SidePrinter& operator<<(const char* s) { 51 | while (*s) { 52 | *this << *s; 53 | s++; 54 | } 55 | return *this; 56 | } 57 | SidePrinter& operator<<(const string& s) { 58 | for (char c : s) { 59 | *this << c; 60 | } 61 | return *this; 62 | } 63 | }; 64 | -------------------------------------------------------------------------------- /Codes/src/main.cpp: -------------------------------------------------------------------------------- 1 | //============================================================================ 2 | // Name : Codes.cpp 3 | // Author : Carlos Toribio 4 | // Version : 5 | // Copyright : Your copyright notice 6 | // Description : Hello World in C++, Ansi-style 7 | //============================================================================ 8 | 9 | #include 10 | #include "../DynamicProgramming/InversionCount.cpp" 11 | 12 | using namespace std; 13 | 14 | int main() 15 | { 16 | 17 | vector V; 18 | V.push_back(4); 19 | V.push_back(2); 20 | V.push_back(1); 21 | V.push_back(3); 22 | cout << InversionCount::inversionCount(V) << endl; 23 | 24 | cout << "Compiled !!!" << endl; // prints !!!Hello World!!! 25 | return 0; 26 | 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Images/Aho-Corasick/AhoCorasick-Example.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cjtoribio/Algorithms/9e9609b12e47b8897f7026198f2e55ffc9f457f5/Images/Aho-Corasick/AhoCorasick-Example.PNG -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Carlos Toribio 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | My personal algorithmic libraries 4 | 5 | ## Index 6 | 7 | * [Graph](./Codes/Graph) 8 | * [2-SAT](./Codes/Graph/2-SAT.cpp): 9 | * 1-based implementation of 2-Satisfiability Problem (positive numbers for positive propositions and negative number for negative propositions. 10 | * [Connected Components](./Codes/Graph/ConnectedComponnents.cpp) 11 | * Note: Need to extract necesary code for each of the following subproblems. 12 | * StronglyConnectedComponents 13 | * BiconnectedComponents 14 | * ArticulationPointsAndBridges 15 | * [Count Number of Minimum Spanning Trees](./Codes/Graph/CountMinimumSpanningTree.cpp) 16 | * This is uses Count Number of Spanning Trees and [mint](https://github.com/cjtoribio/Algorithms/blob/2402330194adaaeb7e0dae15227f8ce4350cbe4c/Codes/Math/ModInt.cpp#L68) 17 | * [Count Number of Spanning Trees](./Codes/Graph/CountSpanningTree.cpp) 18 | * Note: Code is equivalent to building the matrix with addEdge and finding determinant. [mint](https://github.com/cjtoribio/Algorithms/blob/2402330194adaaeb7e0dae15227f8ce4350cbe4c/Codes/Math/ModInt.cpp#L68) is just a ModularInt with the defined operations (/, *, +, -) [note modular division needed] 19 | * [Eulerian Path And Cycle](./Codes/Graph/EulerianPathAndCycle) 20 | * Finds an eulerian path or a cycle in O(N) 21 | * [HopcroftCarp.cpp](./Codes/Graph/EulerianPathAndCycle) 22 | * Maximum matching O(sqrt(V)*E) 23 | * [Hungarian Algorithm](./Graph/MaxFlow%5BDinics-EdgeList%5D.cpp) 24 | * Finds a weighted maximum matching in O(V^3) best for dense graphs, for non complete graphs use INF as edge cost, an alternative is to run MinCostMaxFlow. 25 | * [MaxFlow](./Codes/Graph/MincostMaxflow%5BAdjMatrix%5D.cpp) 26 | * Has a running time of O(|V|^2 |E|). 27 | * Can be used to find MaximumMatching and runs relatively fast, in theory same complexity as HopcroftCarp if all edges has capacity 1. 28 | * [MinCostMaxFlow](./Codes/Graph/MincostMaxflow%5BAdjMatrix%5D.cpp) 29 | * Can be a substitute of HungarianAlgorithm and also other MaxFlow with costs involved. 30 | * [VertextCover](./Codes/Graph/VertexCover.cpp) 31 | * Can find a minimum vertex cover after a maximum matching is provided. 32 | * NOTE: It does not have MaxMatching you have to run MaxMatching and then pass the matching to this algorithm. 33 | * Dynamic Programming 34 | * Math 35 | * Trees 36 | * String 37 | * Geometry 38 | --------------------------------------------------------------------------------