├── Closest_Pair_of_Points.cpp ├── CycleDetect_DirectedGraph.cpp ├── DSU.cpp ├── Dinic_MaxFlow.cpp ├── Hopcroft_Karp_Max_Bipartite_Matching.cpp ├── Kruskal's Algo - MST.cpp ├── LIS.cpp ├── Lazy_Prop_Segment_Tree.cpp ├── MInHeap.cpp ├── Manacher's Algo - no. of palindromes.cpp ├── Maths.cpp ├── Mo's_algo.cpp ├── PBDS.cpp ├── README.md ├── Suffix_Array.cpp ├── Tree_LCA.cpp ├── Trie.cpp ├── Undir_Graph_Cycle_Det.cpp ├── Zarray.cpp ├── dfs.cpp ├── dijkstra_&_bfs.cpp ├── fenwick.cpp ├── fft_ntt.cpp ├── matrixExpo.cpp ├── prim_algo_n2.cpp ├── segment_tree.cpp ├── subset_sum.cpp └── umap_hasher.cpp /Closest_Pair_of_Points.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // A structure to represent a Point in 2D plane 5 | class Point 6 | { 7 | public: 8 | int x, y, idx; 9 | }; 10 | 11 | // Needed to sort array of points according to X coordinate 12 | int compareX(const void* a, const void* b) 13 | { 14 | Point *p1 = (Point *)a, *p2 = (Point *)b; 15 | return (p1->x - p2->x); 16 | } 17 | 18 | // Needed to sort array of points according to Y coordinate 19 | int compareY(const void* a, const void* b) 20 | { 21 | Point *p1 = (Point *)a, *p2 = (Point *)b; 22 | return (p1->y - p2->y); 23 | } 24 | 25 | 26 | // Find distance between two points 27 | float dist(Point p1, Point p2) 28 | { 29 | return sqrt( (p1.x - p2.x)*(p1.x - p2.x) +(p1.y - p2.y)*(p1.y - p2.y)); 30 | } 31 | 32 | // Find the smallest distance between two points by brute force 33 | float bruteForce(Point P[], int n, int &i1, int &i2) 34 | { 35 | float min = FLT_MAX; 36 | for (int i = 0; i < n; ++i) 37 | { 38 | for (int j = i+1; j < n; ++j) 39 | { 40 | if (dist(P[i], P[j]) < min) 41 | { 42 | min = dist(P[i], P[j]); 43 | i1 = P[i].idx; 44 | i2 = P[j].idx; 45 | } 46 | } 47 | } 48 | return min; 49 | } 50 | 51 | 52 | // Find the distance between the closest points of strip[] 53 | float stripClosest(Point strip[], int size, float d, int &i1, int &i2) 54 | { 55 | float min = d; 56 | qsort(strip, size, sizeof(Point), compareY); 57 | 58 | // Inner loop runs at most 6 times 59 | for (int i = 0; i < size; ++i) 60 | { 61 | for (int j = i+1; j < size && (strip[j].y - strip[i].y) < min; ++j) 62 | { 63 | if (dist(strip[i],strip[j]) < min) 64 | { 65 | min = dist(strip[i], strip[j]); 66 | i1 = strip[i].idx; 67 | i2 = strip[j].idx; 68 | } 69 | } 70 | } 71 | 72 | return min; 73 | } 74 | 75 | 76 | // Find the smallest distance using divide and conquer technique. 77 | float closestUtil(Point P[], int n, int &i1, int &i2) 78 | { 79 | // If there are 2 or 3 points, then use brute force 80 | if (n <= 3) 81 | return bruteForce(P, n, i1, i2); 82 | 83 | int mid = n/2; 84 | Point midPoint = P[mid]; 85 | 86 | int i11, i12, i21, i22; 87 | float dl = closestUtil(P, mid, i11, i12); 88 | float dr = closestUtil(P + mid, n - mid, i21, i22); 89 | float d; 90 | if(dl < dr) 91 | { 92 | d = dl; 93 | i1 = i11; i2 = i12; 94 | } 95 | else 96 | { 97 | d = dr; 98 | i1 = i21; i2 = i22; 99 | } 100 | 101 | // Create a strip of width 2d 102 | Point strip[n]; 103 | int j = 0; 104 | for (int i = 0; i < n; i++) 105 | if (abs(P[i].x - midPoint.x) < d) 106 | strip[j] = P[i], j++; 107 | 108 | return stripClosest(strip, j, d, i1, i2); 109 | } 110 | 111 | 112 | float closest(Point P[], int n, int &i1, int &i2) 113 | { 114 | qsort(P, n, sizeof(Point), compareX); 115 | return closestUtil(P, n, i1, i2); 116 | } 117 | 118 | 119 | int main() 120 | { 121 | Point P[] = {{2, 3, 1}, {12, 30, 2}, {40, 50, 3}, {5, 1, 4}, {12, 10, 5}, {3, 4, 6}}; 122 | int n = sizeof(P) / sizeof(P[0]); 123 | int i1, i2; 124 | cout << "The smallest distance is " << closest(P, n, i1, i2) << endl; 125 | cout << i1 << " " << i2 << endl; 126 | return 0; 127 | } 128 | -------------------------------------------------------------------------------- /CycleDetect_DirectedGraph.cpp: -------------------------------------------------------------------------------- 1 | vll v[mxN]; 2 | vll vis(mxN); 3 | vll in(mxN); 4 | bool cycle; 5 | void cdfs(ll x) 6 | { 7 | vis[x]=1; 8 | for(auto i:v[x]) 9 | { 10 | if(vis[i]==1){ cycle=true; break; } 11 | if(vis[i]==0) cdfs(i); 12 | if(cycle) break; 13 | } 14 | vis[x]=2; 15 | } 16 | bool is_cycle(ll n) 17 | { 18 | cycle=false; 19 | rep(i,1,n+1) 20 | { 21 | if(in[i]==0) cdfs(i); 22 | if(cycle) break; 23 | } 24 | rep(i,1,n+1) 25 | if(vis[i]==0) cycle=true; 26 | return cycle; 27 | } -------------------------------------------------------------------------------- /DSU.cpp: -------------------------------------------------------------------------------- 1 | //to get number of different sets - count 1 in siz or siz.size() 2 | //clear parent and siz after DSU is used 3 | 4 | //Disjoint Set Union 5 | ll parent[mxN]; //map parent; 6 | ll siz[mxN]; //map siz; 7 | void make_set(ll v) { 8 | parent[v]=v; siz[v]=1; 9 | } 10 | ll find_set(ll v) { 11 | return (v==parent[v])?v:parent[v]=find_set(parent[v]); 12 | } 13 | void union_sets(ll a, ll b) { 14 | a = find_set(a); 15 | b = find_set(b); 16 | if (a == b) return; 17 | if(siz[a] 4 | struct Dinic { 5 | struct FlowEdge 6 | { 7 | int v, u; 8 | flow_t cap, flow = 0; 9 | FlowEdge(int v, int u, flow_t cap) : v(v), u(u), cap(cap) {} 10 | }; 11 | const flow_t flow_inf = numeric_limits::max()/2; 12 | vector edges; 13 | vector> adj; 14 | int n, m = 0; 15 | int s, t; 16 | // s -> source 17 | // t -> sink 18 | vector level, ptr; 19 | queue q; 20 | 21 | Dinic(int n, int s, int t) : n(n), s(s), t(t) 22 | { 23 | adj.resize(n+1); 24 | level.resize(n+1); 25 | ptr.resize(n+1); 26 | } 27 | 28 | void add_edge(int v, int u, flow_t cap) 29 | { 30 | edges.emplace_back(v, u, cap); 31 | edges.emplace_back(u, v, 0); 32 | adj[v].push_back(m); 33 | adj[u].push_back(m + 1); 34 | m += 2; 35 | } 36 | 37 | bool bfs() 38 | { 39 | while (!q.empty()) { 40 | int v = q.front(); 41 | q.pop(); 42 | for (int id : adj[v]) { 43 | if (edges[id].cap - edges[id].flow < 1) 44 | continue; 45 | if (level[edges[id].u] != -1) 46 | continue; 47 | level[edges[id].u] = level[v] + 1; 48 | q.push(edges[id].u); 49 | } 50 | } 51 | return level[t] != -1; 52 | } 53 | 54 | flow_t dfs(int v, flow_t pushed) 55 | { 56 | if (pushed == 0) 57 | return 0; 58 | if (v == t) 59 | return pushed; 60 | for (int& cid = ptr[v]; cid < (int)adj[v].size(); cid++) { 61 | int id = adj[v][cid]; 62 | int u = edges[id].u; 63 | if (level[v] + 1 != level[u] || edges[id].cap - edges[id].flow < 1) 64 | continue; 65 | flow_t tr = dfs(u, min(pushed, edges[id].cap - edges[id].flow)); 66 | if (tr == 0) 67 | continue; 68 | edges[id].flow += tr; 69 | edges[id ^ 1].flow -= tr; 70 | return tr; 71 | } 72 | return 0; 73 | } 74 | 75 | flow_t flow() 76 | { 77 | flow_t f = 0; 78 | while (true) { 79 | fill(level.begin(), level.end(), -1); 80 | level[s] = 0; 81 | q.push(s); 82 | if (!bfs()) 83 | break; 84 | fill(ptr.begin(), ptr.end(), 0); 85 | while (flow_t pushed = dfs(s, flow_inf)) { 86 | f += pushed; 87 | } 88 | } 89 | return f; 90 | } 91 | }; 92 | // .add_edge(u,v,cap);u->v 93 | // .flow() == maxFlow 94 | 95 | 96 | //Use - https://www.codechef.com/viewsolution/47741478 97 | -------------------------------------------------------------------------------- /Hopcroft_Karp_Max_Bipartite_Matching.cpp: -------------------------------------------------------------------------------- 1 | // Hopcroft Karp algorithm for 2 | // Maximum Bipartite Matching 3 | 4 | #define NIL 0 5 | #define INF INT_MAX 6 | 7 | class BipGraph 8 | { 9 | int m, n; 10 | list *adj; 11 | int *pairU, *pairV, *dist; 12 | 13 | public: 14 | BipGraph(int m, int n); 15 | void addEdge(int u, int v); 16 | 17 | bool bfs(); 18 | bool dfs(int u); 19 | vector hopcroftKarp(); 20 | }; 21 | 22 | vector BipGraph::hopcroftKarp() 23 | { 24 | pairU = new int[m+1]; 25 | pairV = new int[n+1]; 26 | dist = new int[m+1]; 27 | 28 | for (int u=0; u<=m; u++) 29 | pairU[u] = NIL; 30 | for (int v=0; v<=n; v++) 31 | pairV[v] = NIL; 32 | 33 | int result = 0; 34 | while (bfs()) 35 | { 36 | for (int u=1; u<=m; u++) 37 | if (pairU[u]==NIL && dfs(u)) 38 | result++; 39 | } 40 | 41 | vector ans(m); 42 | for(int i=0; i Q; 52 | for (int u=1; u<=m; u++) 53 | { 54 | if (pairU[u]==NIL) 55 | { 56 | dist[u] = 0; 57 | Q.push(u); 58 | } 59 | else dist[u] = INF; 60 | } 61 | 62 | dist[NIL] = INF; 63 | while (!Q.empty()) 64 | { 65 | int u = Q.front(); 66 | Q.pop(); 67 | if (dist[NIL]!=INF) break; 68 | for (auto v: adj[u]) 69 | { 70 | if (dist[pairV[v]] == INF) 71 | { 72 | dist[pairV[v]] = dist[u] + 1; 73 | Q.push(pairV[v]); 74 | } 75 | } 76 | } 77 | 78 | return (dist[NIL] != INF); 79 | } 80 | 81 | // Returns true if there is an augmenting path beginning with free vertex u 82 | bool BipGraph::dfs(int u) 83 | { 84 | if (u == NIL) return true; 85 | for (auto v: adj[u]) 86 | { 87 | if (dist[pairV[v]] == dist[u]+1) 88 | { 89 | if (dfs(pairV[v]) == true) 90 | { 91 | pairV[v] = u; 92 | pairU[u] = v; 93 | return true; 94 | } 95 | } 96 | } 97 | dist[u] = INF; 98 | return false; 99 | } 100 | 101 | // Constructor 102 | BipGraph::BipGraph(int m, int n) 103 | { 104 | this->m = m; 105 | this->n = n; 106 | adj = new list[m+1]; 107 | } 108 | 109 | // To add edge from u to v and v to u 110 | void BipGraph::addEdge(int u, int v) 111 | { 112 | adj[u].push_back(v); 113 | } 114 | -------------------------------------------------------------------------------- /Kruskal's Algo - MST.cpp: -------------------------------------------------------------------------------- 1 | //include DSU before using it 2 | 3 | // Kruskal's algo 4 | vtll e; 5 | vtll mst; 6 | ll kruskal() 7 | { 8 | sortall(e); 9 | ll cost=0; 10 | rep(i,0,n) make_set(i); 11 | for(auto i:e) 12 | { 13 | ll w,x,y; 14 | tie(w,x,y)=i; 15 | if(find_set(x)!=find_set(y)) 16 | { 17 | cost+=w; 18 | union_sets(x,y); 19 | mst.pb(i); 20 | } 21 | } 22 | return cost; 23 | } 24 | -------------------------------------------------------------------------------- /LIS.cpp: -------------------------------------------------------------------------------- 1 | // strictly increasing - use lower_bound 2 | // increasing or non decreasing - use upper_bound 3 | 4 | 5 | ll LIS(vll &a) 6 | { 7 | ll n=a.size(); 8 | vll d(n+1,INF); 9 | d[0]=-INF; 10 | rep(i,0,n) 11 | { 12 | ll j=ub(all(d),a[i])-d.begin(); 13 | // if(d[j-1]= 0) 28 | { 29 | MinHeapify(i); 30 | i--; 31 | } 32 | } 33 | void MinHeap::MinHeapify(ll i) 34 | { 35 | ll l = left(i); 36 | ll r = right(i); 37 | ll smallest = i; 38 | if (l < heap_size && 39 | harr[l].element < harr[i].element) 40 | smallest = l; 41 | if (r < heap_size && 42 | harr[r].element < harr[smallest].element) 43 | smallest = r; 44 | if (smallest != i) 45 | { 46 | swap(harr[i], harr[smallest]); 47 | MinHeapify(smallest); 48 | } 49 | } -------------------------------------------------------------------------------- /Manacher's Algo - no. of palindromes.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Manacher's Algo - Find No. of Palindromic substrings in O(n) 3 | void Manacher(string s) 4 | { 5 | ll n=s.size(); 6 | 7 | vector d1(n); //odd length palindrome with center i 8 | for(ll i = 0, l = 0, r = -1; i < n; i++) 9 | { 10 | ll k = (i > r) ? 1 : min(d1[l + r - i], r - i + 1); 11 | while (0 <= i - k && i + k < n && s[i - k] == s[i + k]) k++; 12 | d1[i] = k--; 13 | if (i + k > r) { 14 | l = i - k; 15 | r = i + k; 16 | } 17 | } 18 | vector d2(n); //even length palindrome with center i 19 | for(ll i = 0, l = 0, r = -1; i < n; i++) 20 | { 21 | ll k = (i > r) ? 0 : min(d2[l + r - i + 1], r - i + 1); 22 | while (0 <= i - k - 1 && i + k < n && s[i - k - 1] == s[i + k]) k++; 23 | d2[i] = k--; 24 | if (i + k > r) { 25 | l = i - k - 1; 26 | r = i + k ; 27 | } 28 | } 29 | 30 | ll count=0; 31 | for(ll i=0; i 0) { 15 | if(p & 1) res = res * a % M; 16 | a = a * a % M; 17 | p >>= 1; 18 | } 19 | return res; 20 | } 21 | ll modInv(ll a) { 22 | return modExp(a,M-2) % M ; 23 | } 24 | void pre() { 25 | fact[0] = 1 ; 26 | for(ll i = 1; i< mxN; i++) 27 | fact[i] = i * fact[i-1] % M ; 28 | 29 | ifact[mxN-1] = modInv(fact[mxN-1]) ; 30 | 31 | for(ll i = mxN-1 ; i>0 ; i--) 32 | ifact[i-1] = ifact[i] * i % M ; 33 | } 34 | 35 | ll nCr(ll n, ll r) { 36 | if (n < r || r < 0 || n < 0) return 0; 37 | ll res = fact[n] * ifact[r] % M * ifact[n-r] % M ; 38 | return res ; 39 | } 40 | 41 | void add(ll &a, ll b) { 42 | b %= M; 43 | a = (a + b) % M; 44 | } 45 | void mul(ll &a, ll b) { 46 | b %= M; 47 | a = (a * b) % M; 48 | } 49 | void sub(ll &a, ll b) { 50 | b %= M; 51 | a = (a - b) % M; 52 | a = (a + M) % M; 53 | } 54 | 55 | 56 | 57 | const ll N = 1e6 + 1; 58 | vector is_prime(N,1); 59 | vll prime; 60 | void sieve() 61 | { 62 | for(ll i=2; i is_prime(mxN,1); 105 | vector prime; 106 | void sieve() 107 | { 108 | is_prime[0] = 0; 109 | is_prime[1] = 0; 110 | for(int i = 2; i < mxN; i++) 111 | { 112 | if(is_prime[i]) 113 | { 114 | prime.pb(i); 115 | } 116 | for(int p: prime) 117 | { 118 | if(i*p >= mxN) break; 119 | is_prime[i*p] = 0; 120 | if(i%p == 0) break; 121 | } 122 | } 123 | } 124 | 125 | 126 | // ModInv using GCD when m is not prime but gcd(a,m) == 1 127 | ll gcdExtended(ll a, ll b, ll* x, ll* y) 128 | { 129 | if (a == 0) 130 | { 131 | *x = 0, *y = 1; 132 | return b; 133 | } 134 | 135 | // To store results of recursive call 136 | ll x1, y1; 137 | ll gcd = gcdExtended(b % a, a, &x1, &y1); 138 | 139 | // Update x and y using results of recursive call 140 | *x = y1 - (b / a) * x1; 141 | *y = x1; 142 | 143 | return gcd; 144 | } 145 | 146 | ll modInverse(ll a, ll m) 147 | { 148 | ll x, y; 149 | ll g = gcdExtended(a, m, &x, &y); 150 | 151 | // inverse doesn't exist 152 | if (g != 1) return -1; 153 | 154 | // m is added to handle negative x 155 | ll res = (x % m + m) % m; 156 | return res; 157 | } 158 | -------------------------------------------------------------------------------- /Mo's_algo.cpp: -------------------------------------------------------------------------------- 1 | ll current_answer; 2 | ll cnt[mxN]; 3 | ll BLOCK_SIZE; 4 | 5 | bool mo_cmp(pair x, pair< pll, ll> &y) 6 | { 7 | ll block_x = x.ff.ff / BLOCK_SIZE; 8 | ll block_y = y.ff.ff / BLOCK_SIZE; 9 | if(block_x != block_y) 10 | return block_x < block_y; 11 | return x.ff.ss < y.ff.ss; 12 | } 13 | 14 | void add(int x) 15 | { 16 | current_answer -= cnt[x] * cnt[x] * x; 17 | cnt[x]++; 18 | current_answer += cnt[x] * cnt[x] * x; 19 | } 20 | 21 | void remove(int x) 22 | { 23 | current_answer -= cnt[x] * cnt[x] * x; 24 | cnt[x]--; 25 | current_answer += cnt[x] * cnt[x] * x; 26 | } 27 | 28 | void MOs_algo(vll &a, vector> &queries) 29 | { 30 | ll n=a.size(), q=queries.size(); 31 | BLOCK_SIZE = sqrt(n); 32 | sort(queries.begin(), queries.end(), mo_cmp); 33 | 34 | ll answers[q]; 35 | ll mo_left = 0, mo_right = -1; 36 | rep(i,0,q) 37 | { 38 | ll left = queries[i].ff.ff; 39 | ll right = queries[i].ff.ss; 40 | 41 | while(mo_right < right) { 42 | mo_right++; 43 | add(a[mo_right]); 44 | } 45 | while(mo_right > right) { 46 | remove(a[mo_right]); 47 | mo_right--; 48 | } 49 | while(mo_left < left) { 50 | remove(a[mo_left]); 51 | mo_left++; 52 | } 53 | while(mo_left > left) { 54 | mo_left--; 55 | add(a[mo_left]); 56 | } 57 | 58 | answers[queries[i].ss] = current_answer; 59 | } 60 | 61 | rep(i,0,q) cout << answers[i] << endl; 62 | } -------------------------------------------------------------------------------- /PBDS.cpp: -------------------------------------------------------------------------------- 1 | // ordered_set - PBDS 2 | #include 3 | #include 4 | using namespace __gnu_pbds; 5 | template using ordered_set = tree, rb_tree_tag, tree_order_statistics_node_update>; 6 | template using ordered_map = tree, rb_tree_tag, tree_order_statistics_node_update>; 7 | 8 | //s.order_of_key(k) : Number of items strictly smaller than k 9 | //s.find_by_order(k) : iterator to K-th element in a set (counting from zero) 10 | //multiset : use pair 11 | 12 | 13 | 14 | //Using Fenwick Tree implementing PBDS 15 | int bit[mxN]; 16 | void update(ll x, ll val) { 17 | for (; x < mxN; x += x & -x) 18 | bit[x] += val; 19 | } 20 | 21 | ll query(ll x) { 22 | ll res = 0; 23 | for (; x > 0; x -= x & -x) 24 | res += bit[x]; 25 | return res; 26 | } 27 | 28 | ll median(ll x) 29 | { 30 | ll l=0, r=mxN-1; 31 | ll res=0; 32 | while(l<=r) 33 | { 34 | ll m=(l+r)/2; 35 | if(query(m)>=x) { res=m; r=m-1; } 36 | else l=m+1; 37 | } 38 | return res; 39 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Competitive-Programming-Templates 2 | A collection of templates for commonly used Data Structures and Algorithms that can be used during Competitive Programming to solve problems easily and quickly. 3 | 4 | # To Do List 5 | - making implementations more readable and easier to understand and use 6 | - adding more templates 7 | - giving a brief explanation of all the template files and adding sources where you can learn the dsa in the template 8 | -------------------------------------------------------------------------------- /Suffix_Array.cpp: -------------------------------------------------------------------------------- 1 | const ll K = 21; 2 | vector SA(mxN,vector(K)); 3 | vll P(K); 4 | vll Suffix_Array(string s) 5 | { 6 | ll n = s.size(); 7 | P[0] = 1; 8 | rep(i,1,K) P[i] = 2 * P[i-1]; 9 | rep(i,0,n) SA[i][0] = s[i] - 'a'; 10 | 11 | vector> v(n); 12 | rep(k,1,K) 13 | { 14 | rep(i,0,n) 15 | { 16 | v[i].ff.ff = SA[i][k-1]; 17 | v[i].ff.ss = (i + P[k-1] < n)? SA[i + P[k-1]][k-1] : -1; 18 | v[i].ss = i; 19 | } 20 | sortall(v); 21 | 22 | rep(i,0,n) 23 | { 24 | if(i > 0 && v[i].ff == v[i-1].ff) 25 | SA[v[i].ss][k] = SA[v[i-1].ss][k]; 26 | else 27 | SA[v[i].ss][k] = i; 28 | } 29 | } 30 | 31 | vll sa(n); 32 | rep(i,0,n) sa[SA[i][K-1]] = i; 33 | return sa; 34 | } 35 | 36 | // Finds Longest Common Prefix of 2 suffixes of string starting at indices i and j using Suffix Array in O(logn) time. 37 | ll LCP(ll i, ll j, ll n) 38 | { 39 | if(i == j) return n - i; 40 | ll len = 0; 41 | rrep(k,K-1,0) 42 | { 43 | if(SA[i][k] == SA[j][k]) 44 | { 45 | len += P[k]; 46 | i += P[k]; 47 | j += P[k]; 48 | } 49 | } 50 | return len; 51 | } 52 | -------------------------------------------------------------------------------- /Tree_LCA.cpp: -------------------------------------------------------------------------------- 1 | // Find Lowest Common Ancestor (LCA) of two nodes in a tree in O(logn) 2 | 3 | const ll N = 2e5; 4 | vll v[N]; 5 | ll par[N][20]; 6 | ll dep[N]; 7 | 8 | // find depth and parent of each node 9 | void dfs(ll x,ll p) 10 | { 11 | if(x==p) dep[x]=0; 12 | par[x][0]=p; 13 | for(auto i:v[x]) 14 | { 15 | if(i==p) continue; 16 | dep[i]=dep[x]+1; 17 | dfs(i,x); 18 | } 19 | } 20 | 21 | // find parents of every node at two's power 22 | void find_parent(ll n) 23 | { 24 | for(int i = 1; i < 20; i++) 25 | for(int j = 1; j <= n; j++) 26 | par[j][i] = par[par[j][i - 1]][i - 1]; 27 | } 28 | 29 | // lowest comman ancestor - binary lifting 30 | ll lca(ll u,ll v) 31 | { 32 | if(dep[u] < dep[v]) swap(u, v); 33 | 34 | for(int i = 19; i >= 0; i--) 35 | if(dep[par[u][i]] >= dep[v]) 36 | u = par[u][i]; 37 | 38 | if(u == v) return u; 39 | 40 | for(int i = 19; i >= 0; i--) 41 | if(par[u][i] != par[v][i]) 42 | u = par[u][i], v = par[v][i]; 43 | 44 | return par[u][0]; 45 | } 46 | 47 | // find distance between x and y 48 | ll dis(ll x,ll y) 49 | { 50 | ll z = lca(x,y); 51 | ll d = dep[x] + dep[y] - 2*dep[z]; 52 | return d; 53 | } 54 | 55 | -------------------------------------------------------------------------------- /Trie.cpp: -------------------------------------------------------------------------------- 1 | 2 | const int ALPHA_SIZE = 26; 3 | struct trienode 4 | { 5 | trienode* children[ALPHA_SIZE]; 6 | bool end_of_word; 7 | trienode() 8 | { 9 | end_of_word = false; 10 | for(int i=0; ichildren[index]) 23 | pcrawl->children[index] = new trienode; 24 | pcrawl = pcrawl->children[index]; 25 | } 26 | pcrawl -> end_of_word = true; 27 | } 28 | 29 | bool search(trienode* root, string key) 30 | { 31 | trienode* pcrawl = root; 32 | for(int i=0; ichildren[index]) 36 | return false; 37 | pcrawl = pcrawl->children[index]; 38 | } 39 | return pcrawl->end_of_word; 40 | } 41 | 42 | // For prefixes, don't use end_of_word -------------------------------------------------------------------------------- /Undir_Graph_Cycle_Det.cpp: -------------------------------------------------------------------------------- 1 | //directed graph cycle detection 2 | const ll N=2e5+1; 3 | vll v[N]; 4 | bool dfs(ll x, vll &vis) 5 | { 6 | vis[x]=1; 7 | bool ret=false; 8 | for(auto i:v[x]) 9 | { 10 | if(vis[i]==1) 11 | { 12 | ret=true; 13 | break; 14 | } 15 | else if(vis[i]==0) 16 | { 17 | if(dfs(i,vis)) 18 | { 19 | ret=true; 20 | break; 21 | } 22 | } 23 | } 24 | vis[x]=2; 25 | return ret; 26 | } 27 | 28 | bool cycle(ll n) 29 | { 30 | vll vis(n,0); 31 | bool ret=false; 32 | rep(i,0,n) 33 | { 34 | if(vis[i]==0) 35 | { 36 | if(dfs(i,vis)) 37 | { 38 | ret=true; 39 | break; 40 | } 41 | } 42 | } 43 | return ret; 44 | } 45 | 46 | /* 47 | Use dfs implemented above, don't use normal dfs. 48 | Normal dfs will give tle for graphs like this: 49 | 1 50 | / / \ \ 51 | 2 3 4 5 52 | \ \ / / 53 | 6 54 | 7 55 | 8 56 | 9 57 | 10 58 | */ -------------------------------------------------------------------------------- /Zarray.cpp: -------------------------------------------------------------------------------- 1 | 2 | //KMP - kmp[i] tells The longest proper prefix of pattern[0..i] which is also a suffix of pattern[0..i]. 3 | void preprocess_kmp(string &pattern, vector &kmp) 4 | { 5 | kmp[0] = 0; 6 | for (int i = 1; i < pattern.size(); i++) 7 | { 8 | kmp[i] = 0; 9 | int length = kmp[i - 1]; 10 | while ((length > 0) && (pattern[i] != pattern[length])) 11 | { 12 | length = kmp[length - 1]; 13 | } 14 | if (pattern[i] == pattern[length]) 15 | { 16 | kmp[i] = length + 1; 17 | } 18 | } 19 | } 20 | 21 | 22 | // Z array - z[i] tells max length prefix starting from i 23 | vll Zarray(string s) 24 | { 25 | ll n=s.size(); 26 | vll z(n,0); z[0]=n; 27 | ll l=1, r=1; 28 | for(ll i=1; i=r) l=i, r=i; 31 | ll x=i-l; 32 | if(i+z[x]>=r) 33 | { 34 | l=i; 35 | while(r Zarray(string s) 46 | { 47 | int n = s.size(); 48 | vector z(n,-1); 49 | int L = 0, R = 0; 50 | for(int i = 1; i < n; i++) 51 | { 52 | if(i > R) 53 | { 54 | L = R = i; 55 | while (R < n && s[R-L] == s[R]) R++; 56 | z[i] = R-L; 57 | R--; 58 | } 59 | else 60 | { 61 | int k = i-L; 62 | if(z[k] < R-i+1) z[i] = z[k]; 63 | else 64 | { 65 | L = i; 66 | while (R < n && s[R-L] == s[R]) R++; 67 | z[i] = R-L; 68 | R--; 69 | } 70 | } 71 | } 72 | return z; 73 | } 74 | -------------------------------------------------------------------------------- /dfs.cpp: -------------------------------------------------------------------------------- 1 | vll g[N] ; 2 | ll d[N] ; 3 | void dfs(ll node,ll par=-1) { 4 | for(auto i : g[node]) { 5 | if(i != par) { 6 | d[i] = d[node] + 1; 7 | dfs(i,node) ; 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /dijkstra_&_bfs.cpp: -------------------------------------------------------------------------------- 1 | //Dijkstra - O(ElogV) - Weighted Graph 2 | vpll v[mxN]; 3 | vll d(mxN,INF); 4 | void dijk(ll src) 5 | { 6 | vector vis(mxN,0); 7 | multiset s; 8 | d[src]=0; 9 | s.insert({0,src}); 10 | while(!s.empty()) 11 | { 12 | pll p=*s.begin(); 13 | s.erase(s.begin()); 14 | ll x=p.ss, wei=p.ff; 15 | if(vis[x]) continue; 16 | vis[x]=1; 17 | for(ll i=0; i vis(mxN,0); 35 | queue q; 36 | d[src]=0; 37 | q.push(src); 38 | vis[src]=1; 39 | while(!q.empty()) 40 | { 41 | ll x=q.front(); 42 | q.pop(); 43 | for(auto e:v[x]) 44 | { 45 | if(d[x]+1 0; x -= x & -x) 12 | res += bit[x]; 13 | return res; 14 | } -------------------------------------------------------------------------------- /fft_ntt.cpp: -------------------------------------------------------------------------------- 1 | 2 | // mod = 7340033 = 7*(2^20) + 1, root = 5, root_inv = 4404020, root_pw = 1 << 20, 3 | // mod = 998244353 = 7*17*(2^23) + 1, root = 3, root_inv = 332748118, root_pw = 1 << 23 4 | 5 | const ll mod = 998244353; 6 | const ll root = 3; 7 | const ll root_1 = 332748118; 8 | const ll root_pw = 1 << 23; 9 | 10 | const ll M = mod ; 11 | ll modExp(ll a, ll p) { 12 | a %= M; 13 | ll res=1; 14 | while(p > 0) { 15 | if(p & 1) res = res * a % M; 16 | a = a * a % M; 17 | p >>= 1; 18 | } 19 | return res; 20 | } 21 | ll modInv(ll a) { 22 | return modExp(a,M-2) % M ; 23 | } 24 | 25 | void fft(vector & a, bool invert) 26 | { 27 | ll n = a.size(); 28 | 29 | for (ll i = 1, j = 0; i < n; i++) 30 | { 31 | ll bit = n >> 1; 32 | for (; j & bit; bit >>= 1) 33 | j ^= bit; 34 | j ^= bit; 35 | 36 | if (i < j) 37 | swap(a[i], a[j]); 38 | } 39 | 40 | for (ll len = 2; len <= n; len <<= 1) 41 | { 42 | ll wlen = invert ? root_1 : root; 43 | for (ll i = len; i < root_pw; i <<= 1) 44 | wlen = (ll)(1LL * wlen * wlen % mod); 45 | 46 | for (ll i = 0; i < n; i += len) 47 | { 48 | ll w = 1; 49 | for (ll j = 0; j < len / 2; j++) 50 | { 51 | ll u = a[i+j], v = (ll)(1LL * a[i+j+len/2] * w % mod); 52 | a[i+j] = u + v < mod ? u + v : u + v - mod; 53 | a[i+j+len/2] = u - v >= 0 ? u - v : u - v + mod; 54 | w = (ll)(1LL * w * wlen % mod); 55 | } 56 | } 57 | } 58 | 59 | if (invert) 60 | { 61 | ll n_1 = inverse(n, mod); 62 | for (ll & x : a) 63 | x = (ll)(1LL * x * n_1 % mod); 64 | } 65 | 66 | } -------------------------------------------------------------------------------- /matrixExpo.cpp: -------------------------------------------------------------------------------- 1 | //------------------------ Un, Deux, Trois, Quatre, Cinq -----------------------// 2 | #pragma GCC target ("avx2") 3 | #pragma GCC optimize ("O3") 4 | #pragma GCC optimize ("unroll-loops") 5 | 6 | #include 7 | using namespace std; 8 | 9 | //Shorthands 10 | #define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); 11 | #define endl "\n" 12 | #define ll long long 13 | #define ld long double 14 | #define vll vector 15 | #define vv vector 16 | #define pb push_back 17 | #define lb lower_bound2 18 | #define ub upper_bound 19 | #define pll pair 20 | #define vpll vector 21 | #define ff first 22 | #define ss second 23 | #define tll tuple 24 | #define vtll vector 25 | #define mt make_tuple 26 | #define rep(i,a,b) for(ll i=a;i=b;i--) 28 | #define vect(a,n) vll a(n); rep(i,0,n) cin>>a[i]; 29 | #define all(a) a.begin(),a.end() 30 | #define sortall(a) sort(a.begin(),a.end()); 31 | #define shuf(a) shuffle(a.begin(), a.end(), default_random_engine(0)); 32 | 33 | //Debug 34 | #define printv(a) rep(i,0,a.size()) cout<(t)<<","<(t)<<","<(t)<<")"<' << #x << ':' << (x) << "\n"; 39 | #define trace2(x,y) cout<< '>' << #x << ':' << (x) << " | " << #y << ':' << (y) << "\n"; 40 | #define trace3(a,b,c) cout<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<", "<<#c<<"="<<(c)<<"\n"; 41 | #define trace4(a,b,c,d) cout<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<", "<<#c<<"="<<(c)<<", "<<#d<<"="<<(d)<<"\n"; 42 | 43 | //Constants 44 | const ll INF = 1e12; 45 | const ll MOD = 1e9 + 7; 46 | const ll mod = 998244353; 47 | const ll mxN = 1e5+1; 48 | 49 | //Input-Output File 50 | void fileio(){ 51 | #ifndef ONLINE_JUDGE 52 | freopen("input.txt", "r", stdin) ; 53 | freopen("output.txt", "w", stdout) ; 54 | #endif 55 | } 56 | //-------------------------- Six, Sept, Huit, Neuf, Dix ------------------------// 57 | 58 | const ll M=MOD; 59 | const ll N=11; 60 | void multiply(ll mat[N][N],ll res[N][N]) 61 | { 62 | ll temp[N][N]; 63 | rep(i,0,N) 64 | { 65 | rep(j,0,N) 66 | { 67 | ll c=0; 68 | rep(k,0,N) c=(c+mat[i][k]*res[k][j]%M)%M; 69 | temp[i][j]=c; 70 | } 71 | } 72 | rep(i,0,N) rep(j,0,N) res[i][j]=temp[i][j]; 73 | } 74 | void matrixExpo(ll mat[N][N], ll k) 75 | { 76 | ll res[N][N]; 77 | rep(i,0,N) 78 | { 79 | rep(j,0,N) 80 | { 81 | if(i==j) res[i][j]=1; 82 | else res[i][j]=0; 83 | } 84 | } 85 | while(k>0) 86 | { 87 | if(k&1) multiply(mat,res); 88 | k/=2; 89 | multiply(mat,mat); 90 | } 91 | rep(i,0,N) rep(j,0,N) mat[i][j]=res[i][j]; 92 | } 93 | 94 | 95 | void solve() 96 | { 97 | ll n; cin>>n; 98 | vll a(n+1); 99 | rep(i,1,n+1) cin>>a[i]; 100 | vll c(11,0); 101 | rep(i,1,n+1) c[a[i]]++; 102 | 103 | ll q; cin>>q; 104 | while(q--) 105 | { 106 | ll k,r; cin>>k>>r; 107 | map m; 108 | rep(i,0,k) 109 | { 110 | ll x; cin>>x; 111 | if(x<=n) m[x]=1; 112 | } 113 | for(auto x:m) c[a[x.ff]]--; 114 | 115 | vll dp(11,0), s(11,0); 116 | rep(i,1,11) 117 | { 118 | dp[i]=c[i]; 119 | rep(j,1,11) 120 | { 121 | if(i-j<=0) break; 122 | dp[i]+=c[j]*dp[i-j]%M; 123 | dp[i]%=M; 124 | } 125 | s[i]=(s[i-1]+dp[i])%M; 126 | } 127 | for(auto x:m) c[a[x.ff]]++; 128 | 129 | if(r<=10){ cout<> adj(N); // adjacency matrix of graph 6 | 7 | struct Edge { 8 | int w = -INF, to = -1; 9 | }; 10 | 11 | void prim() { 12 | int total_weight = 0; 13 | vector selected(n, false); 14 | vector max_e(n); 15 | max_e[0].w = 0; 16 | 17 | for (int i=0; i max_e[v].w)) 23 | v = j; 24 | } 25 | 26 | // MST doesn't exist 27 | if (max_e[v].w == INF) { 28 | cout << 0 << endl; 29 | return; 30 | } 31 | 32 | selected[v] = true; 33 | total_weight += max_e[v].w; 34 | 35 | //update min edges to other nodes 36 | for (int to = 0; to < n; ++to) { 37 | if (adj[v][to] > max_e[to].w) 38 | max_e[to] = {adj[v][to], v}; 39 | } 40 | } 41 | 42 | cout << total_weight << endl; 43 | } 44 | -------------------------------------------------------------------------------- /segment_tree.cpp: -------------------------------------------------------------------------------- 1 | //0-indexed 2 | //Segment Tree for Range sum query and point update 3 | const ll N = 2e5+1; 4 | ll seg[4*N]; 5 | void update(ll idx,ll val,ll nd=0,ll l=0,ll r=N-1) 6 | { 7 | if(l==r){ seg[nd]=val; return; } 8 | 9 | ll m=(l+r)/2; 10 | ll lnd=2*nd+1; 11 | ll rnd=2*nd+2; 12 | 13 | if(idx<=m) update(idx,val,lnd,l,m); 14 | else update(idx,val,rnd,m+1,r); 15 | 16 | seg[nd]=seg[lnd]+seg[rnd]; 17 | } 18 | ll query(ll L,ll R,ll nd=0,ll l=0,ll r=N-1) 19 | { 20 | //for min return 1e18, for max return -1e18, for sum and gcd return 0 21 | if(r=seg[rnd]) 88 | seg[nd]=seg[lnd], segi[nd]=segi[lnd]; 89 | else 90 | seg[nd]=seg[rnd], segi[nd]=segi[rnd]; 91 | } 92 | 93 | pll query(ll L,ll R,ll nd=0,ll l=0,ll r=n-1) 94 | { 95 | if(r=p2.ff) p=p1; 115 | else p=p2; 116 | return p; 117 | } 118 | } 119 | 120 | 121 | // Implementing Segment Tree using struct 122 | // 0 indexed 123 | // SEGMENT TREE FOR MAX SUFFIX AND PREFIX 124 | template 125 | struct SEGTREE { 126 | 127 | struct NODE { 128 | T sum; 129 | T pre; 130 | T suf; 131 | }; 132 | 133 | NODE merge(const NODE &A,const NODE &B) { 134 | NODE C; 135 | C.sum = A.sum + B.sum; 136 | C.pre = max(A.pre, A.sum + B.pre); 137 | C.suf = max(B.suf, B.sum + A.suf); 138 | return C; 139 | } 140 | 141 | vector t, a; 142 | int n; 143 | 144 | void init(vector A) { 145 | n = A.size(); 146 | t.resize(4 * n); 147 | for (auto it : A) 148 | a.push_back(NODE{it, it, it}); 149 | build(0, 0, n - 1); 150 | } 151 | 152 | void build(int u, int tl, int tr) { 153 | if (tl == tr) { 154 | t[u] = a[tl]; 155 | return; 156 | } 157 | int tm = (tl + tr) >> 1; 158 | build(2 * u + 1, tl, tm); 159 | build(2 * u + 2, tm + 1, tr); 160 | t[u] = merge(t[2 * u + 1], t[2 * u + 2]); 161 | } 162 | 163 | NODE query(int l, int r) { 164 | if (l > r) return NODE{0, 0, 0}; 165 | return _query(0, 0, n - 1, l, r); 166 | } 167 | 168 | NODE _query(int u, int tl, int tr, int l, int r) { 169 | if (tl == l && tr == r) 170 | return t[u]; 171 | int tm = (tl + tr) >> 1; 172 | if(r <= tm) return _query(2 * u + 1, tl, tm, l, r); 173 | else if(l > tm) return _query(2 * u + 2, tm + 1, tr, l, r); 174 | else return merge(_query(2 * u + 1, tl, tm, l, tm), _query(2 *u + 2, tm + 1, tr, tm + 1, r)); 175 | } 176 | }; 177 | 178 | 179 | // Segment Tree for finding a subsegment a[l' ... r'] with maximal sum such that l <= l' and r' <= r 180 | struct Data { 181 | ll sum, pref, suff, ans; 182 | }; 183 | vector t(mxN); 184 | 185 | Data combine(Data l, Data r) { 186 | Data res; 187 | res.sum = l.sum + r.sum; 188 | res.pref = max(l.pref, l.sum + r.pref); 189 | res.suff = max(r.suff, r.sum + l.suff); 190 | res.ans = max(max(l.ans, r.ans), l.suff + r.pref); 191 | return res; 192 | } 193 | 194 | Data make_Data(ll val) { 195 | Data res; 196 | res.sum = val; 197 | res.pref = res.suff = res.ans = max(0ll, val); 198 | return res; 199 | } 200 | 201 | void build(vll &a, ll v, ll tl, ll tr) { 202 | if (tl == tr) { 203 | t[v] = make_Data(a[tl]); 204 | } else { 205 | ll tm = (tl + tr) / 2; 206 | build(a, v*2, tl, tm); 207 | build(a, v*2+1, tm+1, tr); 208 | t[v] = combine(t[v*2], t[v*2+1]); 209 | } 210 | } 211 | 212 | void update(ll v, ll tl, ll tr, ll pos, ll new_val) { 213 | if (tl == tr) { 214 | t[v] = make_Data(new_val); 215 | } else { 216 | ll tm = (tl + tr) / 2; 217 | if (pos <= tm) 218 | update(v*2, tl, tm, pos, new_val); 219 | else 220 | update(v*2+1, tm+1, tr, pos, new_val); 221 | t[v] = combine(t[v*2], t[v*2+1]); 222 | } 223 | } 224 | 225 | Data query(ll v, ll tl, ll tr, ll l, ll r) { 226 | if (l > r) 227 | return make_Data(0); 228 | if (l == tl && r == tr) 229 | return t[v]; 230 | ll tm = (tl + tr) / 2; 231 | Data q1 = query(v*2, tl, tm, l, min(r, tm)); 232 | Data q2 = query(v*2+1, tm+1, tr, max(l, tm+1), r); 233 | return combine(q1, q2); 234 | } 235 | 236 | -------------------------------------------------------------------------------- /subset_sum.cpp: -------------------------------------------------------------------------------- 1 | // subset or subsequence with sum s possible or not 2 | // dp - O(n*sum) 3 | 4 | // recursive dp 5 | const ll S=2e5+1; 6 | const ll N=101; 7 | int dp[N][S]; 8 | int subset_sum(vll &a,ll n,ll s) 9 | { 10 | if(s==0) return 1; 11 | if(n<=0) return 0; 12 | if(dp[n][s]!=-1) return dp[n][s]; 13 | 14 | if(s &V) const { 3 | int hash = V.size(); 4 | for(auto &i : V) { 5 | hash ^= i + 0x9e3779b9 + (hash << 6) + (hash >> 2); 6 | } 7 | return hash; 8 | } 9 | }; 10 | 11 | unordered_map m; --------------------------------------------------------------------------------