├── .gitignore ├── TemplateStuff ├── BuildSystemForCPP.sublime-build ├── Int_128.cpp └── Template.cpp ├── String Algorithms ├── Prefix_Function.cpp ├── ZAlgirthm.cpp ├── Trie.cpp ├── String_Hashing.cpp └── Suffix_array.cpp ├── Graph Algorithms ├── BellmanFord.cpp ├── Dijkstra.cpp ├── UnionFind.cpp ├── FloydWarshall.cpp ├── EulerianCircuit.cpp ├── FordFulkerson_Algo.cpp ├── EdmondsKarp.cpp ├── Topological_sorting.cpp ├── Cycle_in_DAG.cpp ├── Prims.cpp ├── PrimsUpdated.cpp ├── Kruskals.cpp └── 4.KosaRaju_Algo_SCC.cpp ├── Number Theory └── MillerRabinDeterministic.cpp ├── Common Techniques ├── Fibonacci in LogN.cpp └── Distinct in Range Queries.cpp ├── Range Queries ├── Sparse_Table.cpp ├── Segment_tree.cpp ├── Lazy_SGT.cpp └── Mo_algo.cpp └── Tree Algorithms ├── Binary_Lifting.cpp ├── Centroid_Tree.cpp ├── LCA_tree.cpp ├── LCA_O_1.cpp └── HLD.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | **/.DS_Store -------------------------------------------------------------------------------- /TemplateStuff/BuildSystemForCPP.sublime-build: -------------------------------------------------------------------------------- 1 | { 2 | "cmd": ["g++.exe", 3 | "-DPriyansh31dec", 4 | "-std=c++14", "${file}", 5 | "-o", 6 | "${file_base_name}.exe", 7 | "&&", 8 | "${file_base_name}.exeOutput.txt"], 9 | "shell":true, 10 | "selector":"source.cpp" 11 | } -------------------------------------------------------------------------------- /String Algorithms/Prefix_Function.cpp: -------------------------------------------------------------------------------- 1 | vector prefix_function(string s) { 2 | int n = (int)s.length(); 3 | vector pi(n); 4 | for (int i = 1; i < n; i++) { 5 | int j = pi[i-1]; 6 | while (j > 0 && s[i] != s[j]) 7 | j = pi[j-1]; 8 | if (s[i] == s[j]) 9 | j++; 10 | pi[i] = j; 11 | } 12 | return pi; 13 | } -------------------------------------------------------------------------------- /String Algorithms/ZAlgirthm.cpp: -------------------------------------------------------------------------------- 1 | vector z_function(string s) { 2 | int n = (int) s.length(); 3 | vector z(n); 4 | for (int i = 1, l = 0, r = 0; i < n; ++i) { 5 | if (i <= r) 6 | z[i] = min (r - i + 1, z[i - l]); 7 | while (i + z[i] < n && s[z[i]] == s[i + z[i]]) 8 | ++z[i]; 9 | if (i + z[i] - 1 > r) 10 | l = i, r = i + z[i] - 1; 11 | } 12 | return z; 13 | } -------------------------------------------------------------------------------- /Graph Algorithms/BellmanFord.cpp: -------------------------------------------------------------------------------- 1 | void BellmanFord(int n, int src, vector> *edges, vector& dist, set& negCycle) { 2 | fill(all(dist), INF); 3 | dist[src] = 0; 4 | vector>> e; 5 | for (int i = 0; i < n; i++) { 6 | for (auto j : edges[i]) { 7 | e.pb({j.ss, {i, j.ff}}); 8 | } 9 | } 10 | for (int i = 0; i < n - 1; i++) { 11 | for (auto j : e) { 12 | dist[j.ss.ss] = min(dist[j.ss.ss], dist[j.ss.ff] + j.ff); 13 | } 14 | } 15 | //checking negative cycle 16 | for (int i = 0; i < n; i++) { 17 | for (auto j : e) { 18 | if (dist[j.ss.ss] > dist[j.ss.ff] + j.ff) { 19 | dist[j.ss.ss] = dist[j.ss.ff] + j.ff; 20 | negCycle.insert(j.ss.ss); 21 | } 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /Graph Algorithms/Dijkstra.cpp: -------------------------------------------------------------------------------- 1 | // O(VlogV + ElogV) 2 | // Single Source Shortest Path 3 | 4 | void Dijkstra(int s, int n, vector &dist, vector &parent, vector> *adj) { 5 | dist.assign(n, INF); 6 | parent.assign(n, -1); 7 | dist[s] = 0; 8 | priority_queue , vector>, greater>> q; 9 | q.push({0, s}); 10 | while (!q.empty()) { 11 | pair here = q.top(); 12 | q.pop(); 13 | int v = here.ss; 14 | ll d_v = here.ff; 15 | if (d_v != dist[v]) 16 | continue; 17 | for (auto edge : adj[v]) { 18 | if (dist[v] + edge.ss < dist[edge.ff]) { 19 | dist[edge.ff] = dist[v] + edge.ss; 20 | parent[edge.ff] = v; 21 | q.push({dist[edge.ff], edge.ff}); 22 | } 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /Graph Algorithms/UnionFind.cpp: -------------------------------------------------------------------------------- 1 | //Union Find Algorithm Almost O(1) for reasonable size N. O(log*N) to be precise 2 | struct UnionFind { 3 | int n; 4 | vector rank; 5 | vector parent; 6 | // store other info as required 7 | UnionFind(int n) { 8 | rank.resize(n); 9 | fill(rank.begin(), rank.end(), 0); 10 | parent.resize(n); 11 | for (int i = 0; i < n; i++) { 12 | parent[i] = i; 13 | } 14 | } 15 | int get(int a) { 16 | return parent[a] = (parent[a] == a ? a : get(parent[a])); 17 | } 18 | void merge(int a, int b) { 19 | a = get(a); 20 | b = get(b); 21 | if (a == b) { 22 | return; 23 | } 24 | if (rank[a] == rank[b]) { 25 | rank[a]++; 26 | } 27 | if (rank[a] > rank[b]) { 28 | parent[b] = a; 29 | } else { 30 | parent[a] = b; 31 | } 32 | } 33 | }; -------------------------------------------------------------------------------- /String Algorithms/Trie.cpp: -------------------------------------------------------------------------------- 1 | const int letters = 26; 2 | struct Node { 3 | vector next_node; 4 | int is_a_leaf = 0; 5 | Node() { 6 | next_node.resize(letters); 7 | fill(begin(next_node), end(next_node), -1); 8 | } 9 | }; 10 | struct Trie{ 11 | vector trie_tree; 12 | Trie(){ 13 | trie_tree.emplace_back(); 14 | } 15 | void add_string(string &a) { 16 | int root_here = 0; 17 | for(char c : a){ 18 | int index = c - 'a'; 19 | if(trie_tree[root_here].next_node[index] == -1) { 20 | trie_tree[root_here].next_node[index] = sz(trie_tree); 21 | trie_tree.emplace_back(); 22 | } 23 | root_here = trie_tree[root_here].next_node[index]; 24 | } 25 | trie_tree[root_here].is_a_leaf++; 26 | } 27 | }; 28 | Trie t = Trie(); 29 | -------------------------------------------------------------------------------- /Graph Algorithms/FloydWarshall.cpp: -------------------------------------------------------------------------------- 1 | // O(n ^ 3) 2 | // All pair shortest paths 3 | // Negative Cycle needs to be checked otherwise the answer can be very negative resulting in overflows 4 | // Maintain p[][] for getting path.Recursively find path between i and p[i][j], p[i][j] and j. 5 | 6 | void FloydWarshall(int n, vector> *adj, vector> &dist) { 7 | for (int i = 0; i < n; i++) { 8 | for (int j = 0; j < n; j++) { 9 | dist[i][j] = INF; 10 | } 11 | dist[i][i] = 0; 12 | } 13 | for (int i = 0; i < n; i++) { 14 | for (auto j : adj[i]) { 15 | dist[i][j.ff] = min(dist[i][j.ff], j.ss); 16 | } 17 | } 18 | for (int k = 0; k < n; k++) { 19 | for (int i = 0; i < n; i++) { 20 | for (int j = 0; j < n; j++) { 21 | if (dist[i][k] < INF && dist[k][j] < INF) // for updating only when there is a path 22 | dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]); 23 | } 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /Number Theory/MillerRabinDeterministic.cpp: -------------------------------------------------------------------------------- 1 | ell expo1(ell a, ell b, ell mod) { 2 | ell res = 1; 3 | while (b > 0) { 4 | if (b & 1) 5 | res = (res * a) % mod; 6 | a = (a * a) % mod; 7 | b = b >> 1; 8 | } 9 | return res; 10 | } 11 | 12 | bool check_composite(ell n, ell a, ell d, ell s) { 13 | ell x = expo1(a, d, n); 14 | if (x == 1 || x == n - 1) 15 | return false; 16 | for (int r = 1; r < s; r++) { 17 | x = (x * x) % n; 18 | if (x == n - 1) 19 | return false; 20 | } 21 | return true; 22 | }; 23 | 24 | bool MillerRabin(ell n) { // returns true if n is prime, else returns false. 25 | if (n < 2) 26 | return false; 27 | 28 | int r = 0; 29 | ll d = n - 1; 30 | while ((d & 1) == 0) { 31 | d >>= 1; 32 | r++; 33 | } 34 | 35 | for (int a : {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}) { 36 | if (n == a) 37 | return true; 38 | if (check_composite(n, a, d, r)) 39 | return false; 40 | } 41 | return true; 42 | } -------------------------------------------------------------------------------- /TemplateStuff/Int_128.cpp: -------------------------------------------------------------------------------- 1 | // int128 bit for numbers larger than 1e18. Will support numbers till 1e36 2 | // Comment out everything related to PBDS while using this 3 | // Put all the code in the same order 4 | 5 | 6 | // Typedef to ell 7 | typedef __int128 ell; 8 | 9 | // For printing 10 | std::ostream& 11 | operator<<( std::ostream& dest, __int128_t value ) { 12 | std::ostream::sentry s( dest ); 13 | if ( s ) { 14 | __uint128_t tmp = value < 0 ? -value : value; char buffer[ 128 ]; 15 | char* d = std::end( buffer ); 16 | do { -- d; *d = "0123456789"[ tmp % 10 ]; tmp /= 10;} while ( tmp != 0 ); 17 | if ( value < 0 ) {-- d; *d = '-';} 18 | int len = std::end( buffer ) - d; 19 | if ( dest.rdbuf()->sputn( d, len ) != len ) {dest.setstate( std::ios_base::badbit );} 20 | } 21 | return dest; 22 | } 23 | 24 | // For reading _int128 to_read = read() 25 | __int128 read() { 26 | __int128 x = 0, f = 1; 27 | char ch = getchar(); 28 | while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();} 29 | while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();} 30 | return x * f; 31 | } 32 | 33 | // For debugging 34 | void _print(ell t) {cerr << t;} 35 | -------------------------------------------------------------------------------- /Common Techniques/Fibonacci in LogN.cpp: -------------------------------------------------------------------------------- 1 | vector> identityMatrix({ 2 | {1, 0}, 3 | {0, 1} 4 | }); 5 | vector> result({ 6 | {0, 0}, 7 | {0, 0} 8 | }); 9 | void multiply(vector> a, vector> b){ 10 | for(auto &i : result){ 11 | for(auto &j : i){ 12 | j = 0; 13 | } 14 | } 15 | for(int i = 0; i < 2; i++){ 16 | for(int j = 0; j < 2; j++){ 17 | for(int k = 0; k < 2; k++){ 18 | result[i][k] += a[i][j] * b[j][k]; 19 | result[i][k] %= MOD; 20 | } 21 | } 22 | } 23 | } 24 | void matrixExpo(vector> matrix, ll n){ 25 | if(n == 0){ 26 | result = identityMatrix; 27 | return; 28 | } 29 | matrixExpo(matrix, n / 2); 30 | multiply(result, result); 31 | if(n & 1){ 32 | multiply(result, matrix); 33 | } 34 | } 35 | ll nthFibonacciNumber(ll n){ // n <= 1e18, F0 = 0, F1 = 1, F2 = 1 36 | if(n <= 1) 37 | return n; 38 | vector> baseMatrix({ 39 | {1, 1}, 40 | {1, 0} 41 | }); 42 | multiply(baseMatrix, identityMatrix); 43 | matrixExpo(baseMatrix, n - 1); 44 | return result[0][0]; 45 | } -------------------------------------------------------------------------------- /Graph Algorithms/EulerianCircuit.cpp: -------------------------------------------------------------------------------- 1 | void dfs(int root, set>* edges, vector& path){ 2 | while(sz(edges[root])){ 3 | pair p = *edges[root].begin(); 4 | edges[root].erase(p); 5 | edges[p.ff].erase({root, p.ss}); 6 | dfs(p.ff, edges, path); 7 | } 8 | path.pb(root); 9 | } 10 | vector> EulerCircuits(int n, vector* edges){ 11 | // when sending an undirected graph don't add the edges in the edgesVector on both sides 12 | // for undirected graph 13 | // modify it for directed graph by starting at node with outdegree odd and ending at indegree odd 14 | // undirected -> circuit - all even, path - 2 odd 15 | // directed -> circuit -> all even, path - 1 out > in, 1 in > out 16 | vector> circuits; 17 | int counter = 0; 18 | set> *newEdges = new set>[n]; 19 | for(int i = 0; i < n; i++){ 20 | for(auto j : edges[i]){ 21 | newEdges[i].insert({j, counter}); 22 | newEdges[j].insert({i, counter}); 23 | counter++; 24 | } 25 | } 26 | for(int i = 0; i < n; i++){ 27 | if(sz(newEdges[i]) & 1) 28 | return circuits; 29 | } 30 | for(int i = 0; i < n; i++){ 31 | if(sz(newEdges[i])){ 32 | vector path; 33 | dfs(i, newEdges, path); 34 | circuits.pb(path); 35 | } 36 | } 37 | return circuits; 38 | } 39 | -------------------------------------------------------------------------------- /Range Queries/Sparse_Table.cpp: -------------------------------------------------------------------------------- 1 | // O(1) for idempotent O(logN) for general 2 | // Supports multiple sparse tables with minor change in Node 3 | 4 | template 5 | struct SparseTable { 6 | vector> table; 7 | vector logValues; 8 | int n; 9 | int maxLog; 10 | vector a; 11 | SparseTable(int n1, vector &arr) { 12 | n = n1; 13 | a = arr; 14 | table.resize(n); 15 | logValues.resize(n + 1); 16 | maxLog = log2(n); 17 | logValues[1] = 0; 18 | for (int i = 2; i <= n; i++) { 19 | logValues[i] = logValues[i / 2] + 1; 20 | } 21 | for (int i = 0; i < n; i++) { 22 | table[i].resize(maxLog + 1); 23 | fill(all(table[i]), Node()); 24 | } 25 | build(); 26 | } 27 | void build() { 28 | for (int i = 0; i < n; i++) { 29 | table[i][0] = Node(a[i]); 30 | } 31 | for (int i = 1; i <= maxLog; i++) { 32 | for (int j = 0; (j + (1 << i)) <= n; j++) { 33 | table[j][i].merge(table[j][i - 1], table[j + (1 << (i - 1))][i - 1]); 34 | } 35 | } 36 | } 37 | Node queryNormal(int left, int right) { 38 | Node ans = Node(); 39 | for (int j = logValues[right - left + 1]; j >= 0; j--) { 40 | if ((1 << j) <= right - left + 1) { 41 | ans.merge(ans, table[left][j]); 42 | left += (1 << j); 43 | } 44 | } 45 | return ans; 46 | } 47 | Node queryIdempotent(int left, int right) { 48 | int j = logValues[right - left + 1]; 49 | Node ans = Node(); 50 | ans.merge(table[left][j], table[right - (1 << j) + 1][j]); 51 | return ans; 52 | } 53 | }; 54 | struct Node1 { 55 | ll val; // store more info if required 56 | Node1() { // Identity Element 57 | val = 0; 58 | } 59 | Node1(ll v) { 60 | val = v; 61 | } 62 | void merge(Node1 &l, Node1 &r) { 63 | val = l.val ^ r.val; 64 | } 65 | }; -------------------------------------------------------------------------------- /Tree Algorithms/Binary_Lifting.cpp: -------------------------------------------------------------------------------- 1 | struct BinaryLifting { 2 | int n; 3 | int maxLog; 4 | ll maxRequirement; 5 | vector> parent; 6 | BinaryLifting(int n1, vector *edges, ll requirement, int root) { 7 | n = n1; 8 | parent.resize(n1); 9 | maxLog = log2(requirement + 1); 10 | maxRequirement = requirement; 11 | for (int i = 0; i < n; i++) { 12 | parent[i].resize(maxLog + 1); 13 | for (int j = 0; j <= maxLog; j++) { 14 | parent[i][j] = -1; 15 | } 16 | } 17 | fillParentTable(root, edges); 18 | } 19 | void fillParentTable(int root, vector *edges) { 20 | vector visited(n); 21 | dfsBinaryLifting(root, edges, visited); 22 | int intermediate = -1; 23 | for (int i = 1; i <= maxLog; i++) { 24 | for (int j = 0; j < n; j++) { 25 | intermediate = parent[j][i - 1]; 26 | if (intermediate != -1) { 27 | parent[j][i] = parent[intermediate][i - 1]; 28 | } 29 | } 30 | } 31 | } 32 | void dfsBinaryLifting(int root, vector *edges, vector &visited) { 33 | visited[root] = true; 34 | for (auto i : edges[root]) { 35 | if (!visited[i]) { 36 | parent[i][0] = root; 37 | dfsBinaryLifting(i, edges, visited); 38 | } 39 | } 40 | } 41 | int kthParent(int x, int k) { 42 | for(int i = 0; i <= maxLog; i++){ 43 | if((k >> i) & 1){ 44 | if(x == -1) 45 | return x; 46 | x = parent[x][i]; 47 | } 48 | } 49 | return x; 50 | } 51 | }; -------------------------------------------------------------------------------- /Common Techniques/Distinct in Range Queries.cpp: -------------------------------------------------------------------------------- 1 | bool compare(pair, int>& a, pair, int>& b){ 2 | return a.ff.ss < b.ff.ss; 3 | } 4 | void update(int index, vector& bit, int value){ 5 | for(; index < sz(bit); index += (index & (-index))){ 6 | bit[index] += value; 7 | } 8 | } 9 | int query(int index, vector& bit){ 10 | int sum = 0; 11 | for(; index > 0; index -= (index & (-index))){ 12 | sum += bit[index]; 13 | } 14 | return sum; 15 | } 16 | vector distinctQueries(int n, int q, vector& arr, vector>& queries){ 17 | map compression; 18 | int prev = 0; 19 | for(auto &i : arr){ 20 | if(compression.find(i) == compression.end()){ 21 | compression[i] = prev; 22 | prev++; 23 | } 24 | i = compression[i]; 25 | } 26 | vector lastIndex(sz(compression), -1); 27 | vector, int>> tempQueries(q); 28 | for(int i = 0; i < q; i++){ 29 | tempQueries[i].ff.ff = queries[i].ff + 1; 30 | tempQueries[i].ff.ss = queries[i].ss + 1; 31 | tempQueries[i].ss = i; 32 | } 33 | vector ans(q); 34 | sort(all(tempQueries), compare); 35 | int num = 0; 36 | vector bit(n + 1); 37 | for(int i = 0; i < n; i++){ 38 | if(lastIndex[arr[i]] != -1){ 39 | update(lastIndex[arr[i]] + 1, bit, -1); 40 | } 41 | lastIndex[arr[i]] = i; 42 | update(i + 1, bit, 1); 43 | while(num < q && tempQueries[num].ff.ss == i + 1){ 44 | int index = tempQueries[num].ss; 45 | ans[index] = query(i + 1, bit) - query(tempQueries[num].ff.ff - 1, bit); 46 | num++; 47 | } 48 | } 49 | return ans; 50 | } -------------------------------------------------------------------------------- /String Algorithms/String_Hashing.cpp: -------------------------------------------------------------------------------- 1 | struct Hashing{ 2 | string s; 3 | int n; 4 | int primes; 5 | vector hashPrimes = {1000000009, 100000007}; 6 | const ll base = 31; 7 | vector> hashValues; 8 | vector> powersOfBase; 9 | vector> inversePowersOfBase; 10 | Hashing(string a){ 11 | primes = sz(hashPrimes); 12 | hashValues.resize(primes); 13 | powersOfBase.resize(primes); 14 | inversePowersOfBase.resize(primes); 15 | s = a; 16 | n = s.length(); 17 | for(int i = 0; i < sz(hashPrimes); i++) { 18 | powersOfBase[i].resize(n + 1); 19 | inversePowersOfBase[i].resize(n + 1); 20 | powersOfBase[i][0] = 1; 21 | for(int j = 1; j <= n; j++){ 22 | powersOfBase[i][j] = (base * powersOfBase[i][j - 1]) % hashPrimes[i]; 23 | } 24 | inversePowersOfBase[i][n] = mminvprime(powersOfBase[i][n], hashPrimes[i]); 25 | for(int j = n - 1; j >= 0; j--){ 26 | inversePowersOfBase[i][j] = mod_mul(inversePowersOfBase[i][j + 1], base, hashPrimes[i]); 27 | } 28 | } 29 | for(int i = 0; i < sz(hashPrimes); i++) { 30 | hashValues[i].resize(n); 31 | for(int j = 0; j < n; j++){ 32 | hashValues[i][j] = ((s[j] - 'a' + 1LL) * powersOfBase[i][j]) % hashPrimes[i]; 33 | hashValues[i][j] = (hashValues[i][j] + (j > 0 ? hashValues[i][j - 1] : 0LL)) % hashPrimes[i]; 34 | } 35 | } 36 | } 37 | vector substringHash(int l, int r){ 38 | vector hash(primes); 39 | for(int i = 0; i < primes; i++){ 40 | ll val1 = hashValues[i][r]; 41 | ll val2 = l > 0 ? hashValues[i][l - 1] : 0LL; 42 | hash[i] = mod_mul(mod_sub(val1, val2, hashPrimes[i]), inversePowersOfBase[i][l], hashPrimes[i]); 43 | } 44 | return hash; 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /Tree Algorithms/Centroid_Tree.cpp: -------------------------------------------------------------------------------- 1 | vector> edgeList; 2 | vector deleted; 3 | vector subtree; 4 | inline int getD(int index, int s){ 5 | return edgeList[index].ff ^ edgeList[index].ss ^ s; 6 | } 7 | void computeSubtrees(int root, vector* edges, int parent){ 8 | subtree[root] = 1; 9 | for(auto i : edges[root]){ 10 | int dest = getD(i, root); 11 | if(!deleted[i] && dest != parent){ 12 | computeSubtrees(dest, edges, root); 13 | subtree[root] += subtree[dest]; 14 | } 15 | } 16 | } 17 | int findCentroid(int root, vector* edges, int n, int parent){ 18 | for(auto i : edges[root]){ 19 | int dest = getD(i, root); 20 | if(!deleted[i] && dest != parent && subtree[dest] > n / 2){ 21 | return findCentroid(dest, edges, n, root); 22 | } 23 | } 24 | return root; 25 | } 26 | int decompose(int root, vector* edges, vector* edgesN, int parent){ 27 | computeSubtrees(root, edges, -1); 28 | int n = subtree[root]; 29 | root = findCentroid(root, edges, n, -1); 30 | if(parent != -1){ 31 | edgesN[root].pb(parent); 32 | edgesN[parent].pb(root); 33 | } 34 | for(auto i : edges[root]){ 35 | int dest = getD(i, root); 36 | if(deleted[i]) 37 | continue; 38 | deleted[i] = true; 39 | decompose(dest, edges, edgesN, root); 40 | } 41 | return root; 42 | } 43 | void solve() { 44 | int n; 45 | cin >> n; 46 | edgeList.clear(); 47 | deleted.clear(); 48 | vector* edges= new vector[n]; 49 | for(int i = 0; i < n - 1; i++){ 50 | int a, b; 51 | cin >> a >> b; 52 | a--, b--; 53 | edges[a].pb(sz(edgeList)); 54 | edges[b].pb(sz(edgeList)); 55 | edgeList.pb({a, b}); 56 | deleted.pb(0); 57 | } 58 | vector* edgesN = new vector[n]; 59 | subtree.resize(n); 60 | fill(all(subtree), 0); 61 | int root = 0; 62 | root = decompose(root, edges, edgesN, -1); 63 | } -------------------------------------------------------------------------------- /Graph Algorithms/FordFulkerson_Algo.cpp: -------------------------------------------------------------------------------- 1 | struct Edge{ 2 | int index; 3 | int src, dest; 4 | ll val; 5 | int residualIndex; 6 | }; 7 | struct Flow{ 8 | int n; 9 | int src, dest; 10 | int iteration = 0; 11 | vector edgesT; 12 | vector> edges; 13 | vector visited; 14 | bool solved; 15 | ll flow; 16 | Flow(vector>* edges1, int n1, int s, int d){ 17 | n = n1, src = s, dest = d; 18 | solved = false; 19 | flow = 0, iteration = 1; 20 | visited.resize(n); 21 | fill(all(visited), 0); 22 | edges.resize(n); 23 | for(int i = 0; i < n; i++){ 24 | for(auto j : edges1[i]){ 25 | Edge e1 = {sz(edgesT), i, j.ff, j.ss, sz(edgesT) + 1}; 26 | Edge e2 = {sz(edgesT) + 1, j.ff, i, 0, sz(edgesT)}; 27 | edgesT.pb(e1); 28 | edgesT.pb(e2); 29 | edges[i].pb(e1.index); 30 | edges[j.ff].pb(e2.index); 31 | } 32 | } 33 | } 34 | ll dfs(int root, ll currValue){ 35 | visited[root] = iteration; 36 | if(root == dest){ 37 | return currValue; 38 | } 39 | for(auto i : edges[root]){ 40 | Edge e1 = edgesT[i]; 41 | Edge e2 = edgesT[e1.residualIndex]; 42 | if(visited[e1.dest] != iteration && e1.val > 0){ 43 | ll val = dfs(e1.dest, min(e1.val, currValue)); 44 | if(val > 0){ 45 | e1.val -= val; 46 | e2.val += val; 47 | edgesT[i] = e1; 48 | edgesT[e1.residualIndex] = e2; 49 | return val; 50 | } 51 | } 52 | } 53 | return 0; 54 | 55 | } 56 | void FordFulkersonFlow(){ 57 | while(true){ // random shuffle before every iteration to tackle specially constructed cases 58 | ll f = dfs(src, INF); 59 | if(f == 0) 60 | return; 61 | flow += f; 62 | iteration++; 63 | } 64 | } 65 | ll maxFlow(){ 66 | if(!solved){ 67 | solved = true; 68 | FordFulkersonFlow(); 69 | } 70 | return flow; 71 | } 72 | }; -------------------------------------------------------------------------------- /Graph Algorithms/EdmondsKarp.cpp: -------------------------------------------------------------------------------- 1 | struct Edge{ 2 | int index; 3 | int src, dest; 4 | ll val; 5 | int residualIndex; 6 | }; 7 | struct Flow{ 8 | int n; 9 | int src, dest; 10 | int iteration = 0; 11 | vector edgesT; 12 | vector> edges; 13 | vector visited; 14 | bool solved; 15 | ll flow; 16 | Flow(vector>* edges1, int n1, int s, int d){ 17 | n = n1, src = s, dest = d; 18 | solved = false; 19 | flow = 0, iteration = 1; 20 | visited.resize(n); 21 | fill(all(visited), 0); 22 | edges.resize(n); 23 | for(int i = 0; i < n; i++){ 24 | for(auto j : edges1[i]){ 25 | Edge e1 = {sz(edgesT), i, j.ff, j.ss, sz(edgesT) + 1}; 26 | Edge e2 = {sz(edgesT) + 1, j.ff, i, 0, sz(edgesT)}; 27 | edgesT.pb(e1); 28 | edgesT.pb(e2); 29 | edges[i].pb(e1.index); 30 | edges[j.ff].pb(e2.index); 31 | } 32 | } 33 | } 34 | ll bfs(int root){ 35 | queue qu; 36 | qu.push(root); 37 | visited[root] = iteration; 38 | vector prev(n, -1); 39 | while(!qu.empty()){ 40 | int node = qu.front(); 41 | qu.pop(); 42 | if(node == dest) 43 | break; 44 | for(auto i : edges[node]){ 45 | Edge e1 = edgesT[i]; 46 | if(visited[e1.dest] != iteration && e1.val > 0){ 47 | visited[e1.dest] = iteration; 48 | prev[e1.dest] = e1.index; 49 | qu.push(e1.dest); 50 | } 51 | } 52 | } 53 | int currNode = dest; 54 | if(prev[currNode] == -1) 55 | return 0; 56 | ll finalValue = INF; 57 | while(prev[currNode] != -1){ 58 | Edge e1 = edgesT[prev[currNode]]; 59 | finalValue = min(finalValue, e1.val); 60 | currNode = e1.src; 61 | } 62 | currNode = dest; 63 | while(prev[currNode] != -1){ 64 | Edge e1 = edgesT[prev[currNode]]; 65 | e1.val -= finalValue; 66 | edgesT[e1.index] = e1; 67 | edgesT[e1.residualIndex].val += finalValue; 68 | currNode = e1.src; 69 | } 70 | return finalValue; 71 | } 72 | void EdmondsKarp(){ 73 | while(true){ 74 | ll f = bfs(src); 75 | if(f == 0) 76 | return; 77 | flow += f; 78 | iteration++; 79 | } 80 | } 81 | ll maxFlow(){ 82 | if(!solved){ 83 | solved = true; 84 | EdmondsKarp(); 85 | } 86 | return flow; 87 | } 88 | }; -------------------------------------------------------------------------------- /Range Queries/Segment_tree.cpp: -------------------------------------------------------------------------------- 1 | // Credits to HealthyUG for the inspiration. 2 | // Segment Tree with Point Updates and Range Queries 3 | // Supports multiple Segment Trees with just a change in the Node and Update 4 | // Very few changes required everytime 5 | 6 | template 7 | struct SegTree { 8 | vector tree; 9 | vector arr; // type may change 10 | int n; 11 | int s; 12 | SegTree(int a_len, vector &a) { // change if type updated 13 | arr = a; 14 | n = a_len; 15 | s = 1; 16 | while(s < 2 * n){ 17 | s = s << 1; 18 | } 19 | tree.resize(s); fill(all(tree), Node()); 20 | build(0, n - 1, 1); 21 | } 22 | void build(int start, int end, int index) // Never change this 23 | { 24 | if (start == end) { 25 | tree[index] = Node(arr[start]); 26 | return; 27 | } 28 | int mid = (start + end) / 2; 29 | build(start, mid, 2 * index); 30 | build(mid + 1, end, 2 * index + 1); 31 | tree[index].merge(tree[2 * index], tree[2 * index + 1]); 32 | } 33 | void update(int start, int end, int index, int query_index, Update &u) // Never Change this 34 | { 35 | if (start == end) { 36 | u.apply(tree[index]); 37 | return; 38 | } 39 | int mid = (start + end) / 2; 40 | if (mid >= query_index) 41 | update(start, mid, 2 * index, query_index, u); 42 | else 43 | update(mid + 1, end, 2 * index + 1, query_index, u); 44 | tree[index].merge(tree[2 * index], tree[2 * index + 1]); 45 | } 46 | Node query(int start, int end, int index, int left, int right) { // Never change this 47 | if (start > right || end < left) 48 | return Node(); 49 | if (start >= left && end <= right) 50 | return tree[index]; 51 | int mid = (start + end) / 2; 52 | Node l, r, ans; 53 | l = query(start, mid, 2 * index, left, right); 54 | r = query(mid + 1, end, 2 * index + 1, left, right); 55 | ans.merge(l, r); 56 | return ans; 57 | } 58 | void make_update(int index, ll val) { // pass in as many parameters as required 59 | Update new_update = Update(val); // may change 60 | update(0, n - 1, 1, index, new_update); 61 | } 62 | Node make_query(int left, int right) { 63 | return query(0, n - 1, 1, left, right); 64 | } 65 | }; 66 | 67 | struct Node1 { 68 | ll val; // may change 69 | Node1() { // Identity element 70 | val = 0; // may change 71 | } 72 | Node1(ll p1) { // Actual Node 73 | val = p1; // may change 74 | } 75 | void merge(Node1 &l, Node1 &r) { // Merge two child nodes 76 | val = l.val ^ r.val; // may change 77 | } 78 | }; 79 | 80 | struct Update1 { 81 | ll val; // may change 82 | Update1(ll p1) { // Actual Update 83 | val = p1; // may change 84 | } 85 | void apply(Node1 &a) { // apply update to given node 86 | a.val = val; // may change 87 | } 88 | }; 89 | 90 | -------------------------------------------------------------------------------- /Tree Algorithms/LCA_tree.cpp: -------------------------------------------------------------------------------- 1 | struct BinaryLifting { 2 | int n; 3 | int maxLog; 4 | ll maxRequirement; 5 | vector> parent; 6 | vector logValues; 7 | bool precomputedLogs = false; 8 | BinaryLifting(int n1, vector *edges, ll requirement, int root) { 9 | n = n1; 10 | parent.resize(n); 11 | maxLog = log2(requirement + 1); 12 | maxRequirement = requirement; 13 | for (int i = 0; i < n; i++) { 14 | parent[i].resize(maxLog + 1); 15 | for (int j = 0; j <= maxLog; j++) { 16 | parent[i][j] = -1; 17 | } 18 | } 19 | fillParentTable(root, edges); 20 | if (maxRequirement <= 1000000LL) 21 | precomputeLogs(); 22 | } 23 | void fillParentTable(int root, vector *edges) { 24 | vector visited(n); 25 | dfsBinaryLifting(root, edges, visited); 26 | int intermediate = -1; 27 | for (int i = 1; i <= maxLog; i++) { 28 | for (int j = 0; j < n; j++) { 29 | intermediate = parent[j][i - 1]; 30 | if (intermediate != -1) { 31 | parent[j][i] = parent[intermediate][i - 1]; 32 | } 33 | } 34 | } 35 | } 36 | void dfsBinaryLifting(int root, vector *edges, vector &visited) { 37 | visited[root] = true; 38 | for (auto i : edges[root]) { 39 | if (!visited[i]) { 40 | parent[i][0] = root; 41 | dfsBinaryLifting(i, edges, visited); 42 | } 43 | } 44 | } 45 | void precomputeLogs() { 46 | precomputedLogs = true; 47 | logValues.resize(maxRequirement + 1); 48 | logValues[1] = 0; 49 | for (int i = 2; i <= maxRequirement; i++) { 50 | logValues[i] = logValues[i / 2] + 1; 51 | } 52 | } 53 | int kthParent(int start, int k) { 54 | int a = start; 55 | while (k > 0) { 56 | int x = getLog(k); 57 | a = parent[a][x]; 58 | if (a == -1) 59 | return a; 60 | k -= (1 << x); 61 | } 62 | return a; 63 | } 64 | inline int getLog(ll x) { 65 | return precomputedLogs ? logValues[x] : log2(x); 66 | } 67 | }; 68 | 69 | struct LCA { 70 | int n; 71 | vector level; 72 | LCA(int n1, vector *edges, int root) { 73 | n = n1; 74 | level.resize(n); 75 | dfsLCA(root, edges, -1); 76 | } 77 | void dfsLCA(int root, vector *edges, int parent) { 78 | for (auto i : edges[root]) { 79 | if (i != parent) { 80 | level[i] = level[root] + 1; 81 | dfsLCA(i, edges, root); 82 | } 83 | } 84 | } 85 | int getLCA(int a, int b, BinaryLifting &bl_object) { 86 | if (level[a] > level[b]) { 87 | swap(a, b); 88 | } 89 | b = bl_object.kthParent(b, level[b] - level[a]); 90 | if (a == b) 91 | return a; 92 | for (int i = bl_object.maxLog; i >= 0; i--) { 93 | int parent1 = bl_object.parent[a][i]; 94 | int parent2 = bl_object.parent[b][i]; 95 | if (parent2 != parent1 && parent1 != -1 && parent2 != -1) { 96 | a = parent1; 97 | b = parent2; 98 | } 99 | } 100 | return bl_object.parent[a][0]; 101 | } 102 | }; -------------------------------------------------------------------------------- /Graph Algorithms/Topological_sorting.cpp: -------------------------------------------------------------------------------- 1 | /* Priyansh Agarwal*/ 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 | #define fastio() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL) 14 | #define MOD 1000000007 15 | #define MOD1 998244353 16 | #define nline "\n" 17 | #define pb push_back 18 | #define mp make_pair 19 | #define ff first 20 | #define ss second 21 | #define PI 3.141592653589793238462 22 | #define debug(x) cout << #x << " " << x < a) {return gcd(b, a);} if (b == 0) {return a;} return gcd(b, a % b);} 29 | ll expo(ll a, ll b, ll mod) {ll res = 1; while (b > 0) {if (b & 1)res = (res * a) % mod; a = (a * a) % mod; b = b >> 1;} return res;} 30 | void extendgcd(ll a, ll b, ll*v) {if (b == 0) {v[0] = 1; v[1] = 0; v[2] = a; return ;} extendgcd(b, a % b, v); ll x = v[1]; v[1] = v[0] - v[1] * (a / b); v[0] = x; return;} //pass an arry of size 3 31 | ll mminv(ll a, ll b) {ll arr[3]; extendgcd(a, b, arr); return arr[0];} //for non prime b 32 | ll mminvprime(ll a, ll b) {return expo(a, b - 2, b);} 33 | bool revsort(ll a, ll b) {return a > b;} 34 | void swap(int &x, int &y) {int temp = x; x = y; y = temp;} 35 | ll combination(ll n, ll r, ll m, ll* fact) {ll val1 = fact[n]; ll val2 = mminvprime(fact[r], m); ll val3 = mminvprime(fact[n - r], m); return ((val1 * val2) % m * val3) % m;} 36 | void google(int t) {cout << "Case #" << t << ": ";} 37 | /*--------------------------------------------------------------------------------------------------------------------------*/ 38 | void dfs(int start, vector*edges, bool *visited, vector& ans) 39 | { 40 | visited[start] = true; 41 | for (auto i : edges[start]) 42 | { 43 | if (visited[i]) 44 | continue; 45 | dfs(i, edges, visited, ans); 46 | } 47 | ans.pb(start); 48 | } 49 | vector topo_sort(int n, vector*edges) 50 | { 51 | vector v1; 52 | bool *visited = new bool[n](); 53 | for (int i = 0; i < n; i++) 54 | { 55 | if (visited[i]) 56 | continue; 57 | dfs(i, edges, visited, v1); 58 | } 59 | reverse(v1.begin(), v1.end()); 60 | return v1; 61 | } 62 | int main() 63 | { 64 | fastio(); 65 | #ifndef ONLINE_JUDGE 66 | freopen("Input.txt", "r", stdin); 67 | freopen("Output.txt", "w", stdout); 68 | freopen("Error.txt", "w", stderr); 69 | #endif 70 | int n, m; 71 | cin >> n >> m; 72 | vector*edges = new vector[n]; 73 | for (int i = 0; i < m; i++) 74 | { 75 | int u, v; 76 | cin >> u >> v; 77 | u--; 78 | v--; 79 | edges[u].pb(v); 80 | } 81 | vector v1 = topo_sort(n, edges); 82 | for (int i = 0; i < n; i++) 83 | cout << v1[i] + 1 << " "; 84 | cout << endl; 85 | return 0; 86 | } -------------------------------------------------------------------------------- /Graph Algorithms/Cycle_in_DAG.cpp: -------------------------------------------------------------------------------- 1 | /* Priyansh Agarwal*/ 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 | #define fastio() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL) 14 | #define MOD 1000000007 15 | #define MOD1 998244353 16 | #define nline "\n" 17 | #define pb push_back 18 | #define mp make_pair 19 | #define ff first 20 | #define ss second 21 | #define PI 3.141592653589793238462 22 | #define debug(x) cout << #x << " " << x < a) {return gcd(b, a);} if (b == 0) {return a;} return gcd(b, a % b);} 29 | ll expo(ll a, ll b, ll mod) {ll res = 1; while (b > 0) {if (b & 1)res = (res * a) % mod; a = (a * a) % mod; b = b >> 1;} return res;} 30 | void extendgcd(ll a, ll b, ll*v) {if (b == 0) {v[0] = 1; v[1] = 0; v[2] = a; return ;} extendgcd(b, a % b, v); ll x = v[1]; v[1] = v[0] - v[1] * (a / b); v[0] = x; return;} //pass an arry of size 3 31 | ll mminv(ll a, ll b) {ll arr[3]; extendgcd(a, b, arr); return arr[0];} //for non prime b 32 | ll mminvprime(ll a, ll b) {return expo(a, b - 2, b);} 33 | bool revsort(ll a, ll b) {return a > b;} 34 | void swap(int &x, int &y) {int temp = x; x = y; y = temp;} 35 | ll combination(ll n, ll r, ll m, ll* fact) {ll val1 = fact[n]; ll val2 = mminvprime(fact[r], m); ll val3 = mminvprime(fact[n - r], m); return ((val1 * val2) % m * val3) % m;} 36 | void google(int t) {cout << "Case #" << t << ": ";} 37 | /*--------------------------------------------------------------------------------------------------------------------------*/ 38 | bool dfs(int start, vector*edges, bool *w, bool *g, bool *b) 39 | { 40 | w[start] = false; 41 | g[start] = true; 42 | for (auto i : edges[start]) 43 | { 44 | if (g[i]) 45 | return false; 46 | if (w[i]) 47 | { 48 | bool ans = dfs(i, edges, w, g, b); 49 | if (!ans) 50 | return false; 51 | } 52 | } 53 | g[start] = false; 54 | b[start] = true; 55 | return true; 56 | } 57 | bool check_cycle(int n, vector*edges) 58 | { 59 | bool *white = new bool[n](); 60 | bool *grey = new bool[n](); 61 | bool *black = new bool[n](); 62 | for (int i = 0; i < n; i++) 63 | white[i] = true; 64 | for (int i = 0; i < n; i++) 65 | { 66 | if (white[i]) 67 | { 68 | bool ans = dfs(i, edges, white, grey, black); 69 | if (!ans) 70 | return true; 71 | } 72 | } 73 | return false; 74 | } 75 | int main() 76 | { 77 | fastio(); 78 | #ifndef ONLINE_JUDGE 79 | freopen("Input.txt", "r", stdin); 80 | freopen("Output.txt", "w", stdout); 81 | freopen("Error.txt", "w", stderr); 82 | #endif 83 | int n, m; 84 | cin >> n >> m; 85 | vector*edges = new vector[n]; 86 | for (int i = 0; i < m; i++) 87 | { 88 | int u, v; 89 | cin >> u >> v; 90 | u--; 91 | v--; 92 | edges[u].pb(v); 93 | } 94 | bool check = check_cycle(n, edges); 95 | if (check) 96 | cout << "IMPOSSIBLE" << endl; 97 | return 0; 98 | } 99 | -------------------------------------------------------------------------------- /Tree Algorithms/LCA_O_1.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct SparseTable { 3 | vector> table; 4 | vector logValues; 5 | int n; 6 | int maxLog; 7 | vector a; 8 | SparseTable(int n1, vector &arr) { 9 | n = n1; 10 | a = arr; 11 | table.resize(n); 12 | logValues.resize(n + 1); 13 | maxLog = log2(n); 14 | logValues[1] = 0; 15 | for (int i = 2; i <= n; i++) { 16 | logValues[i] = logValues[i / 2] + 1; 17 | } 18 | for (int i = 0; i < n; i++) { 19 | table[i].resize(maxLog + 1); 20 | fill(all(table[i]), Node()); 21 | } 22 | build(); 23 | } 24 | void build() { 25 | for (int i = 0; i < n; i++) { 26 | table[i][0] = Node(a[i], i); 27 | } 28 | for (int i = 1; i <= maxLog; i++) { 29 | for (int j = 0; (j + (1 << i)) <= n; j++) { 30 | table[j][i].merge(table[j][i - 1], table[j + (1 << (i - 1))][i - 1]); 31 | } 32 | } 33 | } 34 | Node queryNormal(int left, int right) { 35 | Node ans = Node(); 36 | for (int j = logValues[right - left + 1]; j >= 0; j--) { 37 | if ((1 << j) <= right - left + 1) { 38 | ans.merge(ans, table[left][j]); 39 | left += (1 << j); 40 | } 41 | } 42 | return ans; 43 | } 44 | Node queryIdempotent(int left, int right) { 45 | int j = logValues[right - left + 1]; 46 | Node ans = Node(); 47 | ans.merge(table[left][j], table[right - (1 << j) + 1][j]); 48 | return ans; 49 | } 50 | }; 51 | struct Node1 { 52 | int val; // store more info if required 53 | int index; 54 | Node1() { // Identity Element 55 | val = 1e9; 56 | index = -1; 57 | } 58 | Node1(int v, int ind) { 59 | val = v; 60 | index = ind; 61 | } 62 | void merge(Node1 &l, Node1 &r) { 63 | if(l.val < r.val){ 64 | val = l.val; 65 | index = l.index; 66 | }else{ 67 | val = r.val; 68 | index = r.index; 69 | } 70 | } 71 | }; 72 | struct LCA_O_1{ 73 | int n; 74 | vector eulerTour, index; 75 | vector node; 76 | SparseTable sp = SparseTable(0, eulerTour); 77 | LCA_O_1(int n1, vector* edges, int root){ 78 | n = n1; 79 | index.resize(n); 80 | dfs(root, edges, -1, 0); 81 | sp = SparseTable(sz(eulerTour), eulerTour); 82 | debug(sz(eulerTour)) 83 | } 84 | void dfs(int root, vector* edges, int parent, int height){ 85 | eulerTour.pb(height); 86 | node.pb(root); 87 | index[root] = sz(eulerTour) - 1; 88 | for(auto i : edges[root]){ 89 | if(i != parent){ 90 | dfs(i, edges, root, height + 1); 91 | eulerTour.pb(height); 92 | node.pb(root); 93 | } 94 | } 95 | } 96 | inline int query(int a, int b){ 97 | return node[sp.queryIdempotent(min(index[a], index[b]), max(index[a], index[b])).index]; 98 | } 99 | inline int getDepth(int a){ 100 | return eulerTour[index[a]]; 101 | } 102 | }; -------------------------------------------------------------------------------- /String Algorithms/Suffix_array.cpp: -------------------------------------------------------------------------------- 1 | /* Priyansh Agarwal*/ 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 | #define fastio() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL) 14 | #define MOD 1000000007 15 | #define MOD1 998244353 16 | #define nline "\n" 17 | #define pb push_back 18 | #define mp make_pair 19 | #define ff first 20 | #define ss second 21 | #define PI 3.141592653589793238462 22 | #define debug(x) cout << #x << " " << x < a) {return gcd(b, a);} if (b == 0) {return a;} return gcd(b, a % b);} 29 | ll expo(ll a, ll b, ll mod) 30 | {ll res = 1; while (b > 0) {if (b & 1)res = (res * a) % mod; a = (a * a) % mod; b = b >> 1;} return res;} 31 | vector sieve(int n) {int*arr = new int[n + 1](); vector vect; for (int i = 2; i <= n; i++)if (arr[i] == 0) {vect.push_back(i); for (int j = 2 * i; j <= n; j += i)arr[j] = 1;} return vect;} 32 | void extendgcd(ll a, ll b, ll*v) {if (b == 0) {v[0] = 1; v[1] = 0; v[2] = a; return ;} extendgcd(b, a % b, v); ll x = v[1]; v[1] = v[0] - v[1] * (a / b); v[0] = x; return;} //pass an arry of size 3 33 | ll mminv(ll a, ll b) {ll arr[3]; extendgcd(a, b, arr); return arr[0];} //for non prime b 34 | ll mminvprime(ll a, ll b) {return expo(a, b - 2, b);} 35 | bool revsort(ll a, ll b) {return a > b;} 36 | void swap(int &x, int &y) {int temp = x; x = y; y = temp;} 37 | ll combination(ll n, ll r, ll m, ll* fact) {ll val1 = fact[n]; ll val2 = mminvprime(fact[r], m); ll val3 = mminvprime(fact[n - r], m); return ((val1 * val2) % m * val3) % m;} 38 | /*--------------------------------------------------------------------------------------------------------------------------*/ 39 | void counting_sort(vector &p, vector &c, int n) 40 | { 41 | vector cnt(n); 42 | for (auto x : c) 43 | cnt[x]++; 44 | vector p_new(n); 45 | vector pos(n); 46 | pos[0] = 0; 47 | for (int i = 1; i < n; i++) 48 | pos[i] = pos[i - 1] + cnt[i - 1]; 49 | for (auto x : p) 50 | { 51 | int i = c[x]; 52 | p_new[pos[i]] = x; 53 | pos[i]++; 54 | } 55 | p = p_new; 56 | } 57 | int main() 58 | { 59 | fastio(); 60 | #ifndef ONLINE_JUDGE 61 | freopen("Input.txt", "r", stdin); 62 | freopen("Output.txt", "w", stdout); 63 | freopen("Error.txt", "w", stderr); 64 | #endif 65 | string s; 66 | cin >> s; 67 | s += '$'; 68 | int n = s.length(); 69 | vector p(n), c(n); 70 | { 71 | vector> a(n); 72 | for (int i = 0; i < n; i++) 73 | a[i] = {s[i], i}; 74 | sort(a.begin(), a.end()); 75 | for (int i = 0; i < n; i++) 76 | p[i] = a[i].ss; 77 | c[p[0]] = 0; 78 | for (int i = 1; i < n; i++) 79 | { 80 | if (a[i].ff == a[i - 1].ff) 81 | c[p[i]] = c[p[i - 1]]; 82 | else 83 | c[p[i]] = c[p[i - 1]] + 1; 84 | } 85 | } 86 | int k = 0; 87 | while ((1 << k) < n) 88 | { 89 | for (int i = 0; i < n; i++) 90 | p[i] = (p[i] - (1 << k) + n) % n; 91 | counting_sort(p, c, n); 92 | vector c_new(n); 93 | c_new[p[0]] = 0; 94 | for (int i = 1; i < n; i++) 95 | { 96 | pair prev = {c[p[i - 1]], c[(p[i - 1] + (1 << k)) % n]}; 97 | pair now = {c[p[i]], c[(p[i] + (1 << k)) % n]}; 98 | if (now == prev) 99 | c_new[p[i]] = c_new[p[i - 1]]; 100 | else 101 | c_new[p[i]] = c_new[p[i - 1]] + 1; 102 | } 103 | k++; 104 | c = c_new; 105 | } 106 | for (int i = 0; i < n; i++) 107 | cout << p[i] << " "; 108 | cout << endl; 109 | return 0; 110 | } 111 | -------------------------------------------------------------------------------- /Range Queries/Lazy_SGT.cpp: -------------------------------------------------------------------------------- 1 | // Credits to HealthyUG for the inspiration. 2 | // Lazy Segment Tree with Range Updates and Range Queries 3 | // Supports multiple Segment Trees with just a change in the Node and Update 4 | // Very few changes required everytime 5 | 6 | template 7 | struct LazySGT { 8 | vector tree; 9 | vector lazy; 10 | vector updates; 11 | vector arr; // type may change 12 | int n; 13 | int s; 14 | LazySGT(int a_len, vector &a) { // change if type updated 15 | arr = a; 16 | n = a_len; 17 | s = 1; 18 | while(s < 2 * n){ 19 | s = s << 1; 20 | } 21 | tree.resize(s); fill(all(tree), Node()); 22 | lazy.resize(s); fill(all(lazy), false); 23 | updates.resize(s); fill(all(updates), Update()); 24 | build(0, n - 1, 1); 25 | } 26 | void build(int start, int end, int index) { // Never change this 27 | if (start == end) { 28 | tree[index] = Node(arr[start]); 29 | return; 30 | } 31 | int mid = (start + end) / 2; 32 | build(start, mid, 2 * index); 33 | build(mid + 1, end, 2 * index + 1); 34 | tree[index].merge(tree[2 * index], tree[2 * index + 1]); 35 | } 36 | void pushdown(int index, int start, int end){ 37 | if(lazy[index]){ 38 | int mid = (start + end) / 2; 39 | apply(2 * index, start, mid, updates[index]); 40 | apply(2 * index + 1, mid + 1, end, updates[index]); 41 | updates[index] = Update(); 42 | lazy[index] = 0; 43 | } 44 | } 45 | void apply(int index, int start, int end, Update& u){ 46 | if(start != end){ 47 | lazy[index] = 1; 48 | updates[index].combine(u, start, end); 49 | } 50 | u.apply(tree[index], start, end); 51 | } 52 | void update(int start, int end, int index, int left, int right, Update& u) { // Never Change this 53 | if(start > right || end < left) 54 | return; 55 | if(start >= left && end <= right){ 56 | apply(index, start, end, u); 57 | return; 58 | } 59 | pushdown(index, start, end); 60 | int mid = (start + end) / 2; 61 | update(start, mid, 2 * index, left, right, u); 62 | update(mid + 1, end, 2 * index + 1, left, right, u); 63 | tree[index].merge(tree[2 * index], tree[2 * index + 1]); 64 | } 65 | Node query(int start, int end, int index, int left, int right) { // Never change this 66 | if (start > right || end < left) 67 | return Node(); 68 | if (start >= left && end <= right){ 69 | pushdown(index, start, end); 70 | return tree[index]; 71 | } 72 | pushdown(index, start, end); 73 | int mid = (start + end) / 2; 74 | Node l, r, ans; 75 | l = query(start, mid, 2 * index, left, right); 76 | r = query(mid + 1, end, 2 * index + 1, left, right); 77 | ans.merge(l, r); 78 | return ans; 79 | } 80 | void make_update(int left, int right, ll val) { // pass in as many parameters as required 81 | Update new_update = Update(val); // may change 82 | update(0, n - 1, 1, left, right, new_update); 83 | } 84 | Node make_query(int left, int right) { 85 | return query(0, n - 1, 1, left, right); 86 | } 87 | }; 88 | 89 | struct Node1 { 90 | ll val; // may change 91 | Node1() { // Identity element 92 | val = 0; // may change 93 | } 94 | Node1(ll p1) { // Actual Node 95 | val = p1; // may change 96 | } 97 | void merge(Node1 &l, Node1 &r) { // Merge two child nodes 98 | val = l.val + r.val; // may change 99 | } 100 | }; 101 | 102 | struct Update1 { 103 | ll val; // may change 104 | Update1(){ // Identity update 105 | val = 0; 106 | } 107 | Update1(ll val1) { // Actual Update 108 | val = val1; 109 | } 110 | void apply(Node1 &a, int start, int end) { // apply update to given node 111 | a.val = val * (end - start + 1); // may change 112 | } 113 | void combine(Update1& new_update, int start, int end){ 114 | val = new_update.val; 115 | } 116 | }; -------------------------------------------------------------------------------- /Graph Algorithms/Prims.cpp: -------------------------------------------------------------------------------- 1 | //Important Note: The MST generated by Prim and Kruskal may be different but for general purpose any one can be used out of the two 2 | //O(NLongN) using priority queue otherwise O(N^2) 3 | //MST calculation 4 | //Storing does not have to be in terms of edge list here 5 | //We can store a vector of pairs as edges with destination and weight as the parameters 6 | //The output result obtained will be n-1 pairs showing which are the edges included 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | #define fastio() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL) 19 | #define MOD 1000000007 20 | #define MOD1 998244353 21 | #define nline "\n" 22 | #define pb push_back 23 | #define mp make_pair 24 | #define ff first 25 | #define ss second 26 | typedef long long ll; 27 | typedef unsigned long long ull; 28 | typedef priority_queue, function> pq_func; 29 | /*---------------------------------------------------------------------------------------------------------------------------*/ 30 | int gcd(int a, int b) {if (b > a) {return gcd(b, a);} if (b == 0) {return a;} return gcd(b, a % b);} 31 | ll expo(ll a, ll b, ll mod) {ll res = 1; while (b > 0) {if (b & 1)res = (res * a) % mod; a = (a * a) % mod; b = b >> 1;} return res;} 32 | vector sieve(int n) {int*arr = new int[n + 1](); vector vect; for (int i = 2; i <= n; i++)if (arr[i] == 0) {vect.push_back(i); for (int j = 2 * i; j <= n; j += i)arr[j] = 1;} return vect;} 33 | void extendgcd(ll a, ll b, ll*v) {if (b == 0) {v[0] = 1; v[1] = 0; v[2] = a; return ;} extendgcd(b, a % b, v); ll x = v[1]; v[1] = v[0] - v[1] * (a / b); v[0] = x; return;} //pass an arry of size 3 34 | ll mminv(ll a, ll b) {ll arr[3]; extendgcd(a, b, arr); return arr[0];} //for non prime b 35 | ll mminvprime(ll a, ll b) {return expo(a, b - 2, b);} 36 | bool revsort(ll a, ll b) {return a > b;} 37 | /*--------------------------------------------------------------------------------------------------------------------------*/ 38 | bool compare1(pair p1, pair p2) 39 | { 40 | return p1.ss > p2.ss; 41 | } 42 | int get_min_vertex(bool* visited, ll* weight, int n) 43 | { 44 | //can be used if there is some problem with priority queue and the time complexity allowed is O(N^2) 45 | int ans = -1; 46 | ll min1 = 1e18 + 1; 47 | for (int i = 0; i < n; i++) 48 | { 49 | if (!visited[i] && weight[i] < min1) 50 | { 51 | min1 = weight[i]; 52 | ans = i; 53 | } 54 | } 55 | return ans; 56 | } 57 | void prims(vector>* edges, int n) 58 | { 59 | bool*visited = new bool[n](); 60 | int* parent = new int[n]; 61 | ll*weight = new ll[n]; 62 | for (int i = 0; i < n; i++) 63 | weight[i] = 1e18; 64 | parent[0] = -1; 65 | weight[0] = 0; 66 | priority_queue, vector>, function, pair)>> pq1(compare1); 67 | pq1.push(mp(0, ll(0))); 68 | for (int i = 0; i < n - 1; i++) 69 | { 70 | //get_min_vertex which is unvisited and has minimum weight 71 | //getting minimum vertex can be done in LogN using priority queue 72 | int minVertex = pq1.top().ff; 73 | pq1.pop(); 74 | while (visited[minVertex]) 75 | { 76 | minVertex = pq1.top().ff; 77 | pq1.pop(); 78 | } 79 | visited[minVertex] = true; 80 | //explore all the neighbours of minVertex and update accordingly 81 | for (int j = 0; j < edges[minVertex].size(); j++) 82 | { 83 | if (visited[edges[minVertex][j].ff]) 84 | continue; 85 | if (weight[edges[minVertex][j].ff] > edges[minVertex][j].ss) 86 | { 87 | //update the current weigth of the neighbour and change its parent also 88 | weight[edges[minVertex][j].ff] = edges[minVertex][j].ss; 89 | parent[edges[minVertex][j].ff] = minVertex; 90 | pq1.push(mp(edges[minVertex][j].ff, weight[edges[minVertex][j].ff])); 91 | } 92 | } 93 | } 94 | for (int i = 1; i < n; i++) 95 | cout << i << " " << parent[i] << " " << weight[i] << endl; 96 | } 97 | int main() 98 | { 99 | fastio(); 100 | #ifndef ONLINE_JUDGE 101 | freopen("Input.txt", "r", stdin); 102 | freopen("Output.txt", "w", stdout); 103 | freopen("Error.txt", "w", stderr); 104 | #endif 105 | int n, e; 106 | cin >> n >> e; 107 | vector> *edges = new vector>[n]; 108 | //input is taken considering 0 based indexing 109 | //make changes accordingly 110 | for (int i = 0; i < e; i++) 111 | { 112 | int a, b; 113 | ll weight; 114 | cin >> a >> b >> weight; 115 | edges[a].pb(mp(b, weight)); 116 | edges[b].pb(mp(a, weight)); 117 | } 118 | prims(edges, n); 119 | return 0; 120 | } -------------------------------------------------------------------------------- /TemplateStuff/Template.cpp: -------------------------------------------------------------------------------- 1 | #pragma GCC optimize("O3,unroll-loops") 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | using namespace chrono; 9 | using namespace __gnu_pbds; 10 | 11 | #define fastio() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL) 12 | #define MOD 1000000007 13 | #define MOD1 998244353 14 | #define INF 1e18 15 | #define nline "\n" 16 | #define pb push_back 17 | #define ppb pop_back 18 | #define mp make_pair 19 | #define ff first 20 | #define ss second 21 | #define PI 3.141592653589793238462 22 | #define set_bits __builtin_popcountll 23 | #define sz(x) ((int)(x).size()) 24 | #define all(x) (x).begin(), (x).end() 25 | 26 | #ifdef Priyansh31dec 27 | #define debug(x) cerr << #x<<" "; _print(x); cerr << endl; 28 | #else 29 | #define debug(x); 30 | #endif 31 | 32 | typedef long long ll; 33 | typedef unsigned long long ull; 34 | typedef long double lld; 35 | typedef __int128 ell; 36 | typedef tree, null_type, less>, rb_tree_tag, tree_order_statistics_node_update > pbds; // find_by_order, order_of_key 37 | 38 | void _print(ll t) {cerr << t;} 39 | void _print(int t) {cerr << t;} 40 | void _print(string t) {cerr << t;} 41 | void _print(char t) {cerr << t;} 42 | void _print(lld t) {cerr << t;} 43 | void _print(double t) {cerr << t;} 44 | void _print(ull t) {cerr << t;} 45 | 46 | template void _print(pair p); 47 | template void _print(vector v); 48 | template void _print(set v); 49 | template void _print(map v); 50 | template void _print(multiset v); 51 | template void _print(pair p) {cerr << "{"; _print(p.ff); cerr << ","; _print(p.ss); cerr << "}";} 52 | template void _print(vector v) {cerr << "[ "; for (T i : v) {_print(i); cerr << " ";} cerr << "]";} 53 | template void _print(set v) {cerr << "[ "; for (T i : v) {_print(i); cerr << " ";} cerr << "]";} 54 | template void _print(multiset v) {cerr << "[ "; for (T i : v) {_print(i); cerr << " ";} cerr << "]";} 55 | template void _print(map v) {cerr << "[ "; for (auto i : v) {_print(i); cerr << " ";} cerr << "]";} 56 | void _print(pbds v) {cerr << "[ "; for (auto i : v) {_print(i); cerr << " ";} cerr << "]";} 57 | 58 | mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); 59 | /*---------------------------------------------------------------------------------------------------------------------------*/ 60 | ll gcd(ll a, ll b) {if (b > a) {return gcd(b, a);} if (b == 0) {return a;} return gcd(b, a % b);} 61 | ll expo(ll a, ll b, ll mod) {ll res = 1; while (b > 0) {if (b & 1)res = (res * a) % mod; a = (a * a) % mod; b = b >> 1;} return res;} 62 | void extendgcd(ll a, ll b, ll*v) {if (b == 0) {v[0] = 1; v[1] = 0; v[2] = a; return ;} extendgcd(b, a % b, v); ll x = v[1]; v[1] = v[0] - v[1] * (a / b); v[0] = x; return;} //pass an arry of size1 3 63 | ll mminv(ll a, ll b) {ll arr[3]; extendgcd(a, b, arr); return arr[0];} //for non prime b 64 | ll mminvprime(ll a, ll b) {return expo(a, b - 2, b);} 65 | bool revsort(ll a, ll b) {return a > b;} 66 | ll combination(ll n, ll r, ll m, ll *fact, ll *ifact) {ll val1 = fact[n]; ll val2 = ifact[n - r]; ll val3 = ifact[r]; return (((val1 * val2) % m) * val3) % m;} 67 | void google(int t) {cout << "Case #" << t << ": ";} 68 | vector sieve(int n) {int*arr = new int[n + 1](); vector vect; for (int i = 2; i <= n; i++)if (arr[i] == 0) {vect.push_back(i); for (int j = 2 * i; j <= n; j += i)arr[j] = 1;} return vect;} 69 | ll mod_add(ll a, ll b, ll m) {a = a % m; b = b % m; return (((a + b) % m) + m) % m;} 70 | ll mod_mul(ll a, ll b, ll m) {a = a % m; b = b % m; return (((a * b) % m) + m) % m;} 71 | ll mod_sub(ll a, ll b, ll m) {a = a % m; b = b % m; return (((a - b) % m) + m) % m;} 72 | ll mod_div(ll a, ll b, ll m) {a = a % m; b = b % m; return (mod_mul(a, mminvprime(b, m), m) + m) % m;} //only for prime m 73 | ll phin(ll n) {ll number = n; if (n % 2 == 0) {number /= 2; while (n % 2 == 0) n /= 2;} for (ll i = 3; i <= sqrt(n); i += 2) {if (n % i == 0) {while (n % i == 0)n /= i; number = (number / i * (i - 1));}} if (n > 1)number = (number / n * (n - 1)) ; return number;} //O(sqrt(N)) 74 | ll getRandomNumber(ll l, ll r) {return uniform_int_distribution(l, r)(rng);} 75 | /*--------------------------------------------------------------------------------------------------------------------------*/ 76 | void solve() { 77 | 78 | } 79 | int main() { 80 | #ifdef Priyansh31dec 81 | freopen("Error.txt", "w", stderr); 82 | #endif 83 | fastio(); 84 | auto start1 = high_resolution_clock::now(); 85 | solve(); 86 | auto stop1 = high_resolution_clock::now(); 87 | auto duration = duration_cast(stop1 - start1); 88 | #ifdef Priyansh31dec 89 | cerr << "Time: " << duration . count() / 1000 << endl; 90 | #endif 91 | } -------------------------------------------------------------------------------- /Range Queries/Mo_algo.cpp: -------------------------------------------------------------------------------- 1 | /* Priyansh Agarwal*/ 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | using namespace std; 16 | using namespace __gnu_pbds; 17 | using namespace chrono; 18 | #define fastio() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL) 19 | #define MOD 1000000007 20 | #define MOD1 998244353 21 | #define nline "\n" 22 | #define pb push_back 23 | #define mp make_pair 24 | #define ff first 25 | #define ss second 26 | #define PI 3.141592653589793238462 27 | #define debug(x) cout << #x << " " << x <, rb_tree_tag, tree_order_statistics_node_update > pbds; 33 | /*---------------------------------------------------------------------------------------------------------------------------*/ 34 | ll gcd(ll a, ll b) {if (b > a) {return gcd(b, a);} if (b == 0) {return a;} return gcd(b, a % b);} 35 | ll expo(ll a, ll b, ll mod) {ll res = 1; while (b > 0) {if (b & 1)res = (res * a) % mod; a = (a * a) % mod; b = b >> 1;} return res;} 36 | void extendgcd(ll a, ll b, ll*v) {if (b == 0) {v[0] = 1; v[1] = 0; v[2] = a; return ;} extendgcd(b, a % b, v); ll x = v[1]; v[1] = v[0] - v[1] * (a / b); v[0] = x; return;} //pass an arry of size 3 37 | ll mminv(ll a, ll b) {ll arr[3]; extendgcd(a, b, arr); return arr[0];} //for non prime b 38 | ll mminvprime(ll a, ll b) {return expo(a, b - 2, b);} 39 | bool revsort(ll a, ll b) {return a > b;} 40 | void swap(int &x, int &y) {int temp = x; x = y; y = temp;} 41 | ll combination(ll n, ll r, ll m, ll* fact) {ll val1 = fact[n]; ll val2 = mminvprime(fact[r], m); ll val3 = mminvprime(fact[n - r], m); return ((val1 * val2) % m * val3) % m;} 42 | void google(int t) {cout << "Case #" << t << ": ";} 43 | vector sieve(int n) {int*arr = new int[n + 1](); vector vect; for (int i = 2; i <= n; i++)if (arr[i] == 0) {vect.push_back(i); for (int j = 2 * i; j <= n; j += i)arr[j] = 1;} return vect;} 44 | /*--------------------------------------------------------------------------------------------------------------------------*/ 45 | const int block_size = 450; 46 | bool compare(pair, int> p1, pair, int> p2) 47 | { 48 | int b1 = p1.ff.ff / block_size; 49 | int b2 = p2.ff.ff / block_size; 50 | if (b1 == b2) 51 | return b1 % 2 == 0 ? (p1.ff.ss < p2.ff.ss) : (p1.ff.ss > p2.ff.ss); 52 | return b1 < b2; 53 | } 54 | int main() 55 | { 56 | fastio(); 57 | #ifndef ONLINE_JUDGE 58 | freopen("Input.txt", "r", stdin); 59 | freopen("Output.txt", "w", stdout); 60 | freopen("Error.txt", "w", stderr); 61 | #endif 62 | auto start1 = high_resolution_clock::now(); 63 | int n, q; 64 | cin >> n >> q; 65 | // block_size = int(sqrt(n + 0.0) + 1); 66 | int *arr = new int[n]; 67 | int *freq = new int[n + 1](); 68 | int number = 1; 69 | map coordinate_compression; 70 | for (int i = 0; i < n; i++) 71 | { 72 | cin >> arr[i]; 73 | if (coordinate_compression.find(arr[i]) == coordinate_compression.end()) 74 | { 75 | coordinate_compression[arr[i]] = number; 76 | arr[i] = number; 77 | number++; 78 | } 79 | else 80 | arr[i] = coordinate_compression[arr[i]]; 81 | } 82 | int start = 0; 83 | int end = -1; 84 | vector, int>> ans(q); 85 | for (int i = 0; i < q; i ++) 86 | { 87 | int a, b; 88 | cin >> a >> b; 89 | ans[i] = {{a, b}, i}; 90 | } 91 | sort(ans.begin(), ans.end(), compare); 92 | int *ans1 = new int[q]; 93 | int count = 0; 94 | for (auto i : ans) 95 | { 96 | pair, int> p1 = i; 97 | int right = p1.ff.ss - 1; 98 | int left = p1.ff.ff - 1; 99 | while (start < left) 100 | { 101 | int x = arr[start]; 102 | freq[x]--; 103 | if (freq[x] == 0) 104 | count--; 105 | start++; 106 | } 107 | while (start > left) 108 | { 109 | start--; 110 | int x = arr[start]; 111 | freq[x]++; 112 | if (freq[x] == 1) 113 | count++; 114 | } 115 | while (end < right) 116 | { 117 | end++; 118 | int x = arr[end]; 119 | freq[x]++; 120 | if (freq[x] == 1) 121 | count++; 122 | } 123 | while (end > right) 124 | { 125 | int x = arr[end]; 126 | freq[x]--; 127 | if (freq[x] == 0) 128 | count--; 129 | end--; 130 | } 131 | ans1[p1.ss] = count; 132 | } 133 | for (int i = 0; i < q; i++) 134 | cout << ans1[i] << "\n"; 135 | auto stop1 = high_resolution_clock::now(); 136 | auto duration = duration_cast(stop1 - start1); 137 | #ifndef ONLINE_JUDGE 138 | cerr << "Time: " << duration.count() / 1000.0 << endl; 139 | #endif 140 | return 0; 141 | } -------------------------------------------------------------------------------- /Graph Algorithms/PrimsUpdated.cpp: -------------------------------------------------------------------------------- 1 | // Priyansh Agarwal 2 | // Check out my Youtube Channel: https://www.youtube.com/c/PriyanshAgarwal 3 | 4 | #include 5 | // #include 6 | // #include 7 | 8 | using namespace std; 9 | using namespace chrono; 10 | // using namespace __gnu_pbds; 11 | 12 | #define fastio() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL) 13 | #define MOD 1000000007 14 | #define MOD1 998244353 15 | #define INF 1e18 16 | #define nline "\n" 17 | #define pb push_back 18 | #define ppb pop_back 19 | #define mp make_pair 20 | #define ff first 21 | #define ss second 22 | #define PI 3.141592653589793238462 23 | #define set_bits __builtin_popcountll 24 | #define sz(x) ((int)(x).size()) 25 | #define all(x) (x).begin(), (x).end() 26 | 27 | mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); 28 | 29 | #ifdef Priyansh31dec 30 | #define debug(x) cerr << #x <<" "; _print(x); cerr << endl; 31 | #else 32 | #define debug(x); 33 | #endif 34 | 35 | typedef long long ll; 36 | typedef unsigned long long ull; 37 | typedef long double lld; 38 | // typedef tree, null_type, less>, rb_tree_tag, tree_order_statistics_node_update > pbds; // find_by_order, order_of_key 39 | 40 | void _print(ll t) {cerr << t;} 41 | void _print(int t) {cerr << t;} 42 | void _print(string t) {cerr << t;} 43 | void _print(char t) {cerr << t;} 44 | void _print(lld t) {cerr << t;} 45 | void _print(double t) {cerr << t;} 46 | void _print(ull t) {cerr << t;} 47 | 48 | template void _print(pair p); 49 | template void _print(vector v); 50 | template void _print(set v); 51 | template void _print(map v); 52 | template void _print(multiset v); 53 | template void _print(pair p) {cerr << "{"; _print(p.ff); cerr << ","; _print(p.ss); cerr << "}";} 54 | template void _print(vector v) {cerr << "[ "; for (T i : v) {_print(i); cerr << " ";} cerr << "]";} 55 | template void _print(set v) {cerr << "[ "; for (T i : v) {_print(i); cerr << " ";} cerr << "]";} 56 | template void _print(multiset v) {cerr << "[ "; for (T i : v) {_print(i); cerr << " ";} cerr << "]";} 57 | template void _print(map v) {cerr << "[ "; for (auto i : v) {_print(i); cerr << " ";} cerr << "]";} 58 | // void _print(pbds v) {cerr << "[ "; for (auto i : v) {_print(i); cerr << " ";} cerr << "]";} 59 | 60 | /*---------------------------------------------------------------------------------------------------------------------------*/ 61 | ll gcd(ll a, ll b) {if (b > a) {return gcd(b, a);} if (b == 0) {return a;} return gcd(b, a % b);} 62 | ll expo(ll a, ll b, ll mod) {ll res = 1; while (b > 0) {if (b & 1)res = (res * a) % mod; a = (a * a) % mod; b = b >> 1;} return res;} 63 | void extendgcd(ll a, ll b, ll*v) {if (b == 0) {v[0] = 1; v[1] = 0; v[2] = a; return ;} extendgcd(b, a % b, v); ll x = v[1]; v[1] = v[0] - v[1] * (a / b); v[0] = x; return;} //pass an arry of size1 3 64 | ll mminv(ll a, ll b) {ll arr[3]; extendgcd(a, b, arr); return arr[0];} //for non prime b 65 | ll mminvprime(ll a, ll b) {return expo(a, b - 2, b);} 66 | bool revsort(ll a, ll b) {return a > b;} 67 | void swap(int &x, int &y) {int temp = x; x = y; y = temp;} 68 | ll combination(ll n, ll r, ll m, ll *fact, ll *ifact) {ll val1 = fact[n]; ll val2 = ifact[n - r]; ll val3 = ifact[r]; return (((val1 * val2) % m) * val3) % m;} 69 | void google(int t) {cout << "Case #" << t << ": ";} 70 | vector sieve(int n) {int*arr = new int[n + 1](); vector vect; for (ll i = 2; i <= n; i++)if (arr[i] == 0) {vect.push_back(i); for (ll j = 2 * i; j <= n; j += i)arr[j] = 1;} return vect;} 71 | ll mod_add(ll a, ll b, ll m) {a = a % m; b = b % m; return (((a + b) % m) + m) % m;} 72 | ll mod_mul(ll a, ll b, ll m) {a = a % m; b = b % m; return (((a * b) % m) + m) % m;} 73 | ll mod_sub(ll a, ll b, ll m) {a = a % m; b = b % m; return (((a - b) % m) + m) % m;} 74 | ll mod_div(ll a, ll b, ll m) {a = a % m; b = b % m; return (mod_mul(a, mminvprime(b, m), m) + m) % m;} //only for prime m 75 | ll phin(ll n) {ll number = n; if (n % 2 == 0) {number /= 2; while (n % 2 == 0) n /= 2;} for (ll i = 3; i <= sqrt(n); i += 2) {if (n % i == 0) {while (n % i == 0)n /= i; number = (number / i * (i - 1));}} if (n > 1)number = (number / n * (n - 1)) ; return number;} //O(sqrt(N)) 76 | void precision(int a) {cout << setprecision(a) << fixed;} 77 | /*--------------------------------------------------------------------------------------------------------------------------*/ 78 | 79 | 80 | void solve() { 81 | int n, m; 82 | cin >> n >> m; 83 | vector> *edges = new vector>[n]; 84 | for (int i = 0; i < m; i++) { 85 | int a, b, c; 86 | cin >> a >> b >> c; 87 | edges[a].pb({b, c}); 88 | edges[b].pb({a, c}); 89 | } 90 | set> pq; 91 | vector dist(n, INF); 92 | dist[0] = 0; 93 | vector visited(n); 94 | vector parent(n, -1); 95 | pq.insert({0, 0}); 96 | for (int i = 0; i < n; i++) { 97 | pair top = *pq.begin(); 98 | pq.erase(top); 99 | int best = top.ss; 100 | visited[best] = true; 101 | for (auto i : edges[best]) { 102 | if ((!visited[i.ff]) && dist[i.ff] > i.ss) { 103 | pq.erase({dist[i.ff], i.ff}); 104 | dist[i.ff] = i.ss; 105 | pq.insert({dist[i.ff], i.ff}); 106 | parent[i.ff] = best; 107 | } 108 | } 109 | } 110 | for (int i = 1; i < n; i++) { 111 | if (parent[i] < i) { 112 | cout << parent[i] << " " << i << " " << dist[i] << nline; 113 | } else { 114 | cout << i << " " << parent[i] << " " << dist[i] << nline; 115 | } 116 | } 117 | } 118 | 119 | int main() { 120 | #ifdef Priyansh31dec 121 | freopen("Error.txt", "w", stderr); 122 | #endif 123 | fastio(); 124 | auto start1 = high_resolution_clock::now(); 125 | solve(); 126 | auto stop1 = high_resolution_clock::now(); 127 | auto duration = duration_cast(stop1 - start1); 128 | #ifdef Priyansh31dec 129 | cerr << "Time: " << duration . count() / 1000 << endl; 130 | #endif 131 | } -------------------------------------------------------------------------------- /Graph Algorithms/Kruskals.cpp: -------------------------------------------------------------------------------- 1 | // Priyansh Agarwal 2 | // Check out my Youtube Channel: https://www.youtube.com/c/PriyanshAgarwal 3 | 4 | #include 5 | // #include 6 | // #include 7 | 8 | using namespace std; 9 | using namespace chrono; 10 | // using namespace __gnu_pbds; 11 | 12 | #define fastio() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL) 13 | #define MOD 1000000007 14 | #define MOD1 998244353 15 | #define INF 1e18 16 | #define nline "\n" 17 | #define pb push_back 18 | #define ppb pop_back 19 | #define mp make_pair 20 | #define ff first 21 | #define ss second 22 | #define PI 3.141592653589793238462 23 | #define set_bits __builtin_popcountll 24 | #define sz(x) ((int)(x).size()) 25 | #define all(x) (x).begin(), (x).end() 26 | 27 | mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); 28 | 29 | #ifdef Priyansh31dec 30 | #define debug(x) cerr << #x <<" "; _print(x); cerr << endl; 31 | #else 32 | #define debug(x); 33 | #endif 34 | 35 | typedef long long ll; 36 | typedef unsigned long long ull; 37 | typedef long double lld; 38 | // typedef tree, null_type, less>, rb_tree_tag, tree_order_statistics_node_update > pbds; // find_by_order, order_of_key 39 | 40 | void _print(ll t) {cerr << t;} 41 | void _print(int t) {cerr << t;} 42 | void _print(string t) {cerr << t;} 43 | void _print(char t) {cerr << t;} 44 | void _print(lld t) {cerr << t;} 45 | void _print(double t) {cerr << t;} 46 | void _print(ull t) {cerr << t;} 47 | 48 | template void _print(pair p); 49 | template void _print(vector v); 50 | template void _print(set v); 51 | template void _print(map v); 52 | template void _print(multiset v); 53 | template void _print(pair p) {cerr << "{"; _print(p.ff); cerr << ","; _print(p.ss); cerr << "}";} 54 | template void _print(vector v) {cerr << "[ "; for (T i : v) {_print(i); cerr << " ";} cerr << "]";} 55 | template void _print(set v) {cerr << "[ "; for (T i : v) {_print(i); cerr << " ";} cerr << "]";} 56 | template void _print(multiset v) {cerr << "[ "; for (T i : v) {_print(i); cerr << " ";} cerr << "]";} 57 | template void _print(map v) {cerr << "[ "; for (auto i : v) {_print(i); cerr << " ";} cerr << "]";} 58 | // void _print(pbds v) {cerr << "[ "; for (auto i : v) {_print(i); cerr << " ";} cerr << "]";} 59 | 60 | /*---------------------------------------------------------------------------------------------------------------------------*/ 61 | ll gcd(ll a, ll b) {if (b > a) {return gcd(b, a);} if (b == 0) {return a;} return gcd(b, a % b);} 62 | ll expo(ll a, ll b, ll mod) {ll res = 1; while (b > 0) {if (b & 1)res = (res * a) % mod; a = (a * a) % mod; b = b >> 1;} return res;} 63 | void extendgcd(ll a, ll b, ll*v) {if (b == 0) {v[0] = 1; v[1] = 0; v[2] = a; return ;} extendgcd(b, a % b, v); ll x = v[1]; v[1] = v[0] - v[1] * (a / b); v[0] = x; return;} //pass an arry of size1 3 64 | ll mminv(ll a, ll b) {ll arr[3]; extendgcd(a, b, arr); return arr[0];} //for non prime b 65 | ll mminvprime(ll a, ll b) {return expo(a, b - 2, b);} 66 | bool revsort(ll a, ll b) {return a > b;} 67 | void swap(int &x, int &y) {int temp = x; x = y; y = temp;} 68 | ll combination(ll n, ll r, ll m, ll *fact, ll *ifact) {ll val1 = fact[n]; ll val2 = ifact[n - r]; ll val3 = ifact[r]; return (((val1 * val2) % m) * val3) % m;} 69 | void google(int t) {cout << "Case #" << t << ": ";} 70 | vector sieve(int n) {int*arr = new int[n + 1](); vector vect; for (ll i = 2; i <= n; i++)if (arr[i] == 0) {vect.push_back(i); for (ll j = 2 * i; j <= n; j += i)arr[j] = 1;} return vect;} 71 | ll mod_add(ll a, ll b, ll m) {a = a % m; b = b % m; return (((a + b) % m) + m) % m;} 72 | ll mod_mul(ll a, ll b, ll m) {a = a % m; b = b % m; return (((a * b) % m) + m) % m;} 73 | ll mod_sub(ll a, ll b, ll m) {a = a % m; b = b % m; return (((a - b) % m) + m) % m;} 74 | ll mod_div(ll a, ll b, ll m) {a = a % m; b = b % m; return (mod_mul(a, mminvprime(b, m), m) + m) % m;} //only for prime m 75 | ll phin(ll n) {ll number = n; if (n % 2 == 0) {number /= 2; while (n % 2 == 0) n /= 2;} for (ll i = 3; i <= sqrt(n); i += 2) {if (n % i == 0) {while (n % i == 0)n /= i; number = (number / i * (i - 1));}} if (n > 1)number = (number / n * (n - 1)) ; return number;} //O(sqrt(N)) 76 | void precision(int a) {cout << setprecision(a) << fixed;} 77 | /*--------------------------------------------------------------------------------------------------------------------------*/ 78 | 79 | int get(int a, vector& component) { 80 | return component[a] = (component[a] == a ? a : get(component[a], component)); 81 | } 82 | void merge(int a, int b, vector& rank, vector& component) { 83 | a = get(a, component); 84 | b = get(b, component); 85 | if (a == b) 86 | return; 87 | if (rank[a] == rank[b]) 88 | rank[a]++; 89 | if (rank[a] > rank[b]) 90 | component[b] = a; 91 | else 92 | component[a] = b; 93 | } 94 | 95 | void solve() { 96 | 97 | int n, m; 98 | cin >> n >> m; 99 | vector component(n); 100 | for (int i = 0; i < n; i++) { 101 | component[i] = i; 102 | } 103 | vector rank(n, 0); 104 | vector>> edges; 105 | for (int i = 0; i < m; i++) { 106 | int a, b, c; 107 | cin >> a >> b >> c; 108 | edges.push_back({c, {a, b}}); 109 | } 110 | sort(edges.begin(), edges.end()); 111 | vector, ll>> ans; 112 | for (auto i : edges) { 113 | if (sz(ans) == n - 1) 114 | break; 115 | int a = i.ss.ff; 116 | int b = i.ss.ss; 117 | if (get(a, component) != get(b, component)) { 118 | merge(a, b, rank, component); 119 | ans.push_back({{min(a, b), max(b, a)}, i.ff}); 120 | } 121 | } 122 | for (auto i : ans) { 123 | cout << i.ff.ff << " " << i.ff.ss << " " << i.ss << endl; 124 | } 125 | } 126 | 127 | int main() { 128 | #ifdef Priyansh31dec 129 | freopen("Error.txt", "w", stderr); 130 | #endif 131 | fastio(); 132 | auto start1 = high_resolution_clock::now(); 133 | solve(); 134 | auto stop1 = high_resolution_clock::now(); 135 | auto duration = duration_cast(stop1 - start1); 136 | #ifdef Priyansh31dec 137 | cerr << "Time: " << duration . count() / 1000 << endl; 138 | #endif 139 | } -------------------------------------------------------------------------------- /Graph Algorithms/4.KosaRaju_Algo_SCC.cpp: -------------------------------------------------------------------------------- 1 | // Priyansh Agarwal 2 | // Check out my Youtube Channel: https://www.youtube.com/c/PriyanshAgarwal 3 | 4 | #include 5 | // #include 6 | // #include 7 | 8 | using namespace std; 9 | using namespace chrono; 10 | // using namespace __gnu_pbds; 11 | 12 | #define fastio() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL) 13 | #define MOD 1000000007 14 | #define MOD1 998244353 15 | #define INF 1e18 16 | #define nline "\n" 17 | #define pb push_back 18 | #define ppb pop_back 19 | #define mp make_pair 20 | #define ff first 21 | #define ss second 22 | #define PI 3.141592653589793238462 23 | #define set_bits __builtin_popcountll 24 | #define sz(x) ((int)(x).size()) 25 | #define all(x) (x).begin(), (x).end() 26 | 27 | mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); 28 | 29 | #ifdef Priyansh31dec 30 | #define debug(x) cerr << #x <<" "; _print(x); cerr << endl; 31 | #else 32 | #define debug(x); 33 | #endif 34 | 35 | typedef long long ll; 36 | typedef unsigned long long ull; 37 | typedef long double lld; 38 | // typedef tree, null_type, less>, rb_tree_tag, tree_order_statistics_node_update > pbds; // find_by_order, order_of_key 39 | 40 | void _print(ll t) {cerr << t;} 41 | void _print(int t) {cerr << t;} 42 | void _print(string t) {cerr << t;} 43 | void _print(char t) {cerr << t;} 44 | void _print(lld t) {cerr << t;} 45 | void _print(double t) {cerr << t;} 46 | void _print(ull t) {cerr << t;} 47 | 48 | template void _print(pair p); 49 | template void _print(vector v); 50 | template void _print(set v); 51 | template void _print(map v); 52 | template void _print(multiset v); 53 | template void _print(pair p) {cerr << "{"; _print(p.ff); cerr << ","; _print(p.ss); cerr << "}";} 54 | template void _print(vector v) {cerr << "[ "; for (T i : v) {_print(i); cerr << " ";} cerr << "]";} 55 | template void _print(set v) {cerr << "[ "; for (T i : v) {_print(i); cerr << " ";} cerr << "]";} 56 | template void _print(multiset v) {cerr << "[ "; for (T i : v) {_print(i); cerr << " ";} cerr << "]";} 57 | template void _print(map v) {cerr << "[ "; for (auto i : v) {_print(i); cerr << " ";} cerr << "]";} 58 | // void _print(pbds v) {cerr << "[ "; for (auto i : v) {_print(i); cerr << " ";} cerr << "]";} 59 | 60 | /*---------------------------------------------------------------------------------------------------------------------------*/ 61 | ll gcd(ll a, ll b) {if (b > a) {return gcd(b, a);} if (b == 0) {return a;} return gcd(b, a % b);} 62 | ll expo(ll a, ll b, ll mod) {ll res = 1; while (b > 0) {if (b & 1)res = (res * a) % mod; a = (a * a) % mod; b = b >> 1;} return res;} 63 | void extendgcd(ll a, ll b, ll*v) {if (b == 0) {v[0] = 1; v[1] = 0; v[2] = a; return ;} extendgcd(b, a % b, v); ll x = v[1]; v[1] = v[0] - v[1] * (a / b); v[0] = x; return;} //pass an arry of size1 3 64 | ll mminv(ll a, ll b) {ll arr[3]; extendgcd(a, b, arr); return arr[0];} //for non prime b 65 | ll mminvprime(ll a, ll b) {return expo(a, b - 2, b);} 66 | bool revsort(ll a, ll b) {return a > b;} 67 | void swap(int &x, int &y) {int temp = x; x = y; y = temp;} 68 | ll combination(ll n, ll r, ll m, ll *fact, ll *ifact) {ll val1 = fact[n]; ll val2 = ifact[n - r]; ll val3 = ifact[r]; return (((val1 * val2) % m) * val3) % m;} 69 | void google(int t) {cout << "Case #" << t << ": ";} 70 | vector sieve(int n) {int*arr = new int[n + 1](); vector vect; for (ll i = 2; i <= n; i++)if (arr[i] == 0) {vect.push_back(i); for (ll j = 2 * i; j <= n; j += i)arr[j] = 1;} return vect;} 71 | ll mod_add(ll a, ll b, ll m) {a = a % m; b = b % m; return (((a + b) % m) + m) % m;} 72 | ll mod_mul(ll a, ll b, ll m) {a = a % m; b = b % m; return (((a * b) % m) + m) % m;} 73 | ll mod_sub(ll a, ll b, ll m) {a = a % m; b = b % m; return (((a - b) % m) + m) % m;} 74 | ll mod_div(ll a, ll b, ll m) {a = a % m; b = b % m; return (mod_mul(a, mminvprime(b, m), m) + m) % m;} //only for prime m 75 | ll phin(ll n) {ll number = n; if (n % 2 == 0) {number /= 2; while (n % 2 == 0) n /= 2;} for (ll i = 3; i <= sqrt(n); i += 2) {if (n % i == 0) {while (n % i == 0)n /= i; number = (number / i * (i - 1));}} if (n > 1)number = (number / n * (n - 1)) ; return number;} //O(sqrt(N)) 76 | void precision(int a) {cout << setprecision(a) << fixed;} 77 | /*--------------------------------------------------------------------------------------------------------------------------*/ 78 | 79 | void topoSort(int start, vector *edges, vector& topo, vector& visited) { 80 | visited[start] = true; 81 | for (auto i : edges[start]) { 82 | if (!visited[i]) { 83 | topoSort(i, edges, topo, visited); 84 | } 85 | } 86 | topo.pb(start); 87 | } 88 | void getComponent(int start, vector* edges, vector& currComponent, vector& visited) { 89 | currComponent.pb(start); 90 | visited[start] = true; 91 | for (auto i : edges[start]) { 92 | if (!visited[i]) { 93 | getComponent(i, edges, currComponent, visited); 94 | } 95 | } 96 | } 97 | vector> getSCC(int n, vector* edges, vector* edgesT) { 98 | vector visited(n); 99 | vector topo; 100 | for (int i = 0; i < n; i++) { 101 | if (!visited[i]) { 102 | topoSort(i, edges, topo, visited); 103 | } 104 | } 105 | fill(visited.begin(), visited.end(), false); 106 | vector> SCC; 107 | for (int i = topo.size() - 1; i >= 0; i--) { 108 | if (!visited[topo[i]]) { 109 | vector comp; 110 | getComponent(topo[i], edgesT, comp, visited); 111 | SCC.pb(comp); 112 | } 113 | } 114 | return SCC; 115 | } 116 | void solve() { 117 | int n, e; 118 | cin >> n >> e; 119 | vector *edges = new vector[n]; 120 | vector *edgesT = new vector[n]; 121 | for (int i = 0; i < e; i++) 122 | { 123 | int a, b; 124 | cin >> a >> b; 125 | edges[a - 1].pb(b - 1); 126 | edgesT[b - 1].pb(a - 1); 127 | } 128 | vector> SCC = getSCC(n, edges, edgesT); 129 | } 130 | 131 | int main() { 132 | #ifdef Priyansh31dec 133 | freopen("Error.txt", "w", stderr); 134 | #endif 135 | fastio(); 136 | auto start1 = high_resolution_clock::now(); 137 | solve(); 138 | auto stop1 = high_resolution_clock::now(); 139 | auto duration = duration_cast(stop1 - start1); 140 | #ifdef Priyansh31dec 141 | cerr << "Time: " << duration . count() / 1000 << endl; 142 | #endif 143 | } -------------------------------------------------------------------------------- /Tree Algorithms/HLD.cpp: -------------------------------------------------------------------------------- 1 | 2 | // No need to change anything here 3 | struct BinaryLifting { 4 | int n; 5 | int maxLog; 6 | ll maxRequirement; 7 | vector> parent; 8 | vector *edges; 9 | vector logValues; 10 | bool precomputedLogs = false; 11 | BinaryLifting(int n1, vector *edges1, ll requirement, int root) { 12 | n = n1; 13 | edges = edges1; 14 | parent.resize(n); 15 | maxLog = log2(requirement + 1); 16 | maxRequirement = requirement; 17 | for (int i = 0; i < n; i++) { 18 | parent[i].resize(maxLog + 1); 19 | for (int j = 0; j <= maxLog; j++) { 20 | parent[i][j] = -1; 21 | } 22 | } 23 | fillParentTable(root); 24 | if (maxRequirement <= 1000000LL) 25 | precomputeLogs(); 26 | } 27 | BinaryLifting() {} 28 | void fillParentTable(int root) { 29 | vector visited(n); 30 | dfsBinaryLifting(root, visited); 31 | int intermediate = -1; 32 | for (int i = 1; i <= maxLog; i++) { 33 | for (int j = 0; j < n; j++) { 34 | intermediate = parent[j][i - 1]; 35 | if (intermediate != -1) { 36 | parent[j][i] = parent[intermediate][i - 1]; 37 | } 38 | } 39 | } 40 | } 41 | void dfsBinaryLifting(int root, vector &visited) { 42 | visited[root] = true; 43 | for (auto i : edges[root]) { 44 | if (!visited[i]) { 45 | parent[i][0] = root; 46 | dfsBinaryLifting(i, visited); 47 | } 48 | } 49 | } 50 | void precomputeLogs() { 51 | precomputedLogs = true; 52 | logValues.resize(maxRequirement + 1); 53 | logValues[1] = 0; 54 | for (int i = 2; i <= maxRequirement; i++) { 55 | logValues[i] = logValues[i / 2] + 1; 56 | } 57 | } 58 | int kthParent(int start, int k) { 59 | int a = start; 60 | while (k > 0) { 61 | int x = getLog(k); 62 | a = parent[a][x]; 63 | if (a == -1) 64 | return a; 65 | k -= (1 << x); 66 | } 67 | return a; 68 | } 69 | int getLog(ll x) { 70 | return precomputedLogs ? logValues[x] : log2(x); 71 | } 72 | }; 73 | 74 | // No need to change anything here 75 | struct LCA { 76 | int n; 77 | BinaryLifting *bl_object; 78 | vector level; 79 | vector *edges; 80 | LCA(int n1, vector *edges1, int root, BinaryLifting *bl) { 81 | n = n1; 82 | bl_object = bl; 83 | edges = edges1; 84 | level.resize(n); 85 | dfsLCA(root, -1); 86 | } 87 | LCA() {} 88 | void dfsLCA(int root, int parent) { 89 | for (auto i : edges[root]) { 90 | if (i != parent) { 91 | level[i] = level[root] + 1; 92 | dfsLCA(i, root); 93 | } 94 | } 95 | } 96 | int getLCA(int a, int b) { 97 | if (level[a] > level[b]) { 98 | swap(a, b); 99 | } 100 | b = bl_object->kthParent(b, level[b] - level[a]); 101 | if (a == b) 102 | return a; 103 | for (int i = bl_object->maxLog; i >= 0; i--) { 104 | int parent1 = bl_object->parent[a][i]; 105 | int parent2 = bl_object->parent[b][i]; 106 | if (parent2 != parent1 && parent1 != -1 && parent2 != -1) { 107 | a = parent1; 108 | b = parent2; 109 | } 110 | } 111 | return bl_object->parent[a][0]; 112 | } 113 | }; 114 | 115 | 116 | template 117 | struct SegTree { 118 | vector tree; 119 | vector arr; // type may change 120 | int n; 121 | SegTree(int a_len, vector &a) { // change if type updated 122 | arr = a; 123 | n = a_len; 124 | tree.resize(4 * n); fill(all(tree), Node()); 125 | build(0, n - 1, 1); 126 | } 127 | SegTree() {} 128 | void build(int start, int end, int index) // Never change this 129 | { 130 | if (start == end) { 131 | tree[index] = Node(arr[start]); 132 | return; 133 | } 134 | int mid = (start + end) / 2; 135 | build(start, mid, 2 * index); 136 | build(mid + 1, end, 2 * index + 1); 137 | tree[index].merge(tree[2 * index], tree[2 * index + 1]); 138 | } 139 | void update(int start, int end, int index, int query_index, Update &u) // Never Change this 140 | { 141 | if (start == end) { 142 | u.apply(tree[index]); 143 | return; 144 | } 145 | int mid = (start + end) / 2; 146 | if (mid >= query_index) 147 | update(start, mid, 2 * index, query_index, u); 148 | else 149 | update(mid + 1, end, 2 * index + 1, query_index, u); 150 | tree[index].merge(tree[2 * index], tree[2 * index + 1]); 151 | } 152 | Node query(int start, int end, int index, int left, int right) { // Never change this 153 | if (start > right || end < left) 154 | return Node(); 155 | if (start >= left && end <= right) 156 | return tree[index]; 157 | int mid = (start + end) / 2; 158 | Node l, r, ans; 159 | l = query(start, mid, 2 * index, left, right); 160 | r = query(mid + 1, end, 2 * index + 1, left, right); 161 | ans.merge(l, r); 162 | return ans; 163 | } 164 | void make_update(int index, ll val) { // pass in as many parameters as required 165 | Update new_update = Update(val); // may change 166 | update(0, n - 1, 1, index, new_update); 167 | } 168 | Node make_query(int left, int right) { 169 | return query(0, n - 1, 1, left, right); 170 | } 171 | }; 172 | 173 | struct Node1 { 174 | ll val; // may change 175 | Node1() { // Identity element 176 | val = -INF; // may change 177 | } 178 | Node1(ll p1) { // Actual Node 179 | val = p1; // may change 180 | } 181 | void merge(Node1 &l, Node1 &r) { // Merge two child nodes 182 | val = max(l.val, r.val); // may change 183 | } 184 | }; 185 | 186 | struct Update1 { 187 | ll val; // may change 188 | Update1(ll p1) { // Actual Update 189 | val = p1; // may change 190 | } 191 | void apply(Node1 &a) { // apply update to given node 192 | a.val = val; // may change 193 | } 194 | }; 195 | template 196 | struct HLD { 197 | int n; 198 | int rootHere; 199 | vector *edges; 200 | vector big_child; 201 | vector subtree_sum; 202 | vector chain; 203 | vector label; 204 | vector values; 205 | SegTree s1; 206 | LCA *lca_object; 207 | BinaryLifting *bl_object; 208 | HLD(int n1, vector *edges1, int root1, vector &values1, LCA *lca) { 209 | n = n1; 210 | lca_object = lca; 211 | bl_object = lca->bl_object; 212 | edges = edges1; 213 | rootHere = root1; 214 | big_child.resize(n); 215 | subtree_sum.resize(n); 216 | label.resize(n); 217 | chain.resize(n); 218 | values = values1; 219 | dfsPrecompute(rootHere, -1); 220 | int label_time = 0; 221 | dfsLabels(rootHere, -1, label_time); 222 | for (int i = 0; i < n; i++) 223 | chain[i] = i; 224 | dfsChains(rootHere, -1); 225 | s1 = SegTree(n, values); 226 | for (int i = 0; i < n; i++) { 227 | s1.make_update(label[i], values[i]); 228 | } 229 | // debugHLD(); 230 | } 231 | void dfsPrecompute(int root, int parent) { 232 | subtree_sum[root] = 1; 233 | big_child[root] = -1; 234 | int biggest = -1; 235 | for (auto i : edges[root]) { 236 | if (i != parent) { 237 | dfsPrecompute(i, root); 238 | subtree_sum[root] += subtree_sum[i]; 239 | if (subtree_sum[i] > biggest) { 240 | big_child[root] = i; 241 | biggest = subtree_sum[i]; 242 | } 243 | } 244 | } 245 | } 246 | void dfsLabels(int root, int parent, int &label_time) { 247 | label[root] = label_time++; 248 | if (big_child[root] != -1) 249 | dfsLabels(big_child[root], root, label_time); 250 | for (auto i : edges[root]) 251 | if (i != parent && i != big_child[root]) 252 | dfsLabels(i, root, label_time); 253 | } 254 | void dfsChains(int root, int parent) { 255 | if (big_child[root] != -1) 256 | chain[big_child[root]] = chain[root]; 257 | for (auto i : edges[root]) 258 | if (i != parent) 259 | dfsChains(i, root); 260 | } 261 | void debugHLD() { 262 | debug(big_child); 263 | debug(subtree_sum); 264 | debug(chain); 265 | debug(label); 266 | debug(values); 267 | } 268 | Node queryChain(int here, int toReach) { 269 | Node val = Node(0); 270 | int top; 271 | while (lca_object->level[here] > lca_object->level[toReach]) { 272 | top = chain[here]; 273 | if (lca_object->level[top] <= lca_object->level[toReach]) 274 | top = bl_object->kthParent(here, lca_object->level[here] - lca_object->level[toReach] - 1); 275 | Node a1 = val; 276 | Node a2 = s1.make_query(label[top], label[here]); 277 | val.merge(a1, a2); 278 | here = bl_object->parent[top][0]; 279 | } 280 | return val; 281 | } 282 | ll findAnswer(int u, int v) { 283 | int lca = lca_object->getLCA(u, v); 284 | Node n1 = queryChain(u, lca); 285 | Node n2 = queryChain(v, lca); 286 | Node merged; 287 | merged.merge(n1, n2); 288 | Node n3 = Node(s1.make_query(label[lca], label[lca])); 289 | Node ans; 290 | ans.merge(merged, n3); 291 | return ans.val; 292 | } 293 | void makeUpdateatIndex(int u, ll val) { 294 | s1.make_update(label[u], val); 295 | } 296 | }; 297 | // Change accordingly for edge weights instead of node values 298 | void solve() { 299 | int n, q; 300 | cin >> n >> q; 301 | vector values(n); 302 | for (int i = 0; i < n; i++) 303 | cin >> values[i]; 304 | vector *edges = new vector[n]; 305 | for (int i = 0; i < n - 1; i++) { 306 | int a, b; 307 | cin >> a >> b; 308 | edges[a - 1].pb(b - 1); 309 | edges[b - 1].pb(a - 1); 310 | } 311 | BinaryLifting bl_object = BinaryLifting(n, edges, n, 0); 312 | LCA lca_object = LCA(n, edges, 0, &bl_object); 313 | HLD hld = HLD(n, edges, 0, values, &lca_object); 314 | while (q--) { 315 | int a, b, c; 316 | cin >> a >> b >> c; 317 | if (a == 1) { 318 | hld.makeUpdateatIndex(b - 1, c); 319 | } else { 320 | cout << hld.findAnswer(b - 1, c - 1) << " "; 321 | } 322 | } 323 | } 324 | --------------------------------------------------------------------------------