├── Adv_DS ├── DynamicConnect.md ├── DynamicConnectivity.pdf ├── treap.md ├── treap_.pdf ├── trie(bit).md └── veniceset.md ├── BigInt └── bigint.cpp ├── DP ├── DP_Optimizations │ ├── DNC_DP │ │ ├── ciel.cpp │ │ └── subarrayk.cpp │ └── Knuth │ │ └── Knuth_div.cpp ├── DP_tree │ └── rerooting │ │ ├── Max_white_subtree.cpp │ │ ├── Tree_with_max_cost.cpp │ │ ├── tree_distances2.cpp │ │ └── tree_painting.cpp ├── DigitDP │ ├── Digit DP.pdf │ ├── Digitdp.cpp │ ├── Digitdp.md │ └── Digitdp_ques │ │ ├── 369numbers.cpp │ │ ├── AOPN.cpp │ │ ├── MPRODMUL.cpp │ │ ├── MaximumProduct.cpp │ │ ├── Pattern110.cpp │ │ ├── classy.cpp │ │ ├── encoding.cpp │ │ ├── gone.cpp │ │ ├── lucifer.cpp │ │ ├── magicnumbers.cpp │ │ └── raone.cpp ├── LIS.cpp ├── bounded_knapsack.cpp ├── dp.cpp └── matrixexp.cpp ├── Flows ├── dinic.cpp ├── flow_path.cpp ├── max_match.cpp ├── max_match_N^3.cpp └── mincut.cpp ├── Game └── Game.md ├── Geometry └── convexhull.cpp ├── Graphs ├── Bridges │ └── bridge.cpp ├── Components │ ├── 2D-DSU.cpp │ ├── 2SAT.cpp │ ├── DSU.cpp │ └── scc.cpp ├── Cut_vertices │ └── cut.cpp ├── DAG │ └── topo.cpp ├── Eulerian │ └── hierholzers-algorithm.cpp ├── Kinght_tour │ └── knight.cpp ├── MST │ └── Kruskal.cpp ├── Shortest_paths │ ├── Dijkstra.cpp │ ├── bellman.md │ ├── bellman.pdf │ ├── dijsktra_dig.cpp │ └── floyd.cpp └── Traversals │ ├── Bipartite.cpp │ ├── cycle.cpp │ └── grith.cpp ├── Maths ├── Baby_step_giant_step.pdf ├── Burnside_Lemma.pdf ├── Mobius_.pdf ├── fastexpo.cpp ├── linear_sieve.md ├── mobius.md ├── ncr.md ├── no of divisors.cpp ├── sumofdiv.cpp └── totient.md ├── Polynomials ├── FFT.pdf └── NTT_any_mod.cpp ├── README.md ├── STL └── algolib.md ├── Search ├── BinSearch.md ├── bfs.md ├── dfs.md ├── meet_in_the_middle.cpp ├── subset.cpp └── ternary.md ├── Segtree_Fenwick ├── Fenwick.md └── segtree.md ├── Sqrt ├── Mo.cpp ├── mo_hilbert.cpp ├── sparse_table.cpp └── sqrtdecomp.cpp ├── Stack_Queue ├── max_histogram.cpp └── max_one_rectangle.cpp ├── Strings ├── KMP.cpp ├── Reverse_BWT.cpp ├── Z_algo.cpp ├── dfa.cpp ├── hashing.cpp ├── manacher.cpp ├── suffix_array.cpp ├── suffix_array_fast.cpp ├── suffix_lcp.cpp ├── trie.cpp └── trie.md ├── Techs └── compress.cpp ├── Template.cpp ├── Trees ├── Centroid.cpp ├── LCA _O(1).pdf ├── LCA.cpp ├── TreeDSU.cpp ├── center_tree.cpp ├── diameter.cpp ├── lca_bin.cpp ├── mo_tree_hilbert.cpp ├── mo_trees.cpp ├── prufer.cpp └── subtree.cpp ├── learn.md └── learn.pdf /Adv_DS/DynamicConnect.md: -------------------------------------------------------------------------------- 1 | # Dynamic Connectivity 2 | 3 | ``` 4 | Consider an undirected graph that consists of n nodes and m edges. 5 | There are two types of events that can happen: 6 | A new edge is created between nodes a and b. 7 | An existing edge between nodes a and b is removed. 8 | Your task is to report the number of components after every event. 9 | ``` 10 | [CSES Question](https://cses.fi/problemset/task/2133) 11 | 12 | ```C++ 13 | const int N = 2e5 + 5; 14 | vector t[2 * N]; 15 | 16 | vector queries; // Used to store the output times 17 | map in; // In time for the edges 18 | int ans[N]; 19 | 20 | int parent[N], sz[N]; // DSU requirements 21 | stack st; // Used for rolling back the actions 22 | 23 | int cnt; // Number of components 24 | int n, m, q, eu, ev; 25 | 26 | void make() 27 | { 28 | for (int i = 1; i <= n; i++) 29 | { 30 | parent[i] = i; 31 | sz[i] = 1; 32 | } 33 | cnt = n; 34 | } 35 | 36 | // No path compression as real parent is used in rollbacks 37 | int find(int v) 38 | { 39 | while (v != parent[v]) 40 | v = parent[v]; 41 | return v; 42 | } 43 | 44 | bool merge(int a, int b) 45 | { 46 | a = find(a); 47 | b = find(b); 48 | if (a == b) 49 | return false; 50 | if (sz[a] < sz[b]) 51 | swap(a, b); 52 | sz[a] += sz[b]; 53 | parent[b] = a; 54 | st.push(b); 55 | cnt--; 56 | return true; 57 | } 58 | 59 | void rollback(int moment) 60 | { 61 | while (st.size() > moment) 62 | { 63 | int curr = st.top(); 64 | st.pop(); 65 | sz[parent[curr]] -= sz[curr]; 66 | parent[curr] = curr; 67 | cnt++; 68 | } 69 | } 70 | 71 | void dfs(int v, int l, int r) 72 | { 73 | if (l > r) 74 | return; 75 | 76 | int moment = st.size(); 77 | 78 | // Merge all the edges in the current node 79 | for (auto edge : t[v]) 80 | merge(edge.first, edge.second); 81 | 82 | if (l == r) 83 | { 84 | ans[l] = cnt; 85 | } 86 | else 87 | { 88 | int mid = (l + r) / 2; 89 | dfs(2 * v, l, mid); 90 | dfs(2 * v + 1, mid + 1, r); 91 | } 92 | // Rollback once the dfs of the current node is done. 93 | rollback(moment); 94 | } 95 | 96 | void update(int v, int tl, int tr, int l, int r, int eu, int ev) 97 | { 98 | // No overlap in the intervals 99 | if (l > tr || tl > r) 100 | return; 101 | if (l <= tl && r >= tr) 102 | { 103 | // Active range completely overlaps the segtree range 104 | t[v].pb({eu, ev}); 105 | return; 106 | } 107 | int tm = (tl + tr) / 2; 108 | update(2 * v, tl, tm, l, r, eu, ev); 109 | update(2 * v + 1, tm + 1, tr, l, r, eu, ev); 110 | } 111 | 112 | void upd(int l, int r, int eu, int ev) 113 | { 114 | update(1, 1, q + 1, l, r, eu, ev); 115 | } 116 | 117 | int main() 118 | { 119 | kira; 120 | 121 | cin >> n >> m >> q; 122 | make(); 123 | 124 | for (int i = 0; i < m; i++) 125 | { 126 | cin >> eu >> ev; 127 | if (eu > ev) 128 | swap(eu, ev); 129 | in[{eu, ev}] = 1; 130 | } 131 | 132 | for (int i = 1; i <= q + 1; i++) 133 | { 134 | queries.pb(i); 135 | } 136 | 137 | int qt; 138 | for (int i = 2; i <= q + 1; i++) 139 | { 140 | cin >> qt >> eu >> ev; 141 | if (eu > ev) 142 | swap(eu, ev); 143 | if (qt == 1) 144 | { 145 | if (in.find({eu, ev}) != in.end()) 146 | continue; 147 | in[{eu, ev}] = i; 148 | } 149 | else 150 | { 151 | upd(in[{eu, ev}], i - 1, eu, ev); 152 | in.erase({eu, ev}); 153 | } 154 | } 155 | debug(in); 156 | for (auto edges : in) 157 | { 158 | upd(edges.S, q + 1, edges.F.F, edges.F.S); 159 | } 160 | dfs(1, 1, q + 1); 161 | for (auto x : queries) 162 | p0(ans[x]); 163 | run_time(); 164 | return 0; 165 | } 166 | ``` -------------------------------------------------------------------------------- /Adv_DS/DynamicConnectivity.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tejas01101001/Competitive-coding/d0f29301ae5867d6ace451aa58771f3190589711/Adv_DS/DynamicConnectivity.pdf -------------------------------------------------------------------------------- /Adv_DS/treap.md: -------------------------------------------------------------------------------- 1 | # Treaps 2 | 3 | [Cut and Paste](https://cses.fi/problemset/task/2072) 4 | [Substring Reversals](https://cses.fi/problemset/task/2073) 5 | [Reversal Sums](https://cses.fi/problemset/task/2074) 6 | 7 | ```C++ 8 | // Treap is a data structure that stores pairs (X, Y) in a binary tree. 9 | // Binary search tree by X and a Binary heap by Y. 10 | // Node contains values (X0, Y0) 11 | // All nodes in the left subtree have X < X0 12 | // All nodes in the right subtree have X > X0 13 | // All nodes in both left and right subtrees have Y < Y0. 14 | 15 | 16 | // Random number generator 17 | mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count()); 18 | int get_rand(int l, int r) 19 | { 20 | uniform_int_distribution uid(l, r); 21 | return uid(rng); 22 | } 23 | 24 | // Structure for treap node 25 | struct node 26 | { 27 | node *left, *right; 28 | int prior, size; 29 | ll value; 30 | bool invert; 31 | ll sum; 32 | node(ll v) 33 | { 34 | left = right = NULL; 35 | prior = get_rand(1, 2e9); 36 | size = 1; 37 | value = v; 38 | invert = false; 39 | sum = v; 40 | } 41 | }; 42 | 43 | // Global declaration of treap default as NULL 44 | node *treap; 45 | 46 | int size(node *treap) 47 | { 48 | if (treap == NULL) 49 | return 0; 50 | return treap->size; 51 | } 52 | 53 | ll get(node *treap) 54 | { 55 | if (!treap) 56 | return 0; 57 | // Modified according to question 58 | return treap->sum; 59 | } 60 | 61 | void combine(node *treap) 62 | { 63 | if (treap) 64 | { 65 | // Modified according to question 66 | treap->sum = treap->value + get(treap->left) + get(treap->right); 67 | } 68 | } 69 | 70 | // Used for lazy propogation of reversal 71 | void push(node *treap) 72 | { 73 | if (!treap) 74 | return; 75 | 76 | if (treap->invert) 77 | { 78 | treap->invert = false; 79 | swap(treap->left, treap->right); 80 | if (treap->left) 81 | treap->left->invert ^= 1; 82 | if (treap->right) 83 | treap->right->invert ^= 1; 84 | } 85 | } 86 | 87 | // The following function split implements the splitting operation. 88 | // It recursively splits the treap treap into treaps left and right. 89 | // Left treap contains the first k nodes and right treap contains the remaining nodes. 90 | 91 | void split(node *treap, node *&left, node *&right, int k) 92 | { 93 | if (treap == NULL) 94 | { 95 | left = right = NULL; 96 | } 97 | else 98 | { 99 | push(treap); 100 | if (size(treap->left) < k) 101 | { 102 | // 103 | split(treap->right, treap->right, right, k - size(treap->left) - 1); 104 | left = treap; 105 | } 106 | else 107 | { 108 | split(treap->left, left, treap->left, k); 109 | right = treap; 110 | } 111 | treap->size = size(treap->left) + size(treap->right) + 1; 112 | combine(treap); 113 | } 114 | } 115 | 116 | // The following function merge implements the merging operation. 117 | // Creates a treap that contains first the nodes of the treap left and then the nodes of the treap right. 118 | 119 | void merge(node *&treap, node *left, node *right) 120 | { 121 | push(left); 122 | push(right); 123 | 124 | if (left == NULL) 125 | treap = right; 126 | else if (right == NULL) 127 | treap = left; 128 | else 129 | { 130 | if (left->prior > right->prior) 131 | { 132 | merge(left->right, left->right, right); 133 | treap = left; 134 | } 135 | else 136 | { 137 | merge(right->left, left, right->left); 138 | treap = right; 139 | } 140 | treap->size = size(treap->left) + size(treap->right) + 1; 141 | combine(treap); 142 | } 143 | } 144 | 145 | void rev_subarray(node *&treap, int l, int r) 146 | { 147 | node *prefix, *suffix, *waste, *subarray; 148 | 149 | split(treap, prefix, suffix, r); 150 | split(prefix, waste, subarray, l - 1); 151 | 152 | subarray->invert ^= 1; 153 | 154 | merge(prefix, waste, subarray); 155 | merge(treap, prefix, suffix); 156 | } 157 | 158 | void add_node(ll val) 159 | { 160 | merge(treap, treap, new node(val)); 161 | return; 162 | } 163 | 164 | ll range_sum(node *&treap, int l, int r) 165 | { 166 | node *prefix, *suffix, *waste, *subarray; 167 | 168 | split(treap, prefix, suffix, r); 169 | split(prefix, waste, subarray, l - 1); 170 | 171 | ll ans = subarray->sum; 172 | 173 | merge(prefix, waste, subarray); 174 | merge(treap, prefix, suffix); 175 | 176 | return ans; 177 | } 178 | 179 | void print(node *treap) 180 | { 181 | if (!treap) 182 | return; 183 | push(treap); 184 | print(treap->left); 185 | cout << treap->sum << " "; 186 | print(treap->right); 187 | } 188 | ``` -------------------------------------------------------------------------------- /Adv_DS/treap_.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tejas01101001/Competitive-coding/d0f29301ae5867d6ace451aa58771f3190589711/Adv_DS/treap_.pdf -------------------------------------------------------------------------------- /Adv_DS/trie(bit).md: -------------------------------------------------------------------------------- 1 | # Tries for bits of numbers 2 | 3 | ## MAXXOR AND MINXXOR 4 | 5 | ```C++ 6 | typedef struct data 7 | { 8 | data *bit[2]; 9 | int cnt = 0; 10 | } btrie; 11 | 12 | btrie *head; 13 | 14 | void insert(int x) 15 | { 16 | btrie *node = head; 17 | for (int i = 30; i >= 0; i--) 18 | { 19 | int cbit = (x >> i) & 1; 20 | if (node->bit[cbit] == NULL) 21 | { 22 | node->bit[cbit] = new btrie(); 23 | } 24 | node = node->bit[cbit]; 25 | node->cnt++; 26 | } 27 | } 28 | 29 | void remove(int x) 30 | { 31 | btrie *node = head; 32 | for (int i = 30; i >= 0; i--) 33 | { 34 | int cbit = (x >> i) & 1; 35 | node = node->bit[cbit]; 36 | node->cnt--; 37 | } 38 | } 39 | 40 | int maxxor(int x) 41 | { 42 | btrie *node = head; 43 | int ans = 0; 44 | for (int i = 30; i >= 0; i--) 45 | { 46 | int cbit = (x >> i) & 1; 47 | //MATCH OPP BITS FOR MAXXOR 48 | if (node->bit[cbit ^ 1] != NULL && node->bit[cbit ^ 1]->cnt > 0) 49 | { 50 | ans += (1LL << i); 51 | node = node->bit[cbit ^ 1]; 52 | } 53 | else 54 | node = node->bit[cbit]; 55 | } 56 | return ans; 57 | } 58 | 59 | int minxor(int x) 60 | { 61 | btrie *node = head; 62 | int ans = 0; 63 | for (int i = 30; i >= 0; i--) 64 | { 65 | int cbit = (x >> i) & 1; 66 | //MATCH SAME BITS FOR MINXOR 67 | if (node->bit[cbit] != NULL && node->bit[cbit]->cnt > 0) 68 | node = node->bit[cbit]; 69 | else 70 | { 71 | ans += (1LL << i); 72 | node = node->bit[cbit ^ 1]; 73 | } 74 | } 75 | return ans; 76 | } 77 | 78 | int main() 79 | { 80 | kira; 81 | int t, x; 82 | char op; 83 | cin >> t; 84 | head = new btrie(); 85 | //Maxxor then insert(0) not for minxor 86 | insert(0); 87 | while (t--) 88 | { 89 | cin >> op >> x; 90 | if (op == '+') 91 | insert(x); 92 | else if (op == '-') 93 | remove(x); 94 | else 95 | { 96 | int ans = maxxor(x); 97 | p1(ans); 98 | } 99 | } 100 | return 0; 101 | } 102 | ``` 103 | 104 | ## MAXXOR SUBARRAY: 105 | 106 | Insert prefix xors in the trie and query for maxxor 107 | for each subarray ending with a[i] 108 | 109 | [Maximum subarray xor](https://cses.fi/problemset/result/278806/) -------------------------------------------------------------------------------- /Adv_DS/veniceset.md: -------------------------------------------------------------------------------- 1 | # Venice Set 2 | 3 | 1. Imagine you have an empty land and the government can make queries of the following type: 4 | 1. Make a building with A floors. 5 | 2. Remove a building with B floors. 6 | 3. Remove C floors from all the buildings. 7 | 4. (A lot of buildings can be vanished) 8 | 5. Which is the smallest standing building. 9 | 6. (Obviously buildings which are already banished dont count) 10 | 2. The operations 1,2 and 4 seems very easy with a set, but the 3 is very cost effective probably O(N) so you might need a lot of workers. 11 | 3. But what if instead of removing C floors we just fill the streets with enough water (as in venice) to cover up the first C floors of all the buildings : 12 | 4. Well that seems like cheating but at least those floor are now vanished :). So in order to do that we apart from the SET we can maintain a global variable which is the water level. 13 | 5. So in fact if we have an element and want to know the number of floors it has we can just do height - water_level and in fact after water level is for example 80. 14 | 6. If we want to make a building of 3 floors we must make it of 83 floors so that it can tough the land. So the implementation of this technique might look like this. 15 | 16 | ```C++ 17 | struct veniceset 18 | { 19 | multiset s; 20 | ll water_level = 0; 21 | 22 | void add(ll v) 23 | { 24 | s.insert(v + water_level); 25 | } 26 | void remove(ll v) 27 | { 28 | s.erase(s.find(v + water_level)); 29 | } 30 | void updall(ll v) 31 | { 32 | water_level += v; 33 | } 34 | ll getmin() 35 | { 36 | return *s.begin() - water_level; 37 | } 38 | ll size() 39 | { 40 | return s.size(); 41 | } 42 | }; 43 | ``` -------------------------------------------------------------------------------- /DP/DP_Optimizations/DNC_DP/ciel.cpp: -------------------------------------------------------------------------------- 1 | 2 | //https://codeforces.com/problemset/problem/321/E 3 | 4 | const int N = 4e3 + 5; 5 | ll dp_prev[N], dp_curr[N]; 6 | ll a[N][N], mat[N][N]; 7 | 8 | ll cost(int x, int i) 9 | { 10 | return mat[i][i] + mat[x - 1][x - 1] - mat[i][x - 1] - mat[x - 1][i]; 11 | } 12 | 13 | void compute(int l, int r, int optl, int optr) 14 | { 15 | if (l > r) 16 | return; 17 | 18 | int mid = (l + r) / 2; 19 | 20 | pll best = mp(INF, -1); 21 | for (int x = optl; x <= min(mid, optr); x++) 22 | { 23 | best = min(best, {dp_prev[x] + cost(x + 1, mid), x}); 24 | } 25 | 26 | dp_curr[mid] = best.first; 27 | int opt = best.second; 28 | 29 | compute(l, mid - 1, optl, opt); 30 | compute(mid + 1, r, opt, optr); 31 | } 32 | 33 | int main() 34 | { 35 | kira; 36 | 37 | ll n, k; 38 | cin >> n >> k; 39 | 40 | memset(dp_curr, 0, sizeof(dp_curr)); 41 | memset(dp_prev, 0, sizeof(dp_prev)); 42 | 43 | for (int i = 1; i <= n; i++) 44 | { 45 | for (int j = 1; j <= n; j++) 46 | { 47 | cin >> a[i][j]; 48 | mat[i][j] = mat[i - 1][j] + mat[i][j - 1] - mat[i - 1][j - 1] + a[i][j]; 49 | } 50 | } 51 | 52 | for (int i = 0; i <= n; i++) 53 | { 54 | dp_prev[i] = 0; 55 | dp_curr[i] = mat[i][i]; 56 | } 57 | 58 | for (int i = 0; i < k - 1; i++) 59 | { 60 | for (int j = 0; j <= n; j++) 61 | { 62 | dp_prev[j] = dp_curr[j]; 63 | } 64 | compute(1, n, 1, n); 65 | } 66 | 67 | p1(dp_curr[n] / 2); 68 | 69 | run_time(); 70 | return 0; 71 | } -------------------------------------------------------------------------------- /DP/DP_Optimizations/DNC_DP/subarrayk.cpp: -------------------------------------------------------------------------------- 1 | 2 | //https://cses.fi/problemset/task/2086 3 | 4 | const int N = 3e3 + 5; 5 | ll dp_prev[N], dp_curr[N]; 6 | ll a[N], pre[N]; 7 | 8 | ll cost(int x, int i) 9 | { 10 | return (pre[i] - pre[x - 1]) * (pre[i] - pre[x - 1]); 11 | } 12 | 13 | void compute(int l, int r, int optl, int optr) 14 | { 15 | if (l > r) 16 | return; 17 | 18 | int mid = (l + r) / 2; 19 | 20 | pll best = mp(INF, -1); 21 | for (int x = optl; x <= min(mid, optr); x++) 22 | { 23 | best = min(best, {dp_prev[x] + cost(x + 1, mid), x}); 24 | } 25 | 26 | dp_curr[mid] = best.first; 27 | int opt = best.second; 28 | 29 | compute(l, mid - 1, optl, opt); 30 | compute(mid + 1, r, opt, optr); 31 | } 32 | 33 | int main() 34 | { 35 | kira; 36 | 37 | ll n, k; 38 | cin >> n >> k; 39 | 40 | memset(dp_curr, 0, sizeof(dp_curr)); 41 | memset(dp_prev, 0, sizeof(dp_prev)); 42 | 43 | for (int i = 1; i <= n; i++) 44 | { 45 | cin >> a[i]; 46 | pre[i] = pre[i - 1] + a[i]; 47 | } 48 | 49 | for (int i = 0; i <= n; i++) 50 | { 51 | dp_prev[i] = 0; 52 | dp_curr[i] = pre[i] * pre[i]; 53 | } 54 | 55 | for (int i = 0; i < k - 1; i++) 56 | { 57 | for (int j = 0; j <= n; j++) 58 | { 59 | dp_prev[j] = dp_curr[j]; 60 | } 61 | compute(1, n, 1, n); 62 | } 63 | 64 | p1(dp_curr[n]); 65 | 66 | run_time(); 67 | return 0; 68 | } -------------------------------------------------------------------------------- /DP/DP_Optimizations/Knuth/Knuth_div.cpp: -------------------------------------------------------------------------------- 1 | 2 | int main() 3 | { 4 | kira; 5 | 6 | ll n; 7 | cin >> n; 8 | 9 | ll dp[n + 1][n + 1]; 10 | ll h[n + 1][n + 1]; 11 | ll a[n + 1], pre[n + 1] = {0}; 12 | 13 | for (int i = 1; i <= n; i++) 14 | { 15 | cin >> a[i]; 16 | pre[i] = pre[i - 1] + a[i]; 17 | } 18 | 19 | for (int len = 1; len <= n; len++) 20 | { 21 | for (int i = 1; i <= n - len + 1; i++) 22 | { 23 | int j = i + len - 1; 24 | if (len == 1) 25 | { 26 | dp[i][j] = 0; 27 | h[i][j] = i; 28 | continue; 29 | } 30 | if (len == 2) 31 | { 32 | dp[i][j] = a[i] + a[j]; 33 | h[i][j] = i; 34 | continue; 35 | } 36 | 37 | dp[i][j] = INF; 38 | ll curr; 39 | for (int k = h[i][j - 1]; k <= h[i + 1][j]; k++) 40 | { 41 | 42 | curr = dp[i][k] + dp[k + 1][j] + pre[j] - pre[i - 1]; 43 | if (dp[i][j] > curr) 44 | { 45 | dp[i][j] = curr; 46 | h[i][j] = k; 47 | } 48 | } 49 | } 50 | } 51 | p1(dp[1][n]); 52 | 53 | run_time(); 54 | return 0; 55 | } -------------------------------------------------------------------------------- /DP/DP_tree/rerooting/Max_white_subtree.cpp: -------------------------------------------------------------------------------- 1 | //https://codeforces.com/contest/1324/problem/F 2 | 3 | //https://codeforces.com/contest/1324/submission/74288042 4 | 5 | void dfs(int s,int e) 6 | { 7 | dp[s]=a[s]; 8 | for(auto u:adj[s]) 9 | { 10 | if(u==e)continue; 11 | dfs(u,s); 12 | dp[s]+=max(0ll,dp[u]); 13 | } 14 | } 15 | void dfs2(int s,int e,ll ans) 16 | { 17 | res[s]=ans; 18 | for(auto u:adj[s]) 19 | { 20 | if(u==e)continue; 21 | dfs2(u,s,dp[u]+max(0ll,ans-max(0ll,dp[u]))); 22 | } 23 | return; 24 | } 25 | 26 | //https://codeforces.com/contest/1324/submission/74294424 27 | 28 | void dfs(int s, int e) 29 | { 30 | dp[s] = a[s]; 31 | for (auto u : adj[s]) 32 | { 33 | if (u == e) 34 | continue; 35 | dfs(u, s); 36 | dp[s] += max(0ll, dp[u]); 37 | } 38 | } 39 | 40 | void dfs2(int s, int e) 41 | { 42 | res[s] = dp[s]; 43 | for (auto u : adj[s]) 44 | { 45 | if (u == e) 46 | continue; 47 | dp[s] -= max(0ll, dp[u]); 48 | dp[u] += max(0ll, dp[s]); 49 | dfs2(u, s); 50 | dp[u] -= max(0ll, dp[s]); 51 | dp[s] += max(0ll, dp[u]); 52 | } 53 | return; 54 | } 55 | -------------------------------------------------------------------------------- /DP/DP_tree/rerooting/Tree_with_max_cost.cpp: -------------------------------------------------------------------------------- 1 | //https://codeforces.com/contest/1092/problem/F 2 | //https://codeforces.com/contest/1092/submission/74304035 3 | 4 | const int N = 2e5 + 5; 5 | vector adj[N]; 6 | ll sum[N], n; 7 | ll a[N]; 8 | ll ans = 0, res = 0; 9 | void dfs(int s, int e = -1, ll h = 0) 10 | { 11 | res += a[s] * h; 12 | sum[s] = a[s]; 13 | for (auto u : adj[s]) 14 | { 15 | if (u == e) 16 | continue; 17 | dfs(u, s, h + 1); 18 | sum[s] += sum[u]; 19 | } 20 | } 21 | void dfs2(int s, int e) 22 | { 23 | res = max(res, ans); 24 | for (auto u : adj[s]) 25 | { 26 | if (u == e) 27 | continue; 28 | 29 | ans -= sum[u]; 30 | sum[s] -= sum[u]; 31 | ans += sum[s]; 32 | sum[u] += sum[s]; 33 | 34 | dfs2(u, s); 35 | 36 | sum[u] -= sum[s]; 37 | ans -= sum[s]; 38 | sum[s] += sum[u]; 39 | ans += sum[u]; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /DP/DP_tree/rerooting/tree_distances2.cpp: -------------------------------------------------------------------------------- 1 | //https://cses.fi/problemset/task/1133 2 | //https://cses.fi/problemset/result/377876/ 3 | 4 | void dfs(int s = 1, int e = -1, int h = 0) 5 | { 6 | siz[s] = 1; 7 | dis[s] = h; 8 | for (auto u : adj[s]) 9 | { 10 | if (u == e) 11 | continue; 12 | dfs(u, s, h + 1); 13 | siz[s] += siz[u]; 14 | sum[s] += sum[u] + siz[u]; 15 | } 16 | } 17 | 18 | void dfs2(int s, int e) 19 | { 20 | ans[s] = sum[s]; 21 | for (auto u : adj[s]) 22 | { 23 | if (u == e) 24 | continue; 25 | 26 | sum[s] -= sum[u]; 27 | sum[s] -= siz[u]; 28 | siz[s] -= siz[u]; 29 | siz[u] += siz[s]; 30 | sum[u] += siz[s]; 31 | sum[u] += sum[s]; 32 | 33 | dfs2(u, s); 34 | 35 | sum[u] -= sum[s]; 36 | sum[u] -= siz[s]; 37 | siz[u] -= siz[s]; 38 | siz[s] += siz[u]; 39 | sum[s] += siz[u]; 40 | sum[s] += sum[u]; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /DP/DP_tree/rerooting/tree_painting.cpp: -------------------------------------------------------------------------------- 1 | //https://codeforces.com/contest/1187/problem/E 2 | //https://codeforces.com/contest/1187/submission/74281657 3 | 4 | 5 | void dfs(int s,int e) 6 | { 7 | sz[s]=1; 8 | for(auto u:adj[s]) 9 | { 10 | if(u==e)continue; 11 | dfs(u,s); 12 | sz[s]+=sz[u]; 13 | } 14 | ans+=sz[s]; 15 | return; 16 | } 17 | 18 | void dfs2(int s,int e,ll ans) 19 | { 20 | for(auto u:adj[s]) 21 | { 22 | if(u==e)continue; 23 | res=max(ans-2*sz[u]+n,res); 24 | dfs2(u,s,ans-2*sz[u]+n); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /DP/DigitDP/Digit DP.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tejas01101001/Competitive-coding/d0f29301ae5867d6ace451aa58771f3190589711/DP/DigitDP/Digit DP.pdf -------------------------------------------------------------------------------- /DP/DigitDP/Digitdp.cpp: -------------------------------------------------------------------------------- 1 | 1)There are many types of problems that ask to count the number 2 | of integers ‘x‘ between two integers say ‘a‘ and ‘b‘ such that 3 | x satisfies a specific property that can be related to its digits. 4 | 5 | 2)G(x) tells the number of such integers between 1 to x 6 | (inclusively), then the number of such integers between a and b 7 | can be given by G(b) – G(a-1). 8 | 9 | 3)tn tn-1 tn-2 … t2 t1 10 | as the decimal representation where ti tells the i-th digit from 11 | the right. The leftmost digit tn is the most significant digit. 12 | 13 | 4)Now, after representing the given number this way we generate 14 | the numbers less than the given number and simultaneously 15 | calculate using DP, if the number satisfy the given property. 16 | 17 | We start generating integers having number of digits = 1 and 18 | then till number of digits = n. Integers having less number of 19 | digits than n can be analyzed by setting the leftmost digits to 20 | be zero. 21 | 22 | 5)Convert the given number to a string. 23 | say sn sn-1 .... s1. 24 | 25 | 6)Declare the string globally to avoid useless recursive calls. 26 | 27 | 7)Standard digit dp question. 28 | 29 | Lets call some positive integer classy if its decimal 30 | representation contains no more than 3 non-zero digits. 31 | 32 | You are given a segment [𝐿;𝑅]. 33 | Count the number of classy integers 𝑥 such that 𝐿≤𝑥≤𝑅. 34 | 35 | 36 | >N: upper limit in number of digits in number. 37 | >M: upper limit of Max value of function G(x) 38 | >2: tight specifies whether we are free to chose any number 39 | as the current digit. 40 | 41 | int dp[N][M][2]; 42 | string s; 43 | 44 | int solve(int pos, int cnt, int t) 45 | { 46 | if (pos == int(s.size())) 47 | { 48 | return cnt <= 3; 49 | } 50 | 51 | if (dp[pos][cnt][t] != -1) 52 | return dp[pos][cnt][t]; 53 | 54 | int lim = t ? s[pos] - '0' : 9; 55 | int ans = 0; 56 | 57 | for (int i = 0; i <= lim; i++) 58 | { 59 | ans += solve(pos + 1, cnt + (i != 0), t & (i == lim)); 60 | } 61 | 62 | return dp[pos][cnt][t] = ans; 63 | } 64 | 65 | int main() 66 | { 67 | cin >> a >> b; 68 | 69 | int i = a.size() - 1; 70 | while (a[i] == '0') 71 | { 72 | a[i] == '9'; 73 | i--; 74 | } 75 | a[i]--; 76 | 77 | s = a; 78 | memset(dp, -1, sizeof(dp)); 79 | int l = solve(0, 0, 1); 80 | 81 | s = b; 82 | memset(dp, -1, sizeof(dp)); 83 | int r = solve(0, 0, 1); 84 | 85 | cout << r - l; 86 | } 87 | -------------------------------------------------------------------------------- /DP/DigitDP/Digitdp.md: -------------------------------------------------------------------------------- 1 | # Digit DP 2 | 3 | 1. There are many types of problems that ask to count the number 4 | of integers ‘x‘ between two integers say ‘a‘ and ‘b‘ such that 5 | x satisfies a specific property that can be related to its digits. 6 | 7 | 2. G(x) tells the number of such integers between 1 to x 8 | (inclusively), then the number of such integers between a and b 9 | can be given by G(b) – G(a-1). 10 | 11 | 3. tn tn-1 tn-2 … t2 t1 12 | as the decimal representation where ti tells the i-th digit from 13 | the right. The leftmost digit tn is the most significant digit. 14 | 15 | 4. Now, after representing the given number this way we generate 16 | the numbers less than the given number and simultaneously 17 | calculate using DP, if the number satisfy the given property. 18 | 19 | 5. We start generating integers having number of digits = 1 and 20 | then till number of digits = n. 21 | 22 | 6. Integers having less number of 23 | digits than n can be analyzed by setting the leftmost digits to 24 | be zero. 25 | 26 | 7. Convert the given number to a string. 27 | say sn sn-1 .... s1. 28 | 29 | 8. Declare the string globally to avoid useless recursive calls. 30 | 31 | 9. Standard digit dp question. 32 | 33 | ## Question Classy Numbers 34 | 35 | - Lets call some positive integer classy if its decimal 36 | representation contains no more than 3 non-zero digits. 37 | 38 | - You are given a segment [𝐿,𝑅]. 39 | Count the number of classy integers 𝑥 such that 𝐿≤𝑥≤𝑅. 40 | 41 | 42 | - N: upper limit in number of digits in number. 43 | - M: upper limit of Max value of function G(x) 44 | - 2: tight specifies whether we are free to chose any number as the current digit. 45 | 46 | ```C++ 47 | int dp[N][M][2]; 48 | string s; 49 | 50 | int solve(int pos, int cnt, int t) 51 | { 52 | if (pos == int(s.size())) 53 | { 54 | return cnt <= 3; 55 | } 56 | 57 | if (dp[pos][cnt][t] != -1) 58 | return dp[pos][cnt][t]; 59 | 60 | int lim = t ? s[pos] - '0' : 9; 61 | int ans = 0; 62 | 63 | for (int i = 0; i <= lim; i++) 64 | { 65 | ans += solve(pos + 1, cnt + (i != 0), t & (i == lim)); 66 | } 67 | 68 | return dp[pos][cnt][t] = ans; 69 | } 70 | 71 | int main() 72 | { 73 | cin >> a >> b; 74 | 75 | int i = a.size() - 1; 76 | while (a[i] == '0') 77 | { 78 | a[i] == '9'; 79 | i--; 80 | } 81 | a[i]--; 82 | 83 | s = a; 84 | memset(dp, -1, sizeof(dp)); 85 | int l = solve(0, 0, 1); 86 | 87 | s = b; 88 | memset(dp, -1, sizeof(dp)); 89 | int r = solve(0, 0, 1); 90 | 91 | cout << r - l; 92 | } 93 | ``` -------------------------------------------------------------------------------- /DP/DigitDP/Digitdp_ques/369numbers.cpp: -------------------------------------------------------------------------------- 1 | //https://www.spoj.com/problems/NUMTSN/ 2 | //BROWNIE TK 3 | 4 | #include 5 | typedef long long int ll; 6 | typedef unsigned long long int ull; 7 | typedef long double ldb; 8 | 9 | 10 | #define pb push_back 11 | #define popb pop_back() 12 | #define pf push_front 13 | #define popf pop_front() 14 | 15 | #define si size() 16 | #define be begin() 17 | #define en end() 18 | #define all(v) v.be, v.en 19 | 20 | #define le length() 21 | #define mp make_pair 22 | #define mt make_tuple 23 | #define acc(v) accumulate(all(v), 0) 24 | #define F first 25 | #define S second 26 | 27 | #define pll pair 28 | #define pii pair 29 | #define pil pair 30 | 31 | #define forz(i, n) for (int i = 0; i < n; i++) 32 | #define fore(i, m, n) for (int i = m; i <= n; i++) 33 | #define rforz(i, n) for (int i = n - 1; i >= 0; i--) 34 | #define rfore(i, m, n) for (int i = n; i >= m; i--) 35 | 36 | #define deci(n) fixed << setprecision(n) 37 | #define high(n) __builtin_popcount(n) 38 | #define highll(n) __builtin_popcountll(n) 39 | #define parity(n) __builtin_parity(n) 40 | #define ctz(n) __builtin_ctz(n) 41 | 42 | #define bset(a, p) ((a) | (1ll << (p))) 43 | #define bchk(a, p) ((a) & (1ll << (p))) 44 | #define bxor(a, p) ((a) ^ (1ll << (p))); 45 | #define brem(a, p) (bchk(a, p) ? (bxor(a, p)) : (a)) 46 | 47 | #define lb lower_bound 48 | #define ub upper_bound 49 | #define er equal_range 50 | 51 | #define findnot find_first_not_of 52 | 53 | #define maxe *max_element 54 | #define mine *min_element 55 | 56 | #define mod 1000000007 57 | #define mod2 998244353 58 | #define gcd __gcd 59 | #define kira ios::sync_with_stdio(0), cin.tie(0), cout.tie(0) 60 | 61 | #define endl "\n" 62 | #define p0(a) cout << a << " " 63 | #define p1(a) cout << a << endl 64 | #define p2(a, b) cout << a << " " << b << endl 65 | #define p3(a, b, c) cout << a << " " << b << " " << c << endl 66 | #define p4(a, b, c, d) cout << a << " " << b << " " << c << " " << d << endl 67 | 68 | #define oset tree, rb_tree_tag, tree_order_statistics_node_update> 69 | #define osetlli tree, rb_tree_tag, tree_order_statistics_node_update> 70 | 71 | #define ofk order_of_key 72 | #define fbo find_by_order 73 | using namespace std; 74 | 75 | 76 | ll power(ll x, ll y, ll p) 77 | { 78 | ll res = 1; 79 | x = x % p; 80 | while (y > 0) 81 | { 82 | if (y & 1) 83 | res = (res * x) % p; 84 | y = y >> 1; 85 | x = (x * x) % p; 86 | } 87 | return res; 88 | } 89 | ll modi(ll a, ll m) { return power(a, m - 2, m); } 90 | 91 | string s; 92 | ll dp[51][18][18][18][2]; 93 | ll solve(int pos, int s3, int s6, int s9, int t) 94 | { 95 | if (s3 >= 17 || s6 >= 17 || s9 >= 17) 96 | return 0; 97 | int k = int(s.si); 98 | if (pos == k) 99 | { 100 | if (s3 == s6 && s6 == s9 && s3 >= 1) 101 | return 1; 102 | return 0; 103 | } 104 | 105 | if (dp[pos][s3][s6][s9][t] != -1) 106 | return dp[pos][s3][s6][s9][t]; 107 | 108 | int lim = t ? s[pos] - '0' : 9; 109 | int nt = t; 110 | ll ans = 0; 111 | for (int i = 0; i <= lim; i++) 112 | { 113 | if (i != lim) 114 | nt = 0; 115 | else 116 | nt = t; 117 | ans = (ans + solve(pos + 1, s3+(i==3), s6+(i==6), s9+(i==9), nt) % mod) % mod; 118 | 119 | } 120 | return dp[pos][s3][s6][s9][t] = ans; 121 | } 122 | int main() 123 | { 124 | kira; 125 | int nc; 126 | string a, b; 127 | cin >> nc; 128 | while (nc--) 129 | { 130 | cin >> a >> b; 131 | int i = int(a.si) - 1; 132 | while (a[i] == '0') 133 | { 134 | a[i] = '9'; 135 | i--; 136 | } 137 | a[i]--; 138 | memset(dp, -1, sizeof(dp)); 139 | s = a; 140 | ll y = solve(0, 0, 0, 0, 1); 141 | memset(dp, -1, sizeof(dp)); 142 | s = b; 143 | ll x = solve(0, 0, 0, 0, 1); 144 | 145 | cout << (x - y + mod) % mod << endl; 146 | } 147 | return 0; 148 | } 149 | -------------------------------------------------------------------------------- /DP/DigitDP/Digitdp_ques/AOPN.cpp: -------------------------------------------------------------------------------- 1 | //https://codeforces.com/contest/1326/problem/C 2 | //BROWNIE TK 3 | 4 | #include 5 | typedef long long int ll; 6 | typedef unsigned long long int ull; 7 | typedef long double ldb; 8 | 9 | #include 10 | #include 11 | using namespace __gnu_pbds; 12 | 13 | #define pb push_back 14 | #define popb pop_back() 15 | #define pf push_front 16 | #define popf pop_front() 17 | 18 | #define si size() 19 | #define be begin() 20 | #define en end() 21 | #define all(v) v.be, v.en 22 | 23 | #define le length() 24 | #define mp make_pair 25 | #define mt make_tuple 26 | #define acc(v) accumulate(all(v), 0) 27 | #define F first 28 | #define S second 29 | 30 | #define pll pair 31 | #define pii pair 32 | #define pil pair 33 | 34 | #define forz(i, n) for (int i = 0; i < n; i++) 35 | #define fore(i, m, n) for (int i = m; i <= n; i++) 36 | #define rforz(i, n) for (int i = n - 1; i >= 0; i--) 37 | #define rfore(i, m, n) for (int i = n; i >= m; i--) 38 | 39 | #define deci(n) fixed << setprecision(n) 40 | #define high(n) __builtin_popcount(n) 41 | #define highll(n) __builtin_popcountll(n) 42 | #define parity(n) __builtin_parity(n) 43 | #define ctz(n) __builtin_ctz(n) 44 | 45 | #define bset(a, p) ((a) | (1ll << (p))) 46 | #define bchk(a, p) ((a) & (1ll << (p))) 47 | #define bxor(a, p) ((a) ^ (1ll << (p))); 48 | #define brem(a, p) (bchk(a, p) ? (bxor(a, p)) : (a)) 49 | /*SOME BITMASK KNOWLEDGE 50 | 1)x & (x - 1):sets the last one bit of x to zero 51 | power of two exactly when x & (x − 1) = 0. 52 | 2)x & -x:sets all the one bits to zero, except last one bit 53 | 3)x | (x - 1):inverts all the bits after the last one bit*/ 54 | 55 | #define lb lower_bound 56 | #define ub upper_bound 57 | #define er equal_range 58 | 59 | #define findnot find_first_not_of 60 | 61 | #define maxe *max_element 62 | #define mine *min_element 63 | 64 | #define mod2 1000000007 65 | #define mod 998244353 66 | #define gcd __gcd 67 | #define kira ios::sync_with_stdio(0), cin.tie(0), cout.tie(0) 68 | 69 | #define endl "\n" 70 | #define p0(a) cout << a << " " 71 | #define p1(a) cout << a << endl 72 | #define p2(a, b) cout << a << " " << b << endl 73 | #define p3(a, b, c) cout << a << " " << b << " " << c << endl 74 | #define p4(a, b, c, d) cout << a << " " << b << " " << c << " " << d << endl 75 | 76 | #define oset tree, rb_tree_tag, tree_order_statistics_node_update> 77 | #define osetlli tree, rb_tree_tag, tree_order_statistics_node_update> 78 | //member functions : 79 | //1. order_of_key(k) : number of elements sbtriectly lesser than k 80 | //2. find_by_order(k) : k-th element in the set 81 | #define ofk order_of_key 82 | #define fbo find_by_order 83 | using namespace std; 84 | 85 | /*STD funcions*/ 86 | ll power(ll x, ll y, ll p) 87 | { 88 | ll res = 1; 89 | x = x % p; 90 | while (y > 0) 91 | { 92 | if (y & 1) 93 | res = (res * x) % p; 94 | y = y >> 1; 95 | x = (x * x) % p; 96 | } 97 | return res; 98 | } 99 | ll modi(ll a, ll m) { return power(a, m - 2, m); } 100 | /*CODE BEGINS*/ 101 | string s; 102 | ll dp[20][11][11][2][2][2][2]; 103 | ll solve(ll pos, ll las, ll slas, ll even, ll odd, ll t, ll st) 104 | { 105 | if (pos == int(s.si)) 106 | return (even && odd); 107 | 108 | if (dp[pos][las][slas][even][odd][t][st] != -1) 109 | return dp[pos][las][slas][even][odd][t][st]; 110 | 111 | ll ans = 0; 112 | if (st == 0) 113 | { 114 | ans += solve(pos + 1, las, slas, even, odd, t & (s[pos] == '0'), st); 115 | ll lim = t ? s[pos] - '0' : 9; 116 | for (ll i = 1; i <= lim; i++) 117 | { 118 | ans += solve(pos + 1, i, slas, even, odd , t & (lim== i), 1ll); 119 | } 120 | } 121 | else 122 | { 123 | ll lim = t ? s[pos] - '0' : 9; 124 | for (int i = 0; i <= lim; i++) 125 | { 126 | ans += solve(pos + 1, i, las, even |(las == i), odd | (slas == i), t & (lim == i), 1ll); 127 | } 128 | } 129 | return dp[pos][las][slas][even][odd][t][st]=ans; 130 | } 131 | int main() 132 | { 133 | kira; 134 | int nt; 135 | cin >> nt; 136 | string a, b; 137 | while (nt--) 138 | { 139 | cin >> a >> b; 140 | memset(dp, -1, sizeof(dp)); 141 | s = a; 142 | ll y = solve(0,10,10,0,0,1,0); 143 | memset(dp, -1, sizeof(dp)); 144 | s = b; 145 | ll x = solve(0,10,10,0,0,1,0); 146 | cout << x - y << endl; 147 | } 148 | return 0; 149 | } 150 | -------------------------------------------------------------------------------- /DP/DigitDP/Digitdp_ques/MPRODMUL.cpp: -------------------------------------------------------------------------------- 1 | //https://www.codechef.com/viewsolution/31873586 2 | //BROWNIE TK 3 | 4 | #include 5 | using namespace std; 6 | 7 | typedef long long int ll; 8 | typedef unsigned long long int ull; 9 | typedef long double ldb; 10 | 11 | #include 12 | #include 13 | using namespace __gnu_pbds; 14 | 15 | #define pb push_back 16 | #define popb pop_back() 17 | #define pf push_front 18 | #define popf pop_front() 19 | 20 | #define si size() 21 | #define be begin() 22 | #define en end() 23 | #define all(v) v.be, v.en 24 | 25 | #define le length() 26 | #define mp make_pair 27 | #define mt make_tuple 28 | #define acc(v) accumulate(all(v), 0) 29 | #define F first 30 | #define S second 31 | 32 | #define pll pair 33 | #define pii pair 34 | #define pil pair 35 | 36 | #define forz(i, n) for (int i = 0; i < n; i++) 37 | #define fore(i, m, n) for (int i = m; i <= n; i++) 38 | #define rforz(i, n) for (int i = n - 1; i >= 0; i--) 39 | #define rfore(i, m, n) for (int i = n; i >= m; i--) 40 | 41 | #define deci(n) fixed << setprecision(n) 42 | #define high(n) __builtin_popcount(n) 43 | #define highll(n) __builtin_popcountll(n) 44 | #define parity(n) __builtin_parity(n) 45 | #define ctz(n) __builtin_ctz(n) 46 | 47 | #define bset(a, p) ((a) | (1ll << (p))) 48 | #define bchk(a, p) ((a) & (1ll << (p))) 49 | #define bxor(a, p) ((a) ^ (1ll << (p))); 50 | #define brem(a, p) (bchk(a, p) ? (bxor(a, p)) : (a)) 51 | 52 | #define lb lower_bound 53 | #define ub upper_bound 54 | #define er equal_range 55 | 56 | #define findnot find_first_not_of 57 | 58 | #define maxe *max_element 59 | #define mine *min_element 60 | 61 | #define mod2 998244353 62 | #define mod3 1000000007 63 | #define gcd __gcd 64 | #define kira ios::sync_with_stdio(0), cin.tie(0), cout.tie(0) 65 | 66 | #define endl "\n" 67 | #define p0(a) cout << a << " " 68 | #define p1(a) cout << a << endl 69 | #define p2(a, b) cout << a << " " << b << endl 70 | #define p3(a, b, c) cout << a << " " << b << " " << c << endl 71 | #define p4(a, b, c, d) cout << a << " " << b << " " << c << " " << d << endl 72 | 73 | #define oset tree, rb_tree_tag, tree_order_statistics_node_update> 74 | #define osetlli tree, rb_tree_tag, tree_order_statistics_node_update> 75 | //member functions : 76 | //1. order_of_key(k) : number of elements sbtriectly lesser than k 77 | //2. find_by_order(k) : k-th element in the set 78 | #define ofk order_of_key 79 | #define fbo find_by_order 80 | 81 | ll mod; 82 | 83 | ll power(ll x, ll y, ll p) 84 | { 85 | ll res = 1; 86 | x = x % p; 87 | while (y > 0) 88 | { 89 | if (y & 1) 90 | res = (res * x) % p; 91 | y = y >> 1; 92 | x = (x * x) % p; 93 | } 94 | return res; 95 | } 96 | ll modi(ll a, ll m) { return power(a, m - 2, m); } 97 | 98 | string s, t; 99 | pair dp[20][2][2][2][100][10]; 100 | 101 | pair solve(int pos, int t1, int t2, int srt, int rem, int g) 102 | { 103 | if (pos == int(s.si)) 104 | { 105 | if (rem == 0) 106 | { 107 | return {1, ""}; 108 | } 109 | else 110 | return {0, ""}; 111 | } 112 | if (g < 10) 113 | { 114 | if (dp[pos][t1][t2][srt][rem][g].F != -1) 115 | return dp[pos][t1][t2][srt][rem][g]; 116 | } 117 | 118 | ll st = t1 ? t[pos] - '0' : 0; 119 | ll et = t2 ? s[pos] - '0' : 9; 120 | 121 | ll res = -1; 122 | string ans = ""; 123 | 124 | for (ll i = et; i >= st; i--) 125 | { 126 | ll val; 127 | if (srt == 0 && i == 0) 128 | val = 1; 129 | else 130 | val = i; 131 | if (pos == int(s.si) - 1) 132 | { 133 | if ((i == 0) || (g % i != 0)) 134 | continue; 135 | } 136 | int ng = g; 137 | if (i != 0) 138 | { 139 | ng =gcd(ll(g), i); 140 | } 141 | pair k = solve(pos + 1, t1 & (i == st), t2 & (i == et), srt | (i > 0), (rem * 10 + i) % mod, ng); 142 | if ((val * k.F) >= res) 143 | { 144 | res = (k.F * val); 145 | if (srt == 0 && i == 0) 146 | { 147 | ans = k.S; 148 | } 149 | else 150 | { 151 | reverse(all(k.S)); 152 | k.S.pb('0' + i); 153 | reverse(all(k.S)); 154 | ans = k.S; 155 | } 156 | } 157 | } 158 | if (g < 10) 159 | dp[pos][t1][t2][srt][rem][g] = {res, ans}; 160 | return {res, ans}; 161 | } 162 | int main() 163 | { 164 | kira; 165 | int q; 166 | cin >> q; 167 | while (q--) 168 | { 169 | ll a, b; 170 | cin >> a >> b >> mod; 171 | string lf, rt; 172 | lf = to_string(a); 173 | rt = to_string(b); 174 | 175 | forz(i, 20) 176 | forz(j, 2) 177 | forz(k, 2) 178 | forz(l, 2) 179 | forz(m, 100) 180 | forz(n, 10) 181 | dp[i][j][k][l][m][n] = {-1, ""}; 182 | 183 | reverse(all(lf)); 184 | while (int(lf.si) < int(rt.si)) 185 | { 186 | lf.pb('0'); 187 | } 188 | reverse(all(lf)); 189 | 190 | t = lf; 191 | s = rt; 192 | pair ret = solve(0, 1, 1, 0, 0, 0); 193 | if (ret.first) 194 | cout << ret.first << " " << ret.second << endl; 195 | else 196 | cout << "-1"< 5 | typedef long long int ll; 6 | typedef unsigned long long int ull; 7 | typedef long double ldb; 8 | 9 | #include 10 | #include 11 | using namespace __gnu_pbds; 12 | 13 | #define pb push_back 14 | #define popb pop_back() 15 | #define pf push_front 16 | #define popf pop_front() 17 | 18 | #define si size() 19 | #define be begin() 20 | #define en end() 21 | #define all(v) v.be, v.en 22 | 23 | #define le length() 24 | #define mp make_pair 25 | #define mt make_tuple 26 | #define acc(v) accumulate(all(v), 0) 27 | #define F first 28 | #define S second 29 | 30 | #define pll pair 31 | #define pii pair 32 | #define pil pair 33 | 34 | #define forz(i, n) for (int i = 0; i < n; i++) 35 | #define fore(i, m, n) for (int i = m; i <= n; i++) 36 | #define rforz(i, n) for (int i = n - 1; i >= 0; i--) 37 | #define rfore(i, m, n) for (int i = n; i >= m; i--) 38 | 39 | #define deci(n) fixed << setprecision(n) 40 | #define high(n) __builtin_popcount(n) 41 | #define highll(n) __builtin_popcountll(n) 42 | #define parity(n) __builtin_parity(n) 43 | #define ctz(n) __builtin_ctz(n) 44 | 45 | #define bset(a, p) ((a) | (1ll << (p))) 46 | #define bchk(a, p) ((a) & (1ll << (p))) 47 | #define bxor(a, p) ((a) ^ (1ll << (p))); 48 | #define brem(a, p) (bchk(a, p) ? (bxor(a, p)) : (a)) 49 | /*SOME BITMASK KNOWLEDGE 50 | 1)x & (x - 1):sets the last one bit of x to zero 51 | power of two exactly when x & (x − 1) = 0. 52 | 2)x & -x:sets all the one bits to zero, except last one bit 53 | 3)x | (x - 1):inverts all the bits after the last one bit*/ 54 | 55 | #define lb lower_bound 56 | #define ub upper_bound 57 | #define er equal_range 58 | 59 | #define findnot find_first_not_of 60 | 61 | #define maxe *max_element 62 | #define mine *min_element 63 | 64 | #define mod2 1000000007 65 | #define mod 998244353 66 | #define gcd __gcd 67 | #define kira ios::sync_with_stdio(0), cin.tie(0), cout.tie(0) 68 | 69 | #define endl "\n" 70 | #define p0(a) cout << a << " " 71 | #define p1(a) cout << a << endl 72 | #define p2(a, b) cout << a << " " << b << endl 73 | #define p3(a, b, c) cout << a << " " << b << " " << c << endl 74 | #define p4(a, b, c, d) cout << a << " " << b << " " << c << " " << d << endl 75 | 76 | #define oset tree, rb_tree_tag, tree_order_statistics_node_update> 77 | #define osetlli tree, rb_tree_tag, tree_order_statistics_node_update> 78 | //member functions : 79 | //1. order_of_key(k) : number of elements sbtriectly lesser than k 80 | //2. find_by_order(k) : k-th element in the set 81 | #define ofk order_of_key 82 | #define fbo find_by_order 83 | using namespace std; 84 | 85 | /*STD funcions*/ 86 | ll power(ll x, ll y, ll p) 87 | { 88 | ll res = 1; 89 | x = x % p; 90 | while (y > 0) 91 | { 92 | if (y & 1) 93 | res = (res * x) % p; 94 | y = y >> 1; 95 | x = (x * x) % p; 96 | } 97 | return res; 98 | } 99 | ll modi(ll a, ll m) { return power(a, m - 2, m); } 100 | /*CODE BEGINS*/ 101 | 102 | string s, t; 103 | pair dp[20][2][2][2]; 104 | 105 | pair solve(int pos, int t1, int t2, int srt) 106 | { 107 | if (pos == int(s.si)) 108 | return {1, ""}; 109 | 110 | if (dp[pos][t1][t2][srt].F != -1) 111 | return dp[pos][t1][t2][srt]; 112 | 113 | ll st = t1 ? t[pos] - '0' : 0; 114 | ll et = t2 ? s[pos] - '0' : 9; 115 | 116 | ll res = -1; 117 | string ans = ""; 118 | for (ll i = st; i <= et; i++) 119 | { 120 | ll val; 121 | if (srt == 0 && i == 0) 122 | val = 1; 123 | else 124 | val = i; 125 | 126 | pair k = solve(pos + 1, t1 & (i == st), t2 & (i == et), srt | (i > 0)); 127 | if ((val * k.F) > res) 128 | { 129 | res = (k.F * val); 130 | if (srt == 0 && i == 0) 131 | { 132 | ans = k.S; 133 | } 134 | else 135 | { 136 | reverse(all(k.S)); 137 | k.S.pb('0' + i); 138 | reverse(all(k.S)); 139 | ans = k.S; 140 | } 141 | } 142 | } 143 | return dp[pos][t1][t2][srt] = {res, ans}; 144 | } 145 | int main() 146 | { 147 | kira; 148 | string lf, rt; 149 | cin >> lf >> rt; 150 | 151 | forz(i, 20) 152 | forz(j, 2) 153 | forz(k, 2) 154 | forz(l, 2) 155 | dp[i][j][k][l] = {-1, ""}; 156 | 157 | reverse(all(lf)); 158 | while (int(lf.si) < int(rt.si)) 159 | { 160 | lf.pb('0'); 161 | } 162 | reverse(all(lf)); 163 | 164 | t = lf; 165 | s = rt; 166 | string ret = solve(0, 1, 1, 0).S; 167 | 168 | cout << ret; 169 | return 0; 170 | } 171 | -------------------------------------------------------------------------------- /DP/DigitDP/Digitdp_ques/Pattern110.cpp: -------------------------------------------------------------------------------- 1 | //Binary rep contains 110 as a substring 2 | //BROWNIE TK 3 | 4 | #include 5 | typedef long long int ll; 6 | typedef unsigned long long int ull; 7 | typedef long double ldb; 8 | 9 | #define pb push_back 10 | #define popb pop_back() 11 | #define pf push_front 12 | #define popf pop_front() 13 | 14 | #define si size() 15 | #define be begin() 16 | #define en end() 17 | #define all(v) v.be, v.en 18 | 19 | #define le length() 20 | #define mp make_pair 21 | #define mt make_tuple 22 | #define acc(v) accumulate(all(v), 0) 23 | #define F first 24 | #define S second 25 | 26 | #define pll pair 27 | #define pii pair 28 | #define pil pair 29 | 30 | #define forz(i, n) for (int i = 0; i < n; i++) 31 | #define fore(i, m, n) for (int i = m; i <= n; i++) 32 | #define rforz(i, n) for (int i = n - 1; i >= 0; i--) 33 | #define rfore(i, m, n) for (int i = n; i >= m; i--) 34 | 35 | #define deci(n) fixed << setprecision(n) 36 | #define high(n) __builtin_popcount(n) 37 | #define highll(n) __builtin_popcountll(n) 38 | #define parity(n) __builtin_parity(n) 39 | #define ctz(n) __builtin_ctz(n) 40 | 41 | #define bset(a, p) ((a) | (1ll << (p))) 42 | #define bchk(a, p) ((a) & (1ll << (p))) 43 | #define bxor(a, p) ((a) ^ (1ll << (p))); 44 | #define brem(a, p) (bchk(a, p) ? (bxor(a, p)) : (a)) 45 | 46 | #define lb lower_bound 47 | #define ub upper_bound 48 | #define er equal_range 49 | 50 | #define findnot find_first_not_of 51 | 52 | #define maxe *max_element 53 | #define mine *min_element 54 | 55 | #define mod 1000000007 56 | #define mod2 998244353 57 | #define gcd __gcd 58 | #define kira ios::sync_with_stdio(0), cin.tie(0), cout.tie(0) 59 | 60 | #define endl "\n" 61 | #define p0(a) cout << a << " " 62 | #define p1(a) cout << a << endl 63 | #define p2(a, b) cout << a << " " << b << endl 64 | #define p3(a, b, c) cout << a << " " << b << " " << c << endl 65 | #define p4(a, b, c, d) cout << a << " " << b << " " << c << " " << d << endl 66 | 67 | #define oset tree, rb_tree_tag, tree_order_statistics_node_update> 68 | #define osetlli tree, rb_tree_tag, tree_order_statistics_node_update> 69 | 70 | 71 | #define ofk order_of_key 72 | #define fbo find_by_order 73 | using namespace std; 74 | 75 | 76 | ll power(ll x, ll y, ll p) 77 | { 78 | ll res = 1; 79 | x = x % p; 80 | while (y > 0) 81 | { 82 | if (y & 1) 83 | res = (res * x) % p; 84 | y = y >> 1; 85 | x = (x * x) % p; 86 | } 87 | return res; 88 | } 89 | ll modi(ll a, ll m) { return power(a, m - 2, m); } 90 | 91 | string s; 92 | ll dp[65][4][2]; 93 | ll solve(int pos, int st, int t) 94 | { 95 | if (pos == int(s.si)) 96 | return (st == 3); 97 | 98 | if (dp[pos][st][t] != -1) 99 | return dp[pos][st][t]; 100 | 101 | int lim = t ? s[pos] - '0' : 1; 102 | int nt = t; 103 | 104 | ll ans = 0; 105 | for (int i = 0; i <= lim; i++) 106 | { 107 | if (i != lim) 108 | nt = 0; 109 | else 110 | nt = t; 111 | int nst; 112 | if (i == 0) 113 | { 114 | if (st == 0) 115 | nst = 0; 116 | else if (st == 1) 117 | nst = 0; 118 | else if (st == 2) 119 | nst = 3; 120 | else if (st == 3) 121 | nst = 3; 122 | } 123 | else 124 | { 125 | if (st == 0) 126 | nst = 1; 127 | else if (st == 1) 128 | nst = 2; 129 | else if (st == 2) 130 | nst = 2; 131 | else if (st == 3) 132 | nst = 3; 133 | } 134 | ans += solve(pos+1,nst,nt); 135 | } 136 | return dp[pos][st][t]=ans; 137 | } 138 | string tobin(ll n) 139 | { 140 | string temp=""; 141 | for(ll i=61;i>=0;i--) 142 | { 143 | if((1ll<>nc; 154 | while(nc--) 155 | { 156 | cin>>l>>r; 157 | l--; 158 | memset(dp,-1,sizeof(dp)); 159 | s=tobin(l); 160 | ll y=solve(0,0,1); 161 | memset(dp,-1,sizeof(dp)); 162 | s=tobin(r); 163 | ll x=solve(0,0,1); 164 | cout< 5 | 6 | typedef long long int ll; 7 | typedef unsigned long long int ull; 8 | typedef long double ldb; 9 | 10 | #include 11 | #include 12 | using namespace __gnu_pbds; 13 | 14 | #define pb push_back 15 | #define popb pop_back() 16 | #define pf push_front 17 | #define popf pop_front() 18 | #define si size() 19 | #define be begin() 20 | #define en end() 21 | #define all(v) v.be, v.en 22 | #define le length() 23 | #define mp make_pair 24 | #define mt make_tuple 25 | #define F first 26 | #define S second 27 | 28 | #define forz(i, n) for (int i = 0; i < n; i++) 29 | #define forzm(i, m, n) for (int i = m; i < n; i++) 30 | #define rforz(i, n) for (int i = n - 1; i >= 0; i--) 31 | #define rforzm(i, m, n) for (int i = n - 1; i >= m; i--) 32 | #define deci(n) fixed << setprecision(n) 33 | #define high(n) __builtin_popcount(n) 34 | #define parity(n) __builtin_parity(n) 35 | #define ctz(n) __builtin_ctz(n) 36 | #define lb lower_bound 37 | #define ub upper_bound 38 | #define er equal_range 39 | #define maxe *max_element 40 | #define mine *min_element 41 | #define mod 1000000007 42 | #define mod2 998244353 43 | #define kira ios::sync_with_stdio(0), cin.tie(0), cout.tie(0) 44 | 45 | #define endl "\n" 46 | #define p0(a) cout << a << " " 47 | #define p1(a) cout << a << endl 48 | #define p2(a, b) cout << a << " " << b << endl 49 | #define p3(a, b, c) cout << a << " " << b << " " << c << endl 50 | #define p4(a, b, c, d) cout << a << " " << b << " " << c << " " << d << endl 51 | 52 | #define oset tree, rb_tree_tag, tree_order_statistics_node_update> 53 | #define osetlli tree, rb_tree_tag, tree_order_statistics_node_update> 54 | //member functions : 55 | //1. order_of_key(k) : number of elements strictly lesser than k 56 | //2. find_by_order(k) : k-th element in the set 57 | #define ofk order_of_key 58 | #define fbo find_by_order 59 | 60 | using namespace std; 61 | 62 | /*STD fucntions*/ 63 | ll power(ll x, ll y, ll p) 64 | { 65 | ll res = 1; 66 | x = x % p; 67 | while (y > 0) 68 | { 69 | if (y & 1) 70 | res = (res * x) % p; 71 | //y must be even now 72 | y = y >> 1; //y=y/2 73 | x = (x * x) % p; 74 | } 75 | return res; 76 | } 77 | ll gcd(ll a, ll b) 78 | { 79 | if (b == 0) 80 | return a; 81 | return gcd(b, a % b); 82 | } 83 | ll lcm(ll a, ll b) 84 | { 85 | return a * b / gcd(a, b); 86 | } 87 | ll modi(ll a, ll m) 88 | { 89 | // fermat little thm where m is prime 90 | return power(a, m - 2, m); 91 | } 92 | /*CODE BEGINS*/ 93 | string s; 94 | ll dp[20][5][2]; 95 | ll solve(int pos, int cnt, int t) 96 | { 97 | if (cnt >= 4) 98 | return 0; 99 | if (pos == s.si) 100 | { 101 | return 1; 102 | } 103 | if (dp[pos][cnt][t] != -1) 104 | return dp[pos][cnt][t]; 105 | int lim = (t) ? 9 : s[pos] - '0'; 106 | ll ans = 0, nt = t; 107 | for (int i = 0; i <= lim; i++) 108 | { 109 | if (i != lim) 110 | nt = 1; 111 | else 112 | nt = t; 113 | if (i != 0) 114 | ans += solve(pos + 1, cnt + 1, nt); 115 | else 116 | ans += solve(pos + 1, cnt, nt); 117 | } 118 | return dp[pos][cnt][nt] = ans; 119 | } 120 | int main() 121 | { 122 | kira; 123 | ll t, l, r; 124 | string a, b; 125 | cin >> t; 126 | while (t--) 127 | { 128 | cin >> a >> b; 129 | int l = a.si - 1; 130 | while (a[l] == '0') 131 | { 132 | a[l] = '9'; 133 | l--; 134 | } 135 | a[l]--; 136 | memset(dp, -1, sizeof(dp)); 137 | s = a; 138 | l = solve(0, 0, 0); 139 | memset(dp, -1, sizeof(dp)); 140 | s = b; 141 | r = solve(0, 0, 0); 142 | p1(r - l); 143 | } 144 | return 0; 145 | } 146 | -------------------------------------------------------------------------------- /DP/DigitDP/Digitdp_ques/encoding.cpp: -------------------------------------------------------------------------------- 1 | //https://codeforces.com/contest/1327/problem/A 2 | //BROWNIE TK 3 | 4 | #include 5 | using namespace std; 6 | 7 | typedef long long int ll; 8 | typedef unsigned long long int ull; 9 | typedef long double ldb; 10 | 11 | #include 12 | #include 13 | using namespace __gnu_pbds; 14 | 15 | #define pb push_back 16 | #define popb pop_back() 17 | #define pf push_front 18 | #define popf pop_front() 19 | 20 | #define si size() 21 | #define be begin() 22 | #define en end() 23 | #define all(v) v.be, v.en 24 | 25 | #define le length() 26 | #define mp make_pair 27 | #define mt make_tuple 28 | #define acc(v) accumulate(all(v), 0) 29 | #define F first 30 | #define S second 31 | 32 | #define pll pair 33 | #define pii pair 34 | #define pil pair 35 | 36 | #define forz(i, n) for (int i = 0; i < n; i++) 37 | #define fore(i, m, n) for (int i = m; i <= n; i++) 38 | #define rforz(i, n) for (int i = n - 1; i >= 0; i--) 39 | #define rfore(i, m, n) for (int i = n; i >= m; i--) 40 | 41 | #define deci(n) fixed << setprecision(n) 42 | #define high(n) __builtin_popcount(n) 43 | #define highll(n) __builtin_popcountll(n) 44 | #define parity(n) __builtin_parity(n) 45 | #define ctz(n) __builtin_ctz(n) 46 | 47 | #define bset(a, p) ((a) | (1ll << (p))) 48 | #define bchk(a, p) ((a) & (1ll << (p))) 49 | #define bxor(a, p) ((a) ^ (1ll << (p))); 50 | #define brem(a, p) (bchk(a, p) ? (bxor(a, p)) : (a)) 51 | /*SOME BITMASK KNOWLEDGE 52 | 1)x & (x - 1):sets the last one bit of x to zero 53 | power of two exactly when x & (x − 1) = 0. 54 | 2)x & -x:sets all the one bits to zero, except last one bit 55 | 3)x | (x - 1):inverts all the bits after the last one bit*/ 56 | 57 | #define lb lower_bound 58 | #define ub upper_bound 59 | #define er equal_range 60 | 61 | #define findnot find_first_not_of 62 | 63 | #define maxe *max_element 64 | #define mine *min_element 65 | 66 | #define mod 1000000007 67 | #define mod2 998244353 68 | #define gcd __gcd 69 | #define kira ios::sync_with_stdio(0), cin.tie(0), cout.tie(0) 70 | 71 | #define endl "\n" 72 | #define p0(a) cout << a << " " 73 | #define p1(a) cout << a << endl 74 | #define p2(a, b) cout << a << " " << b << endl 75 | #define p3(a, b, c) cout << a << " " << b << " " << c << endl 76 | #define p4(a, b, c, d) cout << a << " " << b << " " << c << " " << d << endl 77 | 78 | #define oset tree, rb_tree_tag, tree_order_statistics_node_update> 79 | #define osetlli tree, rb_tree_tag, tree_order_statistics_node_update> 80 | //member functions : 81 | //1. order_of_key(k) : number of elements sbtriectly lesser than k 82 | //2. find_by_order(k) : k-th element in the set 83 | #define ofk order_of_key 84 | #define fbo find_by_order 85 | 86 | /*STD funcions*/ 87 | ll power(ll x, ll y, ll p) 88 | { 89 | ll res = 1; 90 | x = x % p; 91 | while (y > 0) 92 | { 93 | if (y & 1) 94 | res = (res * x) % p; 95 | y = y >> 1; 96 | x = (x * x) % p; 97 | } 98 | return res; 99 | } 100 | ll modi(ll a, ll m) { return power(a, m - 2, m); } 101 | /*CODE BEGINS*/ 102 | string s; 103 | const int N = 1e5 + 5; 104 | ll ten[N]; 105 | pll dp[N][10][2]; 106 | void pre() 107 | { 108 | ten[0] = 1; 109 | for (int i = 1; i < N; i++) 110 | { 111 | ten[i] = (ten[i - 1] * 10ll) % mod; 112 | } 113 | return; 114 | } 115 | pll solve(ll pos, ll dig, ll t) 116 | { 117 | ll k = ll(s.si); 118 | if (pos == k) 119 | return {0, 1}; 120 | 121 | if (dp[pos][dig][t].F != -1) 122 | return dp[pos][dig][t]; 123 | 124 | ll lim = t ? s[pos] - '0' : 9; 125 | pll ans = {0, 0}; 126 | for (ll i = 0; i <= lim; i++) 127 | { 128 | 129 | pll temp = solve(pos + 1, i, t & (i == lim)); 130 | ans.S = (ans.S + temp.S) % mod; 131 | ans.F = (ans.F + temp.F) % mod; 132 | 133 | if (i != dig) 134 | { 135 | ans.F += (((i * ten[k - pos - 1]) % mod) * temp.S) % mod; 136 | ans.F %= mod; 137 | } 138 | } 139 | return dp[pos][dig][t] = ans; 140 | } 141 | int main() 142 | { 143 | kira; 144 | ll nc, nl, nr; 145 | string l, r; 146 | cin >> nc; 147 | pre(); 148 | while (nc--) 149 | { 150 | cin >> nl >> l; 151 | cin >> nr >> r; 152 | int i1 = nl - 1; 153 | while (l[i1] == '0') 154 | { 155 | l[i1] = '9'; 156 | i1--; 157 | } 158 | l[i1]--; 159 | forz(i, nl) 160 | { 161 | forz(j, 10) 162 | { 163 | forz(k, 2) 164 | { 165 | dp[i][j][k].F = -1; 166 | } 167 | } 168 | } 169 | s = l; 170 | ll y = solve(0, 0, 1).F; 171 | forz(i, nr) 172 | { 173 | forz(j, 10) 174 | { 175 | forz(k, 2) 176 | { 177 | dp[i][j][k].F = -1; 178 | } 179 | } 180 | } 181 | s = r; 182 | ll x = solve(0, 0, 1).F; 183 | cout << (x - y + mod) % mod << endl; 184 | } 185 | return 0; 186 | } 187 | -------------------------------------------------------------------------------- /DP/DigitDP/Digitdp_ques/gone.cpp: -------------------------------------------------------------------------------- 1 | //https://www.spoj.com/problems/GONE/ 2 | //BROWNIE TK 3 | 4 | #include 5 | typedef long long int ll; 6 | typedef unsigned long long int ull; 7 | typedef long double ldb; 8 | 9 | #include 10 | #include 11 | using namespace __gnu_pbds; 12 | 13 | #define pb push_back 14 | #define popb pop_back() 15 | #define pf push_front 16 | #define popf pop_front() 17 | 18 | #define si size() 19 | #define be begin() 20 | #define en end() 21 | #define all(v) v.be, v.en 22 | 23 | #define le length() 24 | #define mp make_pair 25 | #define mt make_tuple 26 | #define acc(v) accumulate(all(v), 0) 27 | #define F first 28 | #define S second 29 | 30 | #define pll pair 31 | #define pii pair 32 | #define pil pair 33 | 34 | #define forz(i, n) for (int i = 0; i < n; i++) 35 | #define fore(i, m, n) for (int i = m; i <= n; i++) 36 | #define rforz(i, n) for (int i = n - 1; i >= 0; i--) 37 | #define rfore(i, m, n) for (int i = n; i >= m; i--) 38 | 39 | #define deci(n) fixed << setprecision(n) 40 | #define high(n) __builtin_popcount(n) 41 | #define highll(n) __builtin_popcountll(n) 42 | #define parity(n) __builtin_parity(n) 43 | #define ctz(n) __builtin_ctz(n) 44 | 45 | #define bset(a, p) ((a) | (1ll << (p))) 46 | #define bchk(a, p) ((a) & (1ll << (p))) 47 | #define bxor(a, p) ((a) ^ (1ll << (p))); 48 | #define brem(a, p) (bchk(a, p) ? (bxor(a, p)) : (a)) 49 | /*SOME BITMASK KNOWLEDGE 50 | 1)x & (x - 1):sets the last one bit of x to zero 51 | power of two exactly when x & (x â�� 1) = 0. 52 | 2)x & -x:sets all the one bits to zero, except last one bit 53 | 3)x | (x - 1):inverts all the bits after the last one bit*/ 54 | 55 | #define lb lower_bound 56 | #define ub upper_bound 57 | #define er equal_range 58 | 59 | #define findnot find_first_not_of 60 | 61 | #define maxe *max_element 62 | #define mine *min_element 63 | 64 | #define mod 1000000007 65 | #define mod2 998244353 66 | #define gcd __gcd 67 | #define kira ios::sync_with_stdio(0), cin.tie(0), cout.tie(0) 68 | 69 | #define endl "\n" 70 | #define p0(a) cout << a << " " 71 | #define p1(a) cout << a << endl 72 | #define p2(a, b) cout << a << " " << b << endl 73 | #define p3(a, b, c) cout << a << " " << b << " " << c << endl 74 | #define p4(a, b, c, d) cout << a << " " << b << " " << c << " " << d << endl 75 | 76 | #define oset tree, rb_tree_tag, tree_order_statistics_node_update> 77 | #define osetlli tree, rb_tree_tag, tree_order_statistics_node_update> 78 | //member functions : 79 | //1. order_of_key(k) : number of elements sbtriectly lesser than k 80 | //2. find_by_order(k) : k-th element in the set 81 | #define ofk order_of_key 82 | #define fbo find_by_order 83 | using namespace std; 84 | 85 | /*STD funcions*/ 86 | ll power(ll x, ll y, ll p) 87 | { 88 | ll res = 1; 89 | x = x % p; 90 | while (y > 0) 91 | { 92 | if (y & 1) 93 | res = (res * x) % p; 94 | y = y >> 1; 95 | x = (x * x) % p; 96 | } 97 | return res; 98 | } 99 | ll modi(ll a, ll m) { return power(a, m - 2, m); } 100 | /*CODE BEGINS*/ 101 | string s; 102 | ll dp[10][90][2]; 103 | bool prime[100]; 104 | void sieve(int n) 105 | { 106 | memset(prime, true, sizeof(prime)); 107 | for (int p = 2; p * p <= n; p++) 108 | { 109 | if (prime[p] == true) 110 | { 111 | for (int i = p * p; i <= n; i += p) 112 | prime[i] = false; 113 | } 114 | } 115 | return; 116 | } 117 | ll solve(int pos, int sum, int t) 118 | { 119 | if (pos == s.si) 120 | { 121 | if (prime[sum] && sum > 1) 122 | return 1; 123 | return 0; 124 | } 125 | if (dp[pos][sum][t] != -1) 126 | return dp[pos][sum][t]; 127 | int lim = t ? s[pos] - '0' : 9; 128 | ll ans = 0, nt = t, nsum = sum; 129 | for (int i = 0; i <= lim; i++) 130 | { 131 | if (i != lim) 132 | nt = 0; 133 | else 134 | nt = t; 135 | nsum = sum + i; 136 | ans += solve(pos + 1, nsum, nt); 137 | } 138 | return dp[pos][sum][t] = ans; 139 | } 140 | int main() 141 | { 142 | kira; 143 | int n; 144 | cin >> n; 145 | string a, b; 146 | while (n--) 147 | { 148 | cin >> a >> b; 149 | ll n=stoll(a); 150 | n--; 151 | a=to_string(n); 152 | sieve(100); 153 | memset(dp, -1, sizeof(dp)); 154 | s = b; 155 | ll y = solve(0, 0, 1); 156 | memset(dp, -1, sizeof(dp)); 157 | s = a; 158 | ll x = solve(0, 0, 1); 159 | cout< 5 | typedef long long int ll; 6 | typedef unsigned long long int ull; 7 | typedef long double ldb; 8 | 9 | #include 10 | #include 11 | using namespace __gnu_pbds; 12 | 13 | #define pb push_back 14 | #define popb pop_back() 15 | #define pf push_front 16 | #define popf pop_front() 17 | 18 | #define si size() 19 | #define be begin() 20 | #define en end() 21 | #define all(v) v.be, v.en 22 | 23 | #define le length() 24 | #define mp make_pair 25 | #define mt make_tuple 26 | #define acc(v) accumulate(all(v), 0) 27 | #define F first 28 | #define S second 29 | 30 | #define pll pair 31 | #define pii pair 32 | #define pil pair 33 | 34 | #define forz(i, n) for (int i = 0; i < n; i++) 35 | #define fore(i, m, n) for (int i = m; i <= n; i++) 36 | #define rforz(i, n) for (int i = n - 1; i >= 0; i--) 37 | #define rfore(i, m, n) for (int i = n; i >= m; i--) 38 | 39 | #define deci(n) fixed << setprecision(n) 40 | #define high(n) __builtin_popcount(n) 41 | #define highll(n) __builtin_popcountll(n) 42 | #define parity(n) __builtin_parity(n) 43 | #define ctz(n) __builtin_ctz(n) 44 | 45 | #define bset(a, p) ((a) | (1ll << (p))) 46 | #define bchk(a, p) ((a) & (1ll << (p))) 47 | #define bxor(a, p) ((a) ^ (1ll << (p))); 48 | #define brem(a, p) (bchk(a, p) ? (bxor(a, p)) : (a)) 49 | /*SOME BITMASK KNOWLEDGE 50 | 1)x & (x - 1):sets the last one bit of x to zero 51 | power of two exactly when x & (x â�� 1) = 0. 52 | 2)x & -x:sets all the one bits to zero, except last one bit 53 | 3)x | (x - 1):inverts all the bits after the last one bit*/ 54 | 55 | #define lb lower_bound 56 | #define ub upper_bound 57 | #define er equal_range 58 | 59 | #define findnot find_first_not_of 60 | 61 | #define maxe *max_element 62 | #define mine *min_element 63 | 64 | #define mod 1000000007 65 | #define mod2 998244353 66 | #define gcd __gcd 67 | #define kira ios::sync_with_stdio(0), cin.tie(0), cout.tie(0) 68 | 69 | #define endl "\n" 70 | #define p0(a) cout << a << " " 71 | #define p1(a) cout << a << endl 72 | #define p2(a, b) cout << a << " " << b << endl 73 | #define p3(a, b, c) cout << a << " " << b << " " << c << endl 74 | #define p4(a, b, c, d) cout << a << " " << b << " " << c << " " << d << endl 75 | 76 | #define oset tree, rb_tree_tag, tree_order_statistics_node_update> 77 | #define osetlli tree, rb_tree_tag, tree_order_statistics_node_update> 78 | //member functions : 79 | //1. order_of_key(k) : number of elements sbtriectly lesser than k 80 | //2. find_by_order(k) : k-th element in the set 81 | #define ofk order_of_key 82 | #define fbo find_by_order 83 | using namespace std; 84 | 85 | /*STD funcions*/ 86 | ll power(ll x, ll y, ll p) 87 | { 88 | ll res = 1; 89 | x = x % p; 90 | while (y > 0) 91 | { 92 | if (y & 1) 93 | res = (res * x) % p; 94 | y = y >> 1; 95 | x = (x * x) % p; 96 | } 97 | return res; 98 | } 99 | ll modi(ll a, ll m) { return power(a, m - 2, m); } 100 | /*CODE BEGINS*/ 101 | string s; 102 | ll dp[10][100][100][2][2]; 103 | bool prime[100]; 104 | void sieve(int n) 105 | { 106 | memset(prime, true, sizeof(prime)); 107 | for (int p = 2; p * p <= n; p++) 108 | { 109 | if (prime[p] == true) 110 | { 111 | for (int i = p * p; i <= n; i += p) 112 | prime[i] = false; 113 | } 114 | } 115 | return; 116 | } 117 | ll solve(int pos, int sume, int sumo, int t, int nozero) 118 | { 119 | int k = s.si; 120 | if (pos == k) 121 | { 122 | if (sume - sumo > 1 && prime[abs(sume - sumo)]) 123 | return 1; 124 | else 125 | return 0; 126 | } 127 | if (dp[pos][sume][sumo][t][nozero] != -1) 128 | return dp[pos][sume][sumo][t][nozero]; 129 | int lim = t ? s[pos] - '0' : 9; 130 | ll ans = 0, nt = t; 131 | for (int i = 0; i <= lim; i++) 132 | { 133 | if (i != lim) 134 | nt = 0; 135 | else 136 | nt = t; 137 | int newzero = (nozero || i > 0); 138 | if (newzero) 139 | ans += solve(pos + 1, sume + ((k - pos + 1) % 2 ? i : 0), sumo + ((k - pos + 1) % 2 ? 0 : i), nt, newzero); 140 | else 141 | ans += solve(pos + 1, sume, sumo, nt, newzero); 142 | } 143 | return dp[pos][sume][sumo][t][nozero] = ans; 144 | } 145 | int main() 146 | { 147 | kira; 148 | int n; 149 | cin >> n; 150 | string a, b; 151 | while (n--) 152 | { 153 | cin >> a >> b; 154 | ll n = stoll(a); 155 | n--; 156 | a = to_string(n); 157 | sieve(95); 158 | memset(dp, -1, sizeof(dp)); 159 | s = b; 160 | ll y = solve(0, 0, 0, 1, 0); 161 | memset(dp, -1, sizeof(dp)); 162 | s = a; 163 | ll x = solve(0, 0, 0, 1, 0); 164 | cout << y - x << endl; 165 | } 166 | return 0; 167 | } 168 | -------------------------------------------------------------------------------- /DP/DigitDP/Digitdp_ques/magicnumbers.cpp: -------------------------------------------------------------------------------- 1 | //https://codeforces.com/problemset/problem/628/D 2 | //BROWNIE TK 3 | 4 | #include 5 | 6 | typedef long long int ll; 7 | typedef unsigned long long int ull; 8 | typedef long double ldb; 9 | 10 | #include 11 | #include 12 | using namespace __gnu_pbds; 13 | 14 | #define pb push_back 15 | #define popb pop_back() 16 | #define pf push_front 17 | #define popf pop_front() 18 | #define si size() 19 | #define be begin() 20 | #define en end() 21 | #define all(v) v.be, v.en 22 | #define le length() 23 | #define mp make_pair 24 | #define mt make_tuple 25 | #define F first 26 | #define S second 27 | 28 | #define forz(i, n) for (int i = 0; i < n; i++) 29 | #define forzm(i, m, n) for (int i = m; i < n; i++) 30 | #define rforz(i, n) for (int i = n - 1; i >= 0; i--) 31 | #define rforzm(i, m, n) for (int i = n - 1; i >= m; i--) 32 | #define deci(n) fixed << setprecision(n) 33 | #define high(n) __builtin_popcount(n) 34 | #define parity(n) __builtin_parity(n) 35 | #define ctz(n) __builtin_ctz(n) 36 | #define lb lower_bound 37 | #define ub upper_bound 38 | #define er equal_range 39 | #define maxe *max_element 40 | #define mine *min_element 41 | #define mod 1000000007 42 | #define mod2 998244353 43 | #define kira ios::sync_with_stdio(0), cin.tie(0), cout.tie(0) 44 | 45 | #define endl "\n" 46 | #define p0(a) cout << a << " " 47 | #define p1(a) cout << a << endl 48 | #define p2(a, b) cout << a << " " << b << endl 49 | #define p3(a, b, c) cout << a << " " << b << " " << c << endl 50 | #define p4(a, b, c, d) cout << a << " " << b << " " << c << " " << d << endl 51 | 52 | #define oset tree, rb_tree_tag, tree_order_statistics_node_update> 53 | #define osetlli tree, rb_tree_tag, tree_order_statistics_node_update> 54 | //member functions : 55 | //1. order_of_key(k) : number of elements strictly lesser than k 56 | //2. find_by_order(k) : k-th element in the set 57 | #define ofk order_of_key 58 | #define fbo find_by_order 59 | 60 | using namespace std; 61 | 62 | /*STD fucntions*/ 63 | ll power(ll x, ll y, ll p) 64 | { 65 | ll res = 1; 66 | x = x % p; 67 | while (y > 0) 68 | { 69 | if (y & 1) 70 | res = (res * x) % p; 71 | //y must be even now 72 | y = y >> 1; //y=y/2 73 | x = (x * x) % p; 74 | } 75 | return res; 76 | } 77 | ll gcd(ll a, ll b) 78 | { 79 | if (b == 0) 80 | return a; 81 | return gcd(b, a % b); 82 | } 83 | ll lcm(ll a, ll b) 84 | { 85 | return a * b / gcd(a, b); 86 | } 87 | ll modi(ll a, ll m) 88 | { 89 | // fermat little thm where m is prime 90 | return power(a, m - 2, m); 91 | } 92 | /*CODE BEGINS*/ 93 | 94 | string s; 95 | int m, d; 96 | ll dp[2005][2005][2]; 97 | 98 | ll solve(int pos, int rem, int t) 99 | { 100 | if (pos == s.si) 101 | return (rem == 0); 102 | if (dp[pos][rem][t] != -1) 103 | return dp[pos][rem][t]; 104 | int lim = (t) ? 9 : s[pos] - '0'; 105 | ll ans = 0, nt = t; 106 | for (int i = 0; i <= lim; i++) 107 | { 108 | if (pos % 2 == 0 && i == d) 109 | continue; 110 | if (pos % 2 != 0 && i != d) 111 | continue; 112 | if (i != lim) 113 | nt = 1; 114 | else 115 | nt = t; 116 | ans += solve(pos + 1, (rem * 10 + i) % m, nt); 117 | } 118 | ans %= mod; 119 | return dp[pos][rem][nt] = ans; 120 | } 121 | int main() 122 | { 123 | kira; 124 | ll l, r; 125 | string a, b; 126 | cin >> m >> d; 127 | cin >> a; 128 | cin >> b; 129 | int lt = a.si - 1; 130 | while (a[lt] == '0') 131 | { 132 | a[lt] = '9'; 133 | lt--; 134 | } 135 | a[lt]--; 136 | memset(dp, -1, sizeof(dp)); 137 | s = a; 138 | l = solve(0, 0, 0); 139 | memset(dp, -1, sizeof(dp)); 140 | s = b; 141 | r = solve(0, 0, 0); 142 | cout << (r + mod - l) % mod; 143 | return 0; 144 | } 145 | -------------------------------------------------------------------------------- /DP/DigitDP/Digitdp_ques/raone.cpp: -------------------------------------------------------------------------------- 1 | //https://www.spoj.com/problems/RAONE/ 2 | //BROWNIE TK 3 | 4 | #include 5 | typedef long long int ll; 6 | typedef unsigned long long int ull; 7 | typedef long double ldb; 8 | 9 | #include 10 | #include 11 | using namespace __gnu_pbds; 12 | 13 | #define pb push_back 14 | #define popb pop_back() 15 | #define pf push_front 16 | #define popf pop_front() 17 | 18 | #define si size() 19 | #define be begin() 20 | #define en end() 21 | #define all(v) v.be, v.en 22 | 23 | #define le length() 24 | #define mp make_pair 25 | #define mt make_tuple 26 | #define acc(v) accumulate(all(v), 0) 27 | #define F first 28 | #define S second 29 | 30 | #define pll pair 31 | #define pii pair 32 | #define pil pair 33 | 34 | #define forz(i, n) for (int i = 0; i < n; i++) 35 | #define fore(i, m, n) for (int i = m; i <= n; i++) 36 | #define rforz(i, n) for (int i = n - 1; i >= 0; i--) 37 | #define rfore(i, m, n) for (int i = n; i >= m; i--) 38 | 39 | #define deci(n) fixed << setprecision(n) 40 | #define high(n) __builtin_popcount(n) 41 | #define highll(n) __builtin_popcountll(n) 42 | #define parity(n) __builtin_parity(n) 43 | #define ctz(n) __builtin_ctz(n) 44 | 45 | #define bset(a, p) ((a) | (1ll << (p))) 46 | #define bchk(a, p) ((a) & (1ll << (p))) 47 | #define bxor(a, p) ((a) ^ (1ll << (p))); 48 | #define brem(a, p) (bchk(a, p) ? (bxor(a, p)) : (a)) 49 | /*SOME BITMASK KNOWLEDGE 50 | 1)x & (x - 1):sets the last one bit of x to zero 51 | power of two exactly when x & (x â�� 1) = 0. 52 | 2)x & -x:sets all the one bits to zero, except last one bit 53 | 3)x | (x - 1):inverts all the bits after the last one bit*/ 54 | 55 | #define lb lower_bound 56 | #define ub upper_bound 57 | #define er equal_range 58 | 59 | #define findnot find_first_not_of 60 | 61 | #define maxe *max_element 62 | #define mine *min_element 63 | 64 | #define mod 1000000007 65 | #define mod2 998244353 66 | #define gcd __gcd 67 | #define kira ios::sync_with_stdio(0), cin.tie(0), cout.tie(0) 68 | 69 | #define endl "\n" 70 | #define p0(a) cout << a << " " 71 | #define p1(a) cout << a << endl 72 | #define p2(a, b) cout << a << " " << b << endl 73 | #define p3(a, b, c) cout << a << " " << b << " " << c << endl 74 | #define p4(a, b, c, d) cout << a << " " << b << " " << c << " " << d << endl 75 | 76 | #define oset tree, rb_tree_tag, tree_order_statistics_node_update> 77 | #define osetlli tree, rb_tree_tag, tree_order_statistics_node_update> 78 | //member functions : 79 | //1. order_of_key(k) : number of elements sbtriectly lesser than k 80 | //2. find_by_order(k) : k-th element in the set 81 | #define ofk order_of_key 82 | #define fbo find_by_order 83 | using namespace std; 84 | 85 | /*STD funcions*/ 86 | ll power(ll x, ll y, ll p) 87 | { 88 | ll res = 1; 89 | x = x % p; 90 | while (y > 0) 91 | { 92 | if (y & 1) 93 | res = (res * x) % p; 94 | y = y >> 1; 95 | x = (x * x) % p; 96 | } 97 | return res; 98 | } 99 | ll modi(ll a, ll m) { return power(a, m - 2, m); } 100 | /*CODE BEGINS*/ 101 | string s; 102 | ll dp[10][90][90][2][2]; 103 | bool prime[100]; 104 | void sieve(int n) 105 | { 106 | memset(prime, true, sizeof(prime)); 107 | for (int p = 2; p * p <= n; p++) 108 | { 109 | if (prime[p] == true) 110 | { 111 | for (int i = p * p; i <= n; i += p) 112 | prime[i] = false; 113 | } 114 | } 115 | return; 116 | } 117 | ll solve(int pos, int sume, int sumo, int t, int nozero) 118 | { 119 | int k = s.si; 120 | if (pos == k) 121 | { 122 | return (sume - sumo == 1); 123 | } 124 | if (dp[pos][sume][sumo][t][nozero] != -1) 125 | return dp[pos][sume][sumo][t][nozero]; 126 | int lim = t ? s[pos] - '0' : 9; 127 | ll ans = 0, nt = t; 128 | for (int i = 0; i <= lim; i++) 129 | { 130 | if (i != lim) 131 | nt = 0; 132 | else 133 | nt = t; 134 | int newzero = (nozero || i > 0); 135 | if (newzero) 136 | ans += solve(pos + 1, sume + ((k-pos+1)% 2 ? i : 0), sumo + ((k-pos+1)%2 ? 0 : i), nt, newzero); 137 | else 138 | ans += solve(pos + 1, sume, sumo, nt, newzero); 139 | } 140 | return dp[pos][sume][sumo][t][nozero] = ans; 141 | } 142 | int main() 143 | { 144 | kira; 145 | int n; 146 | cin >> n; 147 | string a, b; 148 | while (n--) 149 | { 150 | cin >> a >> b; 151 | ll n = stoll(a); 152 | n--; 153 | a = to_string(n); 154 | memset(dp, -1, sizeof(dp)); 155 | s = b; 156 | ll y = solve(0, 0, 0, 1,0); 157 | memset(dp, -1, sizeof(dp)); 158 | s = a; 159 | ll x = solve(0, 0, 0, 1,0); 160 | cout << y - x << endl; 161 | } 162 | return 0; 163 | } 164 | -------------------------------------------------------------------------------- /DP/LIS.cpp: -------------------------------------------------------------------------------- 1 | //LIS IN O(nlogn) 2 | //LIS IN O(n^2) can be done by finding LCS of (sorted vector a) and (vector a) 3 | 4 | vector lis(vector &a) 5 | { 6 | int n = int(a.si); 7 | vector parent(n); 8 | vector incsub(n + 1); 9 | int length = 0; 10 | 11 | forz(i, n) 12 | { 13 | int l = 1, r = length; 14 | while (l <= r) 15 | { 16 | ll mid = l + (r - l) / 2; 17 | if (a[incsub[mid]] < a[i]) 18 | l = mid + 1; 19 | else 20 | r = mid - 1; 21 | } 22 | 23 | int pos = l; 24 | parent[i] = incsub[pos - 1]; 25 | incsub[pos] = i; 26 | 27 | if (pos > length) 28 | length = pos; 29 | } 30 | 31 | vector v(length); 32 | int k = incsub[length]; 33 | 34 | for (int j = length - 1; j >= 0; j--) 35 | { 36 | v[j] = a[k]; 37 | k = parent[k]; 38 | } 39 | 40 | return v; 41 | } 42 | -------------------------------------------------------------------------------- /DP/bounded_knapsack.cpp: -------------------------------------------------------------------------------- 1 | 1)Here we break copies into 1,2,4..,2^(k-1), 2 | (copies-(2^k)+1) and discard zero terms. 3 | 4 | int n, target; 5 | vector val, wt; 6 | 7 | int knapsack() 8 | { 9 | int dp[target + 1]; 10 | memset(dp, 0, sizeof(dp)); 11 | forz(i, n) 12 | { 13 | for (int j = target; j >= wt[i]; j--) 14 | { 15 | dp[j] = max(dp[j], val[i] + dp[j - wt[i]]); 16 | } 17 | } 18 | return dp[target]; 19 | } 20 | 21 | int main() 22 | { 23 | kira; 24 | 25 | cin >> n >> target; 26 | int price[n], weight[n], copies[n]; 27 | 28 | forz(i, n) cin >> weight[i]; 29 | forz(i, n) cin >> price[i]; 30 | forz(i, n) cin >> copies[i]; 31 | 32 | forz(i, n) 33 | { 34 | int temp = 1; 35 | int total = 0; 36 | while (total <= copies[i]) 37 | { 38 | if (temp + total > copies[i]) 39 | break; 40 | 41 | val.pb(temp * price[i]); 42 | wt.pb(temp * weight[i]); 43 | total += temp; 44 | temp *= 2; 45 | } 46 | 47 | if (total != copies[i]) 48 | { 49 | val.pb((copies[i] - total) * price[i]); 50 | wt.pb((copies[i] - total) * weight[i]); 51 | } 52 | } 53 | debug(val); 54 | debug(wt); 55 | n=int(val.si); 56 | cout << knapsack(); 57 | run_time(); 58 | return 0; 59 | } -------------------------------------------------------------------------------- /DP/dp.cpp: -------------------------------------------------------------------------------- 1 | Dynamic Programming 2 | 3 | 1) Overlapping Subproblems: 4 | So Dynamic Programming is not useful when there are no common 5 | (overlapping) subproblems because there is no point storing 6 | the solutions if they are not needed again. 7 | 8 | a) Memoization (Top Down): 9 | The memoized program for a problem is similar to the recursive 10 | version with a small modification that it looks into a lookup 11 | table before computing solutions. We initialize a lookup array 12 | with all initial values as NIL. Whenever we need the solution 13 | to a subproblem, we first look into the lookup table. 14 | If the precomputed value is there then we return that value, 15 | otherwise, we calculate the value and put the result in the 16 | lookup table so that it can be reused later. 17 | 18 | b) Tabulation (Bottom Up): 19 | The tabulated program for a given problem builds a table in bottom 20 | up fashion and returns the last entry from table. 21 | 22 | 2) Optimal Substructure: A given problems has Optimal Substructure 23 | Property if optimal solution of the given problem can be obtained 24 | by using optimal solutions of its subproblems. 25 | 26 | 3)Used for: 27 | a)count something,often no of ways 28 | b)min or max some value 29 | c)check if something is possible 30 | 31 | for b and c we can also think of some better greedy approach. 32 | 33 | 4)TRICKS AND PROBLEMS: 34 | 35 | 1)Climbing Stairs: 36 | 1 or 2 steps at a time and atmost k jumps: 37 | >with no limit on jumps 38 | dp[i]=dp[i-1]+dp[i-2]; 39 | >with limit: 40 | dp[i][k]=dp[i-1][k-1]+dp[i-2][k-1]; 41 | ans will be 42 | ∑dp[n][j] for j=[0,k] 43 | 44 | 2)Minimum path sum: 45 | dp[i][j]=min(dp[i-1][j],dp[i][j-1])+a[i][j]; 46 | >with no two consecutive down steps: 47 | dp[row][col][2] 48 | 49 | >>PUSH OR FORWARD DP IS BETTER: 50 | >>Minimise something put INF everywhere except the first one. 51 | >>Think what is important so far and make the dimmensions. 52 | >>AVOID DOUBLE COUNTING 53 | 54 | 3)Combination Sum: 55 | Given the target value N and an array of allowed numbers, 56 | count the ways to write N as the sum of those numbers. 57 | nums:allowed numbers: 58 | 59 | dp[i]:no of ways to get the sum as i 60 | 61 | Backward DP 62 | dp[0]=1; 63 | forz(i,n) 64 | for(x in nums)dp[i]+=dp[i-x]; 65 | 66 | Forward DP 67 | dp[0]=1; 68 | forz(i,n-1) 69 | for(x in nums)dp[i+x]+=dp[i]; 70 | 71 | 4)Coin change(min) 72 | You are given denominations of coins and the target value N. 73 | What is the minimum possible number of coins: 74 | dp[i]:min no of coins to get sum as i 75 | 76 | dp[0]=0 77 | dp[1..N]=INF; 78 | for i=[1....N]: 79 | for x in coins: 80 | dp[i]=min(dp[i],dp[i-x]+1); 81 | 82 | 5)Coin change(ways) 83 | Given denominations of coins and the target amount N. 84 | What is the number of ways to make up amount N: 85 | 86 | Order of coins doesnt matter 87 | k:no of denominations: 88 | dp[n][k] 89 | dp[s][last] 90 | last is the last index of the coin used 91 | If used coins are 0 1 1 and 2 you can say that last coin Used 92 | is 4 if you aint going to take smaller coins 93 | index are given: 94 | 95 | (17,2)->(17+num[2],2) 96 | | 97 | (17,3)->(17+num[3],3) 98 | | 99 | (17,4) 100 | 101 | ans is ∑dp[n][j] for j=[0,k-1] 102 | 103 | 6)LCS:Longest common subseq 104 | dp[i][j]:i is the length of prefix of string s 105 | j is the lenght of the prefix of string t 106 | dp[i][j] gives the LCS of s and t. 107 | 108 | dp[n+1][m+1] 109 | if(i==0||j==0)dp[i][j]=0; 110 | if(s[i-1]==t[j-1])dp[i][j]=dp[i-1][j-1]+1; 111 | else dp[i][j]=max(dp[i-1][j],dp[i][j-1]); 112 | ans=dp[n][m]; 113 | n:length of s; 114 | m:lenght of t; 115 | 116 | 7)Edit distance: 117 | Given two strings s,t find min number of edits 118 | 1)Insert 119 | 2)Remove 120 | 3)Replace 121 | 122 | dp[n+1][m+1] 123 | first:no of elements in first string 124 | second:no of elements in second string 125 | 126 | dp[0][j]=j; 127 | dp[i][0]=i; 128 | 129 | if(s[i-1]==t[j-1])dp[i][j]=dp[i-1][j-1]; 130 | else dp[i][j]=1+min({dp[i][j-1],dp[i-1][j],dp[i-1][j-1]}); 131 | insert remove replace 132 | ans=dp[n][m] 133 | 134 | 8)Cutting a Rod 135 | Given a rod of length n inches and an array of prices that 136 | contains prices of all pieces of size smaller than n. 137 | Determine the maximum value obtainable by cutting up the rod 138 | and selling the pieces. 139 | 140 | int best=-1; 141 | cost[n+1]; 142 | cost[0]=0; 143 | cost[i]:best possible cost for length i 144 | 145 | for(int i=1;i<=n;i++) 146 | { 147 | for(int j=1;j<=i;j++) 148 | best=max(best,cost[j]+dp[i-j]); 149 | 150 | dp[i]=best; 151 | } 152 | 153 | 9)No of distinct subseq of length n: 154 | ll a[n+1][n+1]={0}; 155 | a[i][j]: 156 | first dimmension for length of subseq 157 | second for length of prefix of string 158 | forz(i,n+1) 159 | { 160 | a[i][0]=0;//no chars to choose from 161 | a[0][i]=1;//empty subseq 162 | } 163 | for(int i=1;i<=n;i++) 164 | { 165 | vectorl(256,-1); 166 | //256 no of chars 167 | for(int j=1;j<=n;j++) 168 | { 169 | a[i][j]=a[i][j-1]+a[i-1][j-1];//length either i or i-1 170 | if(l[s[j-1]]!=-1) 171 | a[i][j]-=a[i-1][l[s[j-1]]];//subtract repetitions 172 | l[s[j-1]]=(j-1);//mark last occurance of char 173 | } 174 | } 175 | 176 | ans=a[x][n]; 177 | where x is the length of subseq required 178 | 179 | 10)Binomial coefficent: 180 | C[n][k]=C[n-1][k-1]+C[n-1][k]; 181 | C[n][0]=C[n][n]=1; 182 | 183 | 11)LPS:longest palindrome subseq 184 | dp[n][n]: 185 | First dimmension for l, 186 | and second for r; 187 | dp[i][j]:lps of [i,.....,j] 188 | hence ans=dp[0][n-1]; 189 | 190 | forz(i,n) 191 | dp[i][i]=1; 192 | 193 | length of substing be l: 194 | int l,i,j; 195 | for(l=2;l<=n;l++) 196 | { 197 | for(int i=0;i>Method 1:O(nw) 213 | 214 | 1)Backward DP 215 | dp[n+1][w+1]; 216 | wt[n+1],val[n+1]; 217 | ans is dp[n][w]; 218 | 219 | First dimension for first i objects 220 | second for size of sack 221 | 222 | for(int i=1;i<=n;i++) 223 | { 224 | for(int j=0;j<=w;j++) 225 | { 226 | if(i==0||j==0)dp[i][j]=0; 227 | else if(wt[i]<=j) 228 | { 229 | dp[i][j]=max(val[i]+dp[i-1][j-wt[i]],dp[i-1][j]); 230 | } 231 | else dp[i][j]=dp[i-1][j]; 232 | } 233 | } 234 | 235 | 2)Forward DP:O(nw) 236 | dp[w+1]; 237 | for(int i=0;i>wt>>v; 241 | for(int rem=w-wt,rem>=0;rem--) 242 | { 243 | dp[rem+wt]=max(dp[rem+wt],dp[rem]+v); 244 | } 245 | } 246 | ans=maxe(dp,dp+w+1); 247 | 248 | >>Alternative:O(nv) 249 | 250 | ll wt[n+1],val[n+1]; 251 | ll s=0; 252 | for(int i=1;i<=n;i++) 253 | { 254 | cin>>wt[i]>>val[i]; 255 | s+=val[i]; 256 | } 257 | ll INF=1e18+5; 258 | vectordp(s+1,INF); 259 | dp[0]=0; 260 | //dp[i] the min total weight of items with total value i 261 | for(int i=1;i<=n;i++) 262 | { 263 | for(int j=s;j>=val[i];j--) 264 | { 265 | dp[j]=min(dp[j],dp[j-val[i]]+wt[i]); 266 | } 267 | } 268 | ll ans=0; 269 | forz(i,s+1) 270 | { 271 | if(dp[i]<=w){ 272 | ans=max(ans,ll(i));} 273 | } 274 | 275 | 13) 276 | -------------------------------------------------------------------------------- /DP/matrixexp.cpp: -------------------------------------------------------------------------------- 1 | //BROWNINE TK 2 | 1)F(n) = a*F(n-1) + b*F(n-2) + c*F(n-3) for n >= 3 3 | LET THE SECOND MATRIX BE C 4 | [First Matrix] [Second matrix] [Third Matrix] 5 | | F(n) | = | a b c | * | F(n-1) | 6 | | F(n-1) | | 1 0 0 | | F(n-2) | 7 | | F(n-2) | | 0 1 0 | | F(n-3) | 8 | - - - - - - - - n -2 times - - - - - 9 | | F(n) | = | a b c | * | a b c | * ... * | a b c | * | F(2) | 10 | | F(n-1) | | 1 0 0 | | 1 0 0 | | 1 0 0 | | F(1) | 11 | | F(n-2) | | 0 1 0 | | 0 1 0 | | 0 1 0 | | F(0) | 12 | 13 | 14 | | F(n) | = [ | a b c | ] ^ (n-2) * | F(2) | 15 | | F(n-1) | [ | 1 0 0 | ] | F(1) | 16 | | F(n-2) | [ | 0 1 0 | ] | F(0) | 17 | 18 | i.e,F(n)=C[0][0]*f(2)+C[0][1]*f(1)+C[0][2]*f(0); 19 | 20 | //VERY IMP: 21 | if M is multiplied n times then our job gets easier 22 | we just have to consider the 23 | F(n)=C[0][0]*f(0); 24 | as the f(a)=0 for a<0 25 | 26 | 27 | const int ms=matrixsize; 28 | void mul(ll a[ms][ms],ll b[ms][ms]) 29 | { 30 | ll t[ms][ms]={0}; 31 | forz(i,ms)forz(j,ms)forz(k,ms) 32 | t[i][j]=(t[i][j]+a[i][k]*b[k][j]); 33 | forz(i,ms)forz(j,ms) 34 | a[i][j]=t[i][j]; 35 | } 36 | 37 | ll matpow(ll F[ms][ms],ll n) 38 | { 39 | ll C[ms][ms]={{a,b,c},{1,0,0},{1,0,0}}; 40 | if(n==1) 41 | return (F[0][0]*f(2)+F[0][1]*f(1)+F[0][2]*f(0)); 42 | matpow(F,n/2); 43 | mul(F,F); 44 | if(n%2!=0)mul(F,C); 45 | return (F[0][0]*f(2)+F[0][1]*f(1)+F[0][2]*f(0)); 46 | } 47 | 48 | ll findn(ll n) 49 | { 50 | ll C[ms][ms]={{a,b,c},{1,0,0},{1,0,0}}; 51 | return matpow(C,n-2); 52 | } 53 | 54 | 2)f(n) = f(n-1) + f(n-2) + c 55 | 56 | | f(n) | | f(n+1) | 57 | M x | f(n-1) | = | f(n) | 58 | | c | | c | 59 | 60 | 3)f(n) = if n is odd, f(n-1) else, f(n-2) 61 | In short: 62 | f(n) = (n&1) * f(n-1) + (!(n&1)) * f(n-2) 63 | 64 | Here, we can just split the functions in the basis of odd even and keep 2 different matrix for both of them and calculate separately. Actually, there might appear many different patterns, but these are the basic patterns. 65 | 66 | 4)Lets put it altogether: find matrix suitable for 67 | f(n) = a * f(n-1) + c * f(n-3) + d * f(n-4) + e. 68 | matrix C 69 | | a 0 c d 1 | 70 | | 1 0 0 0 0 | 71 | | 0 1 0 0 0 | 72 | | 0 0 1 0 0 | 73 | | 0 0 0 0 1 | 74 | 75 | 5)Here, g(n+1) = 2g(n) + 2g(n-1) + f(n+1) and f(n+2) = 2f(n+1) + 2f(n). 76 | Now, using the above process, we can generate the objective matrix C as follows: 77 | | g(n) | 78 | | g(n-1) | 79 | | f(n+1) | 80 | | f(n) | 81 | 82 | | 2 2 1 0 | 83 | | 1 0 0 0 | 84 | | 0 0 2 2 | 85 | | 0 0 1 0 | 86 | 87 | IMPLEMENTATION USING STRUCTURES. 88 | struct matrix 89 | { 90 | vector >m; 91 | }; 92 | void msi(matrix &m,ll a,ll b) 93 | { 94 | m.m.resize(a); 95 | forz(i,a) 96 | m.m[i].resize(b); 97 | } 98 | void minit(matrix &m,ll x) 99 | { 100 | forz(i,m.m.size()) 101 | forz(j,m.m[0].size()) 102 | m.m[i][j]=x; 103 | } 104 | matrix mul(matrix m1,matrix m2) 105 | { 106 | matrix m3; 107 | msi(m3,m1.m.size(),m2.m[0].size()); 108 | forz(i,m3.m.size()) 109 | { 110 | forz(j,m3.m[0].size()) 111 | { m3.m[i][j]=0; 112 | forz(k,m1.m[0].size()) 113 | m3.m[i][j]=(m3.m[i][j]+m1.m[i][k]*m2.m[k][j])%mod; 114 | } 115 | } 116 | return m3; 117 | } 118 | matrix mexp(matrix &mx,ll p) 119 | { 120 | matrix res; 121 | msi(res,mx.m.size(),mx.m.size()); 122 | minit(res,0); 123 | forz(i,mx.m.size()) 124 | res.m[i][i]=1; 125 | while(p>0) 126 | { 127 | if(p&1) 128 | res=mul(res,mx); 129 | mx=mul(mx,mx); 130 | p=p>>1; 131 | } 132 | return res; 133 | } 134 | //CODE FOR FIBO 135 | int main() 136 | { 137 | kira; 138 | ll n; 139 | cin>>n; 140 | matrix ans; 141 | msi(ans,3,3); 142 | minit(ans,0); 143 | ans.m[0][0]=1; 144 | ans.m[0][1]=1; 145 | ans.m[0][2]=1; 146 | for(int i=1;i<3;i++) 147 | { 148 | ans.m[i][i-1]=1; 149 | } 150 | ans=mexp(ans,n); 151 | ll res=ans.m[0][0]; 152 | cout<>Ford-fullkerson :O(fE) 3 | >>Edmond's Karp Algo:O(VE^2) 4 | >>Dinic:O(min(fE,EV^2)) 5 | 6 | struct FlowEdge 7 | { 8 | int v, u; 9 | ll cap, flow = 0; 10 | FlowEdge(int v, int u, ll cap) : v(v), u(u), cap(cap) {} 11 | }; 12 | 13 | struct Dinic 14 | { 15 | const ll flow_inf = 1e18; 16 | vector edges; 17 | vector> adj; 18 | int n, m = 0; 19 | int s, t; 20 | vector level, ptr; 21 | queue q; 22 | 23 | Dinic(int n, int s, int t) : n(n), s(s), t(t) 24 | { 25 | adj.resize(n); 26 | level.resize(n); 27 | ptr.resize(n); 28 | } 29 | 30 | void add_edge(int v, int u, ll cap) 31 | { 32 | edges.emplace_back(v, u, cap); 33 | edges.emplace_back(u, v, 0); 34 | adj[v].push_back(m); 35 | adj[u].push_back(m + 1); 36 | m += 2; 37 | } 38 | 39 | bool bfs() 40 | { 41 | while (!q.empty()) 42 | { 43 | int v = q.front(); 44 | q.pop(); 45 | for (int id : adj[v]) 46 | { 47 | if (edges[id].cap - edges[id].flow < 1) 48 | continue; 49 | if (level[edges[id].u] != -1) 50 | continue; 51 | level[edges[id].u] = level[v] + 1; 52 | q.push(edges[id].u); 53 | } 54 | } 55 | return level[t] != -1; 56 | } 57 | 58 | ll dfs(int v, ll pushed) 59 | { 60 | if (pushed == 0) 61 | return 0; 62 | if (v == t) 63 | return pushed; 64 | for (int &cid = ptr[v]; cid < (int)adj[v].size(); cid++) 65 | { 66 | int id = adj[v][cid]; 67 | int u = edges[id].u; 68 | if (level[v] + 1 != level[u] || edges[id].cap - edges[id].flow < 1) 69 | continue; 70 | ll tr = dfs(u, min(pushed, edges[id].cap - edges[id].flow)); 71 | if (tr == 0) 72 | continue; 73 | edges[id].flow += tr; 74 | edges[id ^ 1].flow -= tr; 75 | return tr; 76 | } 77 | return 0; 78 | } 79 | 80 | ll flow() 81 | { 82 | ll f = 0; 83 | while (true) 84 | { 85 | fill(level.begin(), level.end(), -1); 86 | level[s] = 0; 87 | q.push(s); 88 | if (!bfs()) 89 | break; 90 | fill(ptr.begin(), ptr.end(), 0); 91 | while (ll pushed = dfs(s, flow_inf)) 92 | { 93 | f += pushed; 94 | } 95 | } 96 | return f; 97 | } 98 | }; 99 | int main() 100 | { 101 | kira; 102 | int n,m; 103 | cin>>n>>m; 104 | Dinic dinic(n+1,1,n); 105 | int eu,ev,ew; 106 | forz(i,m) 107 | { 108 | cin>>eu>>ev>>ew; 109 | dinic.add_edge(eu,ev,ew); 110 | } 111 | cout< edges; 12 | vector> adj; 13 | int n, m = 0; 14 | int s, t; 15 | vector level, ptr; 16 | queue q; 17 | 18 | Dinic(int n, int s, int t) : n(n), s(s), t(t) 19 | { 20 | adj.resize(n); 21 | level.resize(n); 22 | ptr.resize(n); 23 | } 24 | 25 | void add_edge(int v, int u, ll cap) 26 | { 27 | edges.emplace_back(v, u, cap); 28 | edges.emplace_back(u, v, 0); 29 | adj[v].push_back(m); 30 | adj[u].push_back(m + 1); 31 | m += 2; 32 | } 33 | 34 | bool bfs() 35 | { 36 | while (!q.empty()) 37 | { 38 | int v = q.front(); 39 | q.pop(); 40 | for (int id : adj[v]) 41 | { 42 | if (edges[id].cap - edges[id].flow < 1) 43 | continue; 44 | if (level[edges[id].u] != -1) 45 | continue; 46 | level[edges[id].u] = level[v] + 1; 47 | q.push(edges[id].u); 48 | } 49 | } 50 | return level[t] != -1; 51 | } 52 | 53 | ll dfs(int v, ll pushed) 54 | { 55 | if (pushed == 0) 56 | return 0; 57 | if (v == t) 58 | return pushed; 59 | for (int &cid = ptr[v]; cid < (int)adj[v].size(); cid++) 60 | { 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 | ll 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 | ll flow() 76 | { 77 | ll f = 0; 78 | while (true) 79 | { 80 | fill(level.begin(), level.end(), -1); 81 | level[s] = 0; 82 | q.push(s); 83 | if (!bfs()) 84 | break; 85 | fill(ptr.begin(), ptr.end(), 0); 86 | while (ll pushed = dfs(s, flow_inf)) 87 | { 88 | f += pushed; 89 | } 90 | } 91 | return f; 92 | } 93 | }; 94 | 95 | vector adj[505]; 96 | bool edge_taken[505][505]; 97 | bool vis[505]; 98 | vector res; 99 | int n, m; 100 | 101 | void dfs(int s) 102 | { 103 | if (s == n) 104 | { 105 | p1(int(res.si)); 106 | for (auto x : res) 107 | p0(x); 108 | cout << endl; 109 | return; 110 | } 111 | vis[s] = true; 112 | for (auto u : adj[s]) 113 | { 114 | if (!vis[u] && edge_taken[s][u]) 115 | { 116 | res.pb(u); 117 | dfs(u); 118 | res.pop_back(); 119 | edge_taken[s][u] = false; 120 | } 121 | } 122 | } 123 | int main() 124 | { 125 | kira; 126 | cin >> n >> m; 127 | Dinic dinic(n + 1, 1, n); 128 | 129 | forz(i, m) 130 | { 131 | int u, v; 132 | cin >> u >> v; 133 | dinic.add_edge(u, v, 1); 134 | adj[u].pb(v); 135 | adj[v].pb(u); 136 | } 137 | 138 | cout << dinic.flow() << endl; 139 | for (auto x : dinic.edges) 140 | if (x.flow ==1) 141 | edge_taken[x.v][x.u] = true; 142 | 143 | res.pb(1); 144 | dfs(1); 145 | return 0; 146 | } -------------------------------------------------------------------------------- /Flows/max_match.cpp: -------------------------------------------------------------------------------- 1 | 1)n boys and m girls to be matched 2 | 2)Hopkorft Algo is special case of Dinic 3 | 3)O(EV^(1/2)) 4 | 4)Insert two dummy nodes and convert the problem to a max 5 | flow problem 6 | 7 | struct FlowEdge 8 | { 9 | int v, u; 10 | ll cap, flow = 0; 11 | FlowEdge(int v, int u, ll cap) : v(v), u(u), cap(cap) {} 12 | }; 13 | 14 | struct Dinic 15 | { 16 | const ll flow_inf = 1e18; 17 | vector edges; 18 | vector> adj; 19 | int n, m = 0; 20 | int s, t; 21 | vector level, ptr; 22 | queue q; 23 | 24 | Dinic(int n, int s, int t) : n(n), s(s), t(t) 25 | { 26 | adj.resize(n); 27 | level.resize(n); 28 | ptr.resize(n); 29 | } 30 | 31 | void add_edge(int v, int u, ll cap) 32 | { 33 | edges.emplace_back(v, u, cap); 34 | edges.emplace_back(u, v, 0); 35 | adj[v].push_back(m); 36 | adj[u].push_back(m + 1); 37 | m += 2; 38 | } 39 | 40 | bool bfs() 41 | { 42 | while (!q.empty()) 43 | { 44 | int v = q.front(); 45 | q.pop(); 46 | for (int id : adj[v]) 47 | { 48 | if (edges[id].cap - edges[id].flow < 1) 49 | continue; 50 | if (level[edges[id].u] != -1) 51 | continue; 52 | level[edges[id].u] = level[v] + 1; 53 | q.push(edges[id].u); 54 | } 55 | } 56 | return level[t] != -1; 57 | } 58 | 59 | ll dfs(int v, ll pushed) 60 | { 61 | if (pushed == 0) 62 | return 0; 63 | if (v == t) 64 | return pushed; 65 | for (int &cid = ptr[v]; cid < (int)adj[v].size(); cid++) 66 | { 67 | int id = adj[v][cid]; 68 | int u = edges[id].u; 69 | if (level[v] + 1 != level[u] || edges[id].cap - edges[id].flow < 1) 70 | continue; 71 | ll tr = dfs(u, min(pushed, edges[id].cap - edges[id].flow)); 72 | if (tr == 0) 73 | continue; 74 | edges[id].flow += tr; 75 | edges[id ^ 1].flow -= tr; 76 | return tr; 77 | } 78 | return 0; 79 | } 80 | 81 | vector flow() 82 | { 83 | ll f = 0; 84 | while (true) 85 | { 86 | fill(level.begin(), level.end(), -1); 87 | level[s] = 0; 88 | q.push(s); 89 | if (!bfs()) 90 | break; 91 | fill(ptr.begin(), ptr.end(), 0); 92 | while (ll pushed = dfs(s, flow_inf)) 93 | { 94 | f += pushed; 95 | } 96 | } 97 | vector res; 98 | for (auto x : edges) 99 | { 100 | if (x.flow == 1&&x.v> n >> m >> k; 113 | Dinic dinic(n + m + 3, 1, n + m + 2); 114 | 115 | forz(i, k) 116 | { 117 | int u, v; 118 | cin >> u >> v; 119 | u++; 120 | v++; 121 | dinic.add_edge(u, v + n, 1); 122 | } 123 | 124 | for (int i = 2; i <= n + 1; i++) 125 | { 126 | dinic.add_edge(1, i, 1); 127 | } 128 | 129 | for (int i = n + 2; i <= n + m + 1; i++) 130 | { 131 | dinic.add_edge(i, n + m + 2, 1); 132 | } 133 | 134 | vector ans = dinic.flow(); 135 | cout< edges; 12 | vector> adj; 13 | int n, m = 0; 14 | int s, t; 15 | vector level, ptr; 16 | queue q; 17 | 18 | Dinic(int n, int s, int t) : n(n), s(s), t(t) 19 | { 20 | adj.resize(n); 21 | level.resize(n); 22 | ptr.resize(n); 23 | } 24 | 25 | void add_edge(int v, int u, ll cap) 26 | { 27 | edges.emplace_back(v, u, cap); 28 | edges.emplace_back(u, v, 0); 29 | adj[v].push_back(m); 30 | adj[u].push_back(m + 1); 31 | m += 2; 32 | } 33 | 34 | bool bfs() 35 | { 36 | while (!q.empty()) 37 | { 38 | int v = q.front(); 39 | q.pop(); 40 | for (int id : adj[v]) 41 | { 42 | if (edges[id].cap - edges[id].flow < 1) 43 | continue; 44 | if (level[edges[id].u] != -1) 45 | continue; 46 | level[edges[id].u] = level[v] + 1; 47 | q.push(edges[id].u); 48 | } 49 | } 50 | return level[t] != -1; 51 | } 52 | 53 | ll dfs(int v, ll pushed) 54 | { 55 | if (pushed == 0) 56 | return 0; 57 | if (v == t) 58 | return pushed; 59 | for (int &cid = ptr[v]; cid < (int)adj[v].size(); cid++) 60 | { 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 | ll 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 | ll flow() 76 | { 77 | ll f = 0; 78 | while (true) 79 | { 80 | fill(level.begin(), level.end(), -1); 81 | level[s] = 0; 82 | q.push(s); 83 | if (!bfs()) 84 | break; 85 | fill(ptr.begin(), ptr.end(), 0); 86 | while (ll pushed = dfs(s, flow_inf)) 87 | { 88 | f += pushed; 89 | } 90 | } 91 | return f; 92 | } 93 | }; 94 | 95 | bool hasEdge[505][505]; 96 | vector positive, negative; 97 | 98 | int main() 99 | { 100 | kira; 101 | int n, m; 102 | cin >> n >> m; 103 | Dinic dinic(n + 1, 1, n); 104 | 105 | forz(i,m) 106 | { 107 | int u, v; 108 | cin >> u >> v; 109 | dinic.add_edge(u, v, 1); 110 | dinic.add_edge(v, u, 1); 111 | hasEdge[u][v] = true; 112 | hasEdge[v][u] = true; 113 | } 114 | 115 | cout << dinic.flow() << endl; 116 | 117 | for (int i = 1; i <= n; ++i) 118 | { 119 | if (dinic.level[i] >= 0) 120 | positive.push_back(i); 121 | else 122 | negative.push_back(i); 123 | } 124 | 125 | for (auto x : positive) 126 | for (auto y : negative) 127 | if (hasEdge[x][y]) 128 | p2(x, y); 129 | 130 | return 0; 131 | } -------------------------------------------------------------------------------- /Game/Game.md: -------------------------------------------------------------------------------- 1 | # Game Theory 2 | 3 | 1. **Nim-Sum:** The cumulative XOR value of the number of coins/stones in each piles/heaps at any point of the game is called Nim-Sum at that point. 4 | 2. Optimal strategy for each player is to make the Nim Sum for his opponent zero in each of their turn 5 | 3. **MEX:** Minimum excludant’ a.k.a ‘Mex’ of a set of numbers is the smallest non-negative number not present in the set. 6 | **eg: mex({0,1,4,7,12})=2** 7 | 4. The Grundy Number/ nimber is equal to 0 for a game that is lost immediately by the first player, and is equal to Mex of the nimbers of all possible next positions for any other game. 8 | 9 | ```C++ 10 | ll mex(unordered_sets) 11 | { 12 | ll Mex=0; 13 | while(s.find(Mex)!=s.end())Mex++; 14 | return Mex; 15 | } 16 | 17 | ll grundy(ll n) 18 | { 19 | //if only 1,2,3 stones can be removed from a pile 20 | for(int i=0;i<=3;i++) 21 | if(n==i)return i; 22 | 23 | if(g[n]!=-1) 24 | return(g[n]); 25 | 26 | unordered_sets; 27 | for(int i=1;i<=3;i++)s.insert(grundy(n-i,g)); 28 | g[n]=mex(s); 29 | return g[n]; 30 | } 31 | 32 | int main() 33 | { 34 | ll g[n+1]; 35 | memset(g,-1,sizeof(g)); 36 | return 0; 37 | } 38 | ``` 39 | 40 | ## Sprague-Grundy Theorem 41 | 1. Break the composite game into sub-games. 42 | 2. Then for each sub-game, calculate the Grundy Number at that position. 43 | 3. Then calculate the XOR of all the calculated Grundy Numbers. 44 | 4. If the XOR value is non-zero, then the player who is going to make the turn (First Player) will win else he is destined to lose, no matter what. 45 | 46 | -------------------------------------------------------------------------------- /Geometry/convexhull.cpp: -------------------------------------------------------------------------------- 1 | bool cw(pll a, pll b, pll c) 2 | { 3 | return a.F * (b.S - c.S) + b.F * (c.S - a.S) + c.F * (a.S - b.S) < 0; 4 | } 5 | 6 | bool ccw(pll a, pll b, pll c) 7 | { 8 | return a.F * (b.S - c.S) + b.F * (c.S - a.S) + c.F * (a.S - b.S) > 0; 9 | } 10 | 11 | vector convex(vector a) 12 | { 13 | vector v = a; 14 | int n = int(v.si); 15 | if (n == 1) 16 | return v; 17 | 18 | sort(all(v)); 19 | v.erase(unique(all(v)),v.en); 20 | 21 | vector up, down; 22 | pll p1 = v[0], p2 = v.back(); 23 | up.pb(p1); 24 | down.pb(p1); 25 | 26 | if (p1 == p2) 27 | return {p1}; 28 | 29 | for (int i = 1; i < v.si; i++) 30 | { 31 | if (i == int(v.si - 1) || cw(p1, v[i], p2)) 32 | { 33 | while (up.si >= 2 && !cw(up[up.size() - 2], up[up.size() - 1], v[i])) 34 | up.pop_back(); 35 | up.pb(v[i]); 36 | } 37 | if (i == v.si - 1 || ccw(p1, v[i], p2)) 38 | { 39 | while (down.si >= 2 && !ccw(down[down.size() - 2], down[down.size() - 1], v[i])) 40 | down.pop_back(); 41 | down.pb(v[i]); 42 | } 43 | } 44 | 45 | v.clear(); 46 | for (auto x : up) 47 | v.pb(x); 48 | for (int i = down.si - 2; i > 0; i--) 49 | v.pb(down[i]); 50 | 51 | return v; 52 | } 53 | 54 | int main() 55 | { 56 | kira; 57 | ll n; 58 | cin >> n; 59 | 60 | vector v; 61 | ll x, y; 62 | forz(i, n) 63 | { 64 | cin >> x >> y; 65 | v.pb({x, y}); 66 | } 67 | 68 | vector con = convex(v); 69 | reverse(all(con)); 70 | 71 | p1(con.si); 72 | for (auto x : con) 73 | { 74 | p2(x.F, x.S); 75 | } 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /Graphs/Bridges/bridge.cpp: -------------------------------------------------------------------------------- 1 | const int N = 1e5 + 5; 2 | vector adj[N]; 3 | int tin[N], low[N]; 4 | int timer; 5 | bool vis[N]; 6 | 7 | vector bridges; 8 | 9 | void dfs(int curr, int par) 10 | { 11 | vis[curr] = true; 12 | tin[curr] = timer; 13 | low[curr] = timer; 14 | timer++; 15 | 16 | for (auto child : adj[curr]) 17 | { 18 | if (child == par) 19 | continue; 20 | if (vis[child]) 21 | { 22 | low[curr] = min(low[curr], tin[child]); 23 | } 24 | else 25 | { 26 | dfs(child, curr); 27 | low[curr] = min(low[curr], low[child]); 28 | if (low[child] > tin[curr]) 29 | { 30 | bridges.pb({curr, child}); 31 | } 32 | } 33 | } 34 | } 35 | 36 | int main() 37 | { 38 | kira; 39 | 40 | int n, m; 41 | cin >> n >> m; 42 | 43 | int eu, ev; 44 | forz(i, m) 45 | { 46 | cin >> eu >> ev; 47 | adj[eu].pb(ev); 48 | adj[ev].pb(eu); 49 | } 50 | 51 | for (int i = 1; i <= n; i++) 52 | { 53 | if (!vis[i]) 54 | dfs(i, 0); 55 | } 56 | 57 | cout << bridges.size() << endl; 58 | for (auto x : bridges) 59 | { 60 | p2(x.F, x.S); 61 | } 62 | 63 | run_time(); 64 | return 0; 65 | } -------------------------------------------------------------------------------- /Graphs/Components/2D-DSU.cpp: -------------------------------------------------------------------------------- 1 | const int N = 1e6 + 2005; 2 | ll parent[N]; 3 | ll siz[N]; 4 | bool vis[N]; 5 | void make(ll v) 6 | { 7 | parent[v] = v; 8 | siz[v] = 1; 9 | } 10 | 11 | ll find(ll v) 12 | { 13 | if (v == parent[v]) 14 | return v; 15 | return parent[v] = find(parent[v]); 16 | } 17 | 18 | void merge(ll a, ll b) 19 | { 20 | a = find(a); 21 | b = find(b); 22 | if (a != b) 23 | { 24 | if (siz[a] < siz[b]) 25 | swap(a, b); 26 | parent[b] = a; 27 | siz[a] += siz[b]; 28 | } 29 | } 30 | ll n, m; 31 | ll index(ll i, ll j) 32 | { 33 | return i * (m + 1) + j; 34 | } 35 | int main() 36 | { 37 | kira; 38 | cin >> n >> m; 39 | vector> c(n + 1, vector(m + 1, '0')); 40 | forz(i, n + 1) forz(j, m + 1) make(index(i, j)); 41 | for (int i = 1; i <= n; i++) 42 | { 43 | for (int j = 1; j <= m; j++) 44 | { 45 | cin>>c[i][j]; 46 | if (c[i][j] == c[i - 1][j] && c[i][j] == '.') 47 | merge(index(i, j), index(i - 1, j)); 48 | if (c[i][j] == c[i][j - 1] && c[i][j] == '.') 49 | merge(index(i, j), index(i, j - 1)); 50 | } 51 | } 52 | ll cnt=0; 53 | forz(i,n+1) 54 | { 55 | forz(j,m+1) 56 | { 57 | if(c[i][j]=='.') 58 | { 59 | vis[find(index(i,j))]=true; 60 | } 61 | } 62 | } 63 | forz(i,(n+1)*(m+1)) 64 | { 65 | if(vis[i])cnt++; 66 | } 67 | cout< adj[N]; 3 | vector adr[N]; 4 | vector vis(N), assignment(N); 5 | vector order; 6 | int component[N]; 7 | 8 | void dfs1(int s) 9 | { 10 | vis[s] = true; 11 | for (auto u : adj[s]) 12 | { 13 | if (!vis[u]) 14 | dfs1(u); 15 | } 16 | order.pb(s); 17 | } 18 | 19 | void dfs2(int s, int cnt) 20 | { 21 | vis[s] = true; 22 | component[s] = cnt; 23 | 24 | for (auto u : adr[s]) 25 | { 26 | if (!vis[u]) 27 | dfs2(u, cnt); 28 | } 29 | } 30 | 31 | void edges(int a, int b, int na, int nb) 32 | { 33 | adj[na].pb(b); 34 | adj[nb].pb(a); 35 | 36 | adr[b].pb(na); 37 | adr[a].pb(nb); 38 | } 39 | 40 | int main() 41 | { 42 | kira; 43 | 44 | int n, m, eu, ev; 45 | char u, v; 46 | 47 | cin >> m >> n; 48 | 49 | forz(i, m) 50 | { 51 | cin >> u >> eu >> v >> ev; 52 | int nu = 2 * eu; 53 | int nv = 2 * ev; 54 | eu = nu - 1; 55 | ev = nv - 1; 56 | 57 | if (u == '+' && v == '+') 58 | edges(eu, ev, nu, nv); 59 | if (u == '-' && v == '+') 60 | edges(nu, ev, eu, nv); 61 | if (u == '+' && v == '-') 62 | edges(eu, nv, nu, ev); 63 | if (u == '-' && v == '-') 64 | edges(nu, nv, eu, ev); 65 | } 66 | 67 | n = 2 * n; 68 | vis.assign(n + 1, false); 69 | 70 | fore(i, 1, n) 71 | { 72 | if (!vis[i]) 73 | dfs1(i); 74 | } 75 | 76 | int cnt = 0; 77 | vis.assign(n + 1, false); 78 | 79 | fore(i, 1, n) 80 | { 81 | int v = order[n - i]; 82 | if (!vis[v]) 83 | { 84 | dfs2(v, cnt++); 85 | } 86 | } 87 | 88 | assignment.assign(n + 1, false); 89 | for (int i = 1; i <= n; i += 2) 90 | { 91 | if (component[i] == component[i + 1]) 92 | { 93 | p1("IMPOSSIBLE"); 94 | break; 95 | } 96 | assignment[(i + 1) / 2] = component[i] > component[i + 1]; 97 | } 98 | 99 | for (int i = 1; i <= n/2; i++) 100 | { 101 | cout << (assignment[i] ? "+" : "-") << " "; 102 | } 103 | 104 | return 0; 105 | } -------------------------------------------------------------------------------- /Graphs/Components/DSU.cpp: -------------------------------------------------------------------------------- 1 | 1)make(v) - creates a new set consisting of the new element v 2 | 2)merge(a, b) - merges the two specified sets 3 | 3)find(v) - returns the representative of the set that contains the element v.It is selected in each set by the data structure itself (and can change over time, namely after union_sets calls). This representative can be used to check if two elements are part of the same set of not. a and b are exactly in the same set, if find(a) == find(b). Otherwise they are in different sets. 4 | 4)Always connect the representative of the smaller set to the representative of the larger set . Using this strategy, the length of any chain will be O(logn), so we can find the representative of any element efficiently by following the corresponding chain. 5 | 5)UNION BY SIZE 6 | const int N= 7 | ll parent[N]; 8 | ll siz[N]; 9 | void make(ll v) 10 | { 11 | parent[v]=v; 12 | siz[v]=1; 13 | } 14 | 15 | ll find(ll v) 16 | { 17 | if(v==parent[v])return v; 18 | return parent[v]=find(parent[v]); 19 | } 20 | 21 | void merge(ll a,ll b) 22 | { 23 | a=find(a); 24 | b=find(b); 25 | if(a!=b) 26 | { 27 | if(siz[a] adj[N]; 3 | vector adr[N]; 4 | vector vis(N); 5 | vector order, component; 6 | 7 | void dfs1(int s) 8 | { 9 | vis[s] = true; 10 | for (auto u : adj[s]) 11 | { 12 | if (!vis[u]) 13 | dfs1(u); 14 | } 15 | order.pb(s); 16 | } 17 | 18 | void dfs2(int s) 19 | { 20 | vis[s] = true; 21 | component.pb(s); 22 | for (auto u : adr[s]) 23 | { 24 | if (!vis[u]) 25 | dfs2(u); 26 | } 27 | } 28 | 29 | int main() 30 | { 31 | kira; 32 | int n, m, a, b; 33 | cin >> n >> m; 34 | forz(i, m) 35 | { 36 | cin >> a >> b; 37 | adj[a].pb(b); 38 | adr[b].pb(a); 39 | } 40 | 41 | vis.assign(n + 1, false); 42 | fore(i, 1, n) 43 | { 44 | if (!vis[i]) 45 | dfs1(i); 46 | } 47 | 48 | int cnt = 0; 49 | vector ans; 50 | 51 | vis.assign(n + 1, false); 52 | fore(i, 1, n) 53 | { 54 | int v = order[n - i]; 55 | if (!vis[v]) 56 | { 57 | cnt++; 58 | ans.pb(v); 59 | dfs2(v); 60 | component.clear(); 61 | } 62 | } 63 | return 0; 64 | } -------------------------------------------------------------------------------- /Graphs/Cut_vertices/cut.cpp: -------------------------------------------------------------------------------- 1 | const int N = 1e5 + 5; 2 | vector adj[N]; 3 | int tin[N], low[N]; 4 | int timer; 5 | bool vis[N]; 6 | 7 | vector cut_vertex; 8 | 9 | void dfs(int curr, int par) 10 | { 11 | vis[curr] = true; 12 | tin[curr] = timer; 13 | low[curr] = timer; 14 | int children = 0; 15 | timer++; 16 | 17 | int f = 0; // Avoid duplicates 18 | for (auto child : adj[curr]) 19 | { 20 | if (child == par) 21 | continue; 22 | if (vis[child]) 23 | { 24 | low[curr] = min(low[curr], tin[child]); 25 | } 26 | else 27 | { 28 | 29 | dfs(child, curr); 30 | low[curr] = min(low[curr], low[child]); 31 | 32 | if (low[child] >= tin[curr] && par != 0 && f == 0) 33 | { 34 | cut_vertex.pb(curr); 35 | f = 1; 36 | } 37 | children++; 38 | } 39 | } 40 | 41 | if (par == 0 && children > 1) 42 | cut_vertex.pb(curr); 43 | } 44 | 45 | int main() 46 | { 47 | kira; 48 | 49 | int n, m; 50 | cin >> n >> m; 51 | 52 | int eu, ev; 53 | forz(i, m) 54 | { 55 | cin >> eu >> ev; 56 | adj[eu].pb(ev); 57 | adj[ev].pb(eu); 58 | } 59 | 60 | for (int i = 1; i <= n; i++) 61 | { 62 | if (!vis[i]) 63 | dfs(i, 0); 64 | } 65 | 66 | cout << cut_vertex.size() << endl; 67 | for (auto x : cut_vertex) 68 | { 69 | p0(x); 70 | } 71 | 72 | run_time(); 73 | return 0; 74 | } -------------------------------------------------------------------------------- /Graphs/DAG/topo.cpp: -------------------------------------------------------------------------------- 1 | 2 | const int N = 2e5 + 5; 3 | vector adj[N]; 4 | vector ans; 5 | bool vis[N]; 6 | int n,m; 7 | 8 | void dfs(int s) 9 | { 10 | vis[s] = true; 11 | for (auto u : adj[s]) 12 | { 13 | if (vis[u]) 14 | continue; 15 | dfs(u); 16 | } 17 | ans.pb(s); 18 | } 19 | 20 | void toposort() 21 | { 22 | for (int i = 1; i <= n; i++) 23 | { 24 | if (!vis[i]) 25 | dfs(i); 26 | } 27 | reverse(all(ans)); 28 | } -------------------------------------------------------------------------------- /Graphs/Eulerian/hierholzers-algorithm.cpp: -------------------------------------------------------------------------------- 1 | //Eulerian cycle 2 | 3 | const int N = 2e5 + 5; 4 | listadj[N]; 5 | int deg[N]; 6 | bool vis[N]; 7 | int cnt = 0; 8 | stackhead,tail; 9 | 10 | void dfs(int s) 11 | { 12 | vis[s] = true; 13 | cnt++; 14 | for (auto u : adj[s]) 15 | { 16 | if (vis[u]) 17 | continue; 18 | dfs(u); 19 | } 20 | } 21 | 22 | int main() 23 | { 24 | 25 | int n, m, x, y; 26 | cin >> n >> m; 27 | 28 | forz(i,m) 29 | { 30 | cin >> x >> y; 31 | adj[x].pb(y); 32 | adj[y].pb(x); 33 | ++deg[x]; 34 | ++deg[y]; 35 | } 36 | 37 | int f = 1; 38 | for (int i = 1; i <= n; i++) 39 | { 40 | if (int(adj[i].size()) == 0) 41 | cnt++; 42 | if (int(adj[i].size()) % 2) 43 | f = 0; 44 | } 45 | 46 | dfs(1); 47 | if (cnt != n || f == 0) 48 | { 49 | //Eulerian Cycle Exsists only if graph is connected 50 | //Nodes with zero degree maynnot be in the component 51 | //and all nodes have even degrees 52 | cout << "IMPOSSIBLE"; 53 | return 0; 54 | } 55 | 56 | head.push(1); 57 | while (!head.empty()) 58 | { 59 | while (deg[head.top()]) 60 | { 61 | int v = adj[head.top()].back(); 62 | adj[head.top()].pop_back(); 63 | adj[v].remove(head.top()); 64 | --deg[head.top()]; 65 | head.push(v); 66 | --deg[v]; 67 | } 68 | while (!head.empty() && !deg[head.top()]) 69 | { 70 | tail.push(head.top()); 71 | head.pop(); 72 | } 73 | } 74 | 75 | while (!tail.empty()) 76 | { 77 | cout << tail.top() << " "; 78 | tail.pop(); 79 | } 80 | 81 | run_time(); 82 | return 0; 83 | } -------------------------------------------------------------------------------- /Graphs/Kinght_tour/knight.cpp: -------------------------------------------------------------------------------- 1 | const int n = 8; 2 | int sx, sy; 3 | int a[64]; 4 | 5 | static int cx[n] = {1, 1, 2, 2, -1, -1, -2, -2}; 6 | static int cy[n] = {2, -2, 1, -1, 2, -2, 1, -1}; 7 | 8 | bool limits(int x, int y) 9 | { 10 | return (x >= 0 && y >= 0 && x < n && y < n); 11 | } 12 | 13 | bool isempty(int x, int y) 14 | { 15 | return (limits(x, y) && a[x * n + y] < 0); 16 | } 17 | 18 | bool neigh(int x, int y, int xx, int yy) 19 | { 20 | forz(i, n) 21 | { 22 | if ((x + cx[i] == xx) && (y + cy[i] == yy)) 23 | return true; 24 | } 25 | return false; 26 | } 27 | 28 | void print() 29 | { 30 | forz(i, n) 31 | { 32 | forz(j, n) p0(a[i * n + j]); 33 | cout << endl; 34 | } 35 | } 36 | 37 | int getdeg(int x, int y) 38 | { 39 | int cnt = 0; 40 | forz(i, n) 41 | { 42 | if (isempty(x + cx[i], y + cy[i])) 43 | { 44 | cnt++; 45 | } 46 | } 47 | return cnt; 48 | } 49 | 50 | pii nextmov(int x, int y) 51 | { 52 | int min_id = -1, min_deg = n + 1; 53 | int c, nx, ny; 54 | 55 | int start = rand() % n; 56 | forz(i, n) 57 | { 58 | int ci = (start + i) % n; 59 | nx = x + cx[ci]; 60 | ny = y + cy[ci]; 61 | 62 | if (isempty(nx, ny) && (c = getdeg(nx, ny)) < min_deg) 63 | { 64 | min_id = ci; 65 | min_deg = c; 66 | } 67 | } 68 | if (min_id == -1) 69 | return {-1, -1}; 70 | 71 | nx = x + cx[min_id]; 72 | ny = y + cy[min_id]; 73 | 74 | a[nx * n + ny] = a[x * n + y] + 1; 75 | 76 | return {nx, ny}; 77 | } 78 | 79 | bool knight() 80 | { 81 | memset(a, -1, sizeof(a)); 82 | int x = sx; 83 | int y = sy; 84 | a[x * n + y] = 1; 85 | 86 | forz(i, 63) 87 | { 88 | debug(x,y); 89 | pii p = nextmov(x, y); 90 | if (p.F == -1 && p.S==-1) 91 | return false; 92 | else 93 | { 94 | x = p.F; 95 | y = p.S; 96 | } 97 | } 98 | 99 | if (!neigh(x, y, sx, sy)) 100 | return false; 101 | 102 | print(); 103 | return true; 104 | } 105 | 106 | int main() 107 | { 108 | kira; 109 | cin >> sy >> sx; 110 | sx--; 111 | sy--; 112 | 113 | srand(time(0)); 114 | while (!knight()) 115 | 116 | return 0; 117 | } -------------------------------------------------------------------------------- /Graphs/MST/Kruskal.cpp: -------------------------------------------------------------------------------- 1 | Kruskals Algo 2 | 1)A spanning tree of a graph consists of all nodes of the graph and some of the edges of the graph so that there is a path between any two nodes. Like trees in general, spanning trees are connected and acyclic. Usually there are several ways to construct a spanning tree. 3 | 2)In Kruskal’s algorithm1, the initial spanning tree only contains the nodes of the graph and does not contain any edges. Then the algorithm goes through the edges ordered by their weights, and always adds an edge to the tree if it does not create a cycle. 4 | 3)edges are sorted in asc,des order depending on their weights. 5 | (edge is added between two nodes if they dont belong to same component) 6 | 7 | USE disjoint set union. 8 | 9 | struct edge 10 | { 11 | ll u,v,weight; 12 | bool operator<(edge const& other) 13 | { 14 | return weightedges,result; 18 | ll cost=0; 19 | sort(all(edges)); 20 | for(edge e:edges) 21 | { 22 | if(find(e.u)!=find(e.v)) 23 | { 24 | cost+=e.weight; 25 | result.pb(e); 26 | merge(e.u,e.v); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Graphs/Shortest_paths/Dijkstra.cpp: -------------------------------------------------------------------------------- 1 | 1)The benefit of Dijsktra’s algorithm is that it is more efficient 2 | and can be used for processing large graphs. 3 | However, the algorithm requires that there are NO negative weight 4 | edges in the graph. 5 | 6 | 2)At each step, Dijkstra’s algorithm selects a node that has not 7 | been processed yet and whose distance is as small as possible. 8 | The first such node is node 1 with distance 0. 9 | 10 | 3)adj[a] contains a pair (b,w) always when there is an edge from 11 | node a to node b with weight w. 12 | 13 | 4)In the following code, the priority queue q contains pairs of 14 | the form (−d, x), meaning that the current distance to node x is d. 15 | 16 | vector dijsktra(int x) 17 | { 18 | priority_queue> q; 19 | vector vis(n + 1, false); 20 | vector p(n + 1, -1); 21 | vector dis(n + 1, INF); 22 | 23 | dis[x] = 0; 24 | q.push({0, x}); 25 | while (!q.empty()) 26 | { 27 | int s = q.top().S; 28 | q.pop(); 29 | if (vis[s]) 30 | continue; 31 | vis[s] = true; 32 | for (auto u : adj[s]) 33 | { 34 | int b = u.F; 35 | int w = u.S; 36 | if (dis[s] + w < dis[b]) 37 | { 38 | dis[b] = dis[s] + w; 39 | p[b] = s; 40 | q.push({-dis[b], b}); 41 | } 42 | } 43 | } 44 | return dis; 45 | } 46 | -------------------------------------------------------------------------------- /Graphs/Shortest_paths/bellman.md: -------------------------------------------------------------------------------- 1 | # Bellman Ford Algorithm: 2 | 1. Used to find shortest distances from a source to all the other vertices. 3 | 2. V : No of vertices 4 | 3. E : No of edges 5 | 4. Time complexity O(VE) 6 | 5. |V|-1 iterations required 7 | 6. All edges checked in each of the iteration. 8 | 7. ith iteration uses i edges between (u,v) to minimise the distances. 9 | 8. If at |V| iteration any distance reduces then we have a negative cycle. 10 | 9. Note the following code works for only one source. 11 | 10. To detect all the negative cycles in a graph add a dummy node. 12 | [CSES Cycle Finding](https://cses.fi/paste/ea456a7a7f180d4566144/) 13 | 14 | ```C++ 15 | const int N = 2505; 16 | const ll INF = LLONG_MAX; 17 | ll dis[N]; 18 | 19 | struct edge 20 | { 21 | ll u, v, w; 22 | }; 23 | vector edges; 24 | 25 | int main() 26 | { 27 | 28 | kira; 29 | ll n, m; 30 | cin >> n >> m; 31 | ll eu, ev, ew; 32 | 33 | forz(i, m) 34 | { 35 | cin >> eu >> ev >> ew; 36 | edges.pb({eu, ev,ew}); 37 | } 38 | 39 | for (int i = 1; i <= n; i++) 40 | { 41 | dis[i] = INF; 42 | } 43 | dis[1] = 0; 44 | 45 | for (int i = 1; i <= n - 1; i++) 46 | { 47 | for (auto x : edges) 48 | { 49 | ll u = x.u; 50 | ll v = x.v; 51 | ll w = x.w; 52 | if (dis[u] != INF && dis[u] + w < dis[v]) 53 | { 54 | dis[v] = dis[u] + w; 55 | } 56 | } 57 | } 58 | 59 | for (auto x : edges) 60 | { 61 | ll u = x.u; 62 | ll v = x.v; 63 | ll w = x.w; 64 | if (dis[u] != INF && dis[u] + w < dis[v]) 65 | { 66 | cout << -1; 67 | return 0; 68 | } 69 | } 70 | 71 | cout << dis[n]; 72 | run_time(); 73 | return 0; 74 | } 75 | ``` -------------------------------------------------------------------------------- /Graphs/Shortest_paths/bellman.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tejas01101001/Competitive-coding/d0f29301ae5867d6ace451aa58771f3190589711/Graphs/Shortest_paths/bellman.pdf -------------------------------------------------------------------------------- /Graphs/Shortest_paths/dijsktra_dig.cpp: -------------------------------------------------------------------------------- 1 | 1)what is the minimum price of such a route? 2 | 2)how many minimum-price routes are there? (modulo 109+7) 3 | 3)what is the minimum number of flights in a minimum-price route? 4 | 4)what is the maximum number of flights in a minimum-price route? 5 | 6 | const int N = 1e5 + 5; 7 | const ll INF = LLONG_MAX; 8 | bool vis[N]; 9 | vector dis(N, {INF, 0}); 10 | vector mini(N, INF); 11 | vector maxi(N, -INF); 12 | vector adj[N]; 13 | int n, m; 14 | 15 | int main() 16 | { 17 | kira; 18 | cin >> n >> m; 19 | ll eu, ev, ew; 20 | 21 | forz(i, m) 22 | { 23 | cin >> eu >> ev >> ew; 24 | adj[eu].pb({ev, ew}); 25 | } 26 | 27 | priority_queue> pq; 28 | dis[1] = {0, 1}; 29 | pq.push({0, 1}); 30 | mini[1]=0; 31 | maxi[1]=0; 32 | while (!pq.empty()) 33 | { 34 | ll s = pq.top().S; 35 | pq.pop(); 36 | if (vis[s]) 37 | continue; 38 | vis[s] = true; 39 | 40 | for (auto u : adj[s]) 41 | { 42 | ll v = u.F; 43 | ll w = u.S; 44 | if (dis[s].F + w == dis[v].F) 45 | { 46 | dis[v].S = modadd(dis[s].S, dis[v].S); 47 | mini[v] = min(mini[v], mini[s] + 1); 48 | maxi[v] = max(maxi[v], maxi[s] + 1); 49 | } 50 | if (dis[s].F + w < dis[v].F) 51 | { 52 | dis[v]={dis[s].F+w,dis[s].S}; 53 | mini[v] = mini[s] + 1; 54 | maxi[v] = maxi[s] + 1; 55 | pq.push({-dis[v].F,v}); 56 | } 57 | } 58 | } 59 | p4(dis[n].F,dis[n].S,mini[n],maxi[n]); 60 | run_time(); 61 | return 0; 62 | } -------------------------------------------------------------------------------- /Graphs/Shortest_paths/floyd.cpp: -------------------------------------------------------------------------------- 1 | 1)Finds all shortest paths i.e between two nodes in single run. 2 | 3 | 2)The algorithm maintains a two-dimensional array that contains 4 | distances between the nodes. First, distances are calculated only 5 | using direct edges between the nodes, and after this, the 6 | algorithm reduces distances by using intermediate nodes in paths. 7 | 8 | 3)The graph may have negative weight edges, 9 | but no negative weight cycles (then the shortest path is undefined). 10 | 11 | 4)Before k-th phase (k=1…n), 12 | d[i][j] for any vertices i and j stores the length of the 13 | shortest path between the vertex i and vertex j,which contains 14 | only the vertices {1,2,...,k−1} as internal vertices in the path. 15 | 16 | 5)It is easy to make sure that this property holds for the first 17 | phase. For k=0, we can fill matrix with d[i][j]=wij if there 18 | exists an edge between i and j with weight wij and d[i][j]=∞ 19 | if there doesnt exist an edge.In practice ∞ will be some high value. 20 | 21 | for(int i=1;i<=n;i++) 22 | { 23 | for(int j=1;j<=n;j++) 24 | { 25 | if(i==j)dis[i][j]=0; 26 | else if(adj[i][j])dis[i][j]=adj[i][j]; 27 | else dis[i][j]=INF; 28 | } 29 | } 30 | 31 | for(int k=1;k<=n;k++) 32 | { 33 | for(int i=1;i<=n;i++) 34 | { 35 | for(int j=1;j<=n;j++) 36 | { 37 | if(dis[i][k] color(n + 1, -1); 4 | bool isbi = true; 5 | queue q; 6 | q.push(x); 7 | for (int i = 1; i <= n; i++) 8 | { 9 | if (color[i] == -1) 10 | { 11 | q.push(i); 12 | color[i] = 0; 13 | while (!q.empty()) 14 | { 15 | int s = q.front(); 16 | q.pop(); 17 | for (int u : adj[s]) 18 | { 19 | if (color[u] == -1) 20 | { 21 | color[u] = 1 - color[s]; 22 | q.push(u); 23 | } 24 | else 25 | { 26 | isbi &= (color[u] != color[s]); 27 | } 28 | } 29 | } 30 | } 31 | } 32 | return isbi; 33 | } 34 | -------------------------------------------------------------------------------- /Graphs/Traversals/cycle.cpp: -------------------------------------------------------------------------------- 1 | CYCLE DETECTION 2 | 3 | 1)We will run a series of DFS in the graph.Initially all vertices are colored white(0).From each unvisited(white) vertex,start the DFS, mark it gray(1) while entering and mark it black(2) on exit.If DFS moves to a gray vertex, then we have found a cycle.The cycle itself can be reconstructed using parent array. 4 | 5 | NOTE:If the graph is undirected, the edge to parent is not considered 6 | 7 | const int N = 8 | vector color(N, 0),pred(N); 9 | vector adj[N]; 10 | ll cycst, cycen; 11 | ll n, m; 12 | 13 | bool dfs(ll s) 14 | { 15 | color[s] = 1; 16 | for (auto u : adj[s]) 17 | { 18 | if (color[u] == 0) 19 | { 20 | pred[u] = s; 21 | if (dfs(u)) 22 | return true; 23 | } 24 | else if (color[u] == 1&& pred[s]!=u) 25 | { 26 | //FOR DIRECTED GRAPH REMOVE pred[s]!=u 27 | cycen = s; 28 | cycst = u; 29 | return true; 30 | } 31 | } 32 | color[s] = 2; 33 | return false; 34 | } 35 | 36 | void findcyc() 37 | { 38 | color.assign(n+1, 0); 39 | pred.assign(n+1, -1); 40 | cycst = -1; 41 | for(int i=1;i<=n;i++) 42 | { 43 | if (color[i] == 0 && dfs(i)) 44 | break; 45 | } 46 | if (cycst == -1) 47 | { 48 | cout << "IMPOSSIBLE"; 49 | return; 50 | } 51 | vector path; 52 | path.pb(cycst); 53 | for (ll v = cycen; v != cycst; v = pred[v]) 54 | path.pb(v); 55 | path.pb(cycst); 56 | reverse(all(path)); 57 | cout< adj[N]; 3 | int dis[N]; 4 | int pre[N]; 5 | const int INF = 1e9; 6 | int ans = INF; 7 | void bfs(int s) 8 | { 9 | dis[s] = 0; 10 | queue q; 11 | q.push(s); 12 | 13 | while (!q.empty()) 14 | { 15 | int x = q.front(); 16 | q.pop(); 17 | for (auto u : adj[x]) 18 | { 19 | if (dis[u] == INF) 20 | { 21 | dis[u] = dis[x] + 1; 22 | pre[u] = x; 23 | q.push(u); 24 | } 25 | else if (pre[u] != x && pre[x] != u) 26 | { 27 | ans = min(ans, dis[x] + dis[u] + 1); 28 | } 29 | } 30 | } 31 | } 32 | 33 | int main() 34 | { 35 | kira; 36 | int n, a, b, m; 37 | cin >> n >> m; 38 | forz(i, m) 39 | { 40 | cin >> a >> b; 41 | adj[a].pb(b); 42 | adj[b].pb(a); 43 | } 44 | for (int i = 1; i <= n; i++) 45 | { 46 | for (int i = 1; i <= n; i++) 47 | { 48 | dis[i] = INF; 49 | pre[i] = -1; 50 | } 51 | bfs(i); 52 | } 53 | if (ans == INF) 54 | p1(-1); 55 | else 56 | p1(ans); 57 | return 0; 58 | } -------------------------------------------------------------------------------- /Maths/Baby_step_giant_step.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tejas01101001/Competitive-coding/d0f29301ae5867d6ace451aa58771f3190589711/Maths/Baby_step_giant_step.pdf -------------------------------------------------------------------------------- /Maths/Burnside_Lemma.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tejas01101001/Competitive-coding/d0f29301ae5867d6ace451aa58771f3190589711/Maths/Burnside_Lemma.pdf -------------------------------------------------------------------------------- /Maths/Mobius_.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tejas01101001/Competitive-coding/d0f29301ae5867d6ace451aa58771f3190589711/Maths/Mobius_.pdf -------------------------------------------------------------------------------- /Maths/fastexpo.cpp: -------------------------------------------------------------------------------- 1 | 2 | ll power(ll x, ll y, ll p) 3 | { 4 | ll res = 1; 5 | x = x % p; 6 | while (y > 0) 7 | { 8 | if (y & 1) 9 | res = (res * x) % p; 10 | y = y >> 1; 11 | x = (x * x) % p; 12 | } 13 | return res; 14 | } 15 | 16 | ll modi(ll a, ll m) 17 | { 18 | return power(a, m - 2, m); 19 | } -------------------------------------------------------------------------------- /Maths/linear_sieve.md: -------------------------------------------------------------------------------- 1 | # Sieve for Prime Identification 2 | 3 | ## Sieve of Eratosthenes 4 | 5 | - Sieve of Eratosthenes is an algorithm for finding all the prime numbers in a segment [1,n] using O(nloglogn) operations. 6 | - Algorithm visualization 7 | ![Sieve for [1,16]](https://cp-algorithms.web.app/img/sieve_eratosthenes.png) 8 | - Since we iterate over the prime numbers in order, we already marked all numbers, who are divisible by at least one of the prime numbers, as divisible. 9 | - 10 | ```C++ 11 | int n; 12 | vector is_prime(n + 1, true); 13 | is_prime[0] = is_prime[1] = false; 14 | 15 | for (int i = 2; i * i <= n; i++) 16 | { 17 | if (is_prime[i]) 18 | { 19 | for (int j = i * i; j <= n; j += i) 20 | is_prime[j] = false; 21 | } 22 | } 23 | ``` 24 | ## Linear sieve O(n) also stores the smallest prime factor 25 | 26 | - In practice we run the inner loop for a composite multiple times due to the fact that it has multiple factors. 27 | - Thus, if we can establish a unique representation for each composite and pick them out only once, our algorithm will be somewhat better. 28 | - Note that every composite q must have at least one prime factor, so we can pick the smallest prime factor p, and let the rest of the part be i, i.e. q = ip. 29 | - Since p is the smallest prime factor, we have i ≥ p, and no prime less than p can divide i. 30 | - Now let us take a look at the code we have a moment ago. 31 | - When we loop for every i, all primes not exceeding i is already recorded in the container prime. 32 | - Therefore, if we only loop for all elements in prime in the inner loop, breaking out when the element divides i, we can pick out each composite exactly once. 33 | 34 | ```C++ 35 | const int N = 1e7; 36 | int spf[N + 1]; 37 | vector prime; 38 | 39 | void linear_sieve() 40 | { 41 | //spf:Smallest prime factor 42 | for (int i = 2; i <= N; ++i) 43 | { 44 | if (spf[i] == 0) 45 | { 46 | spf[i] = i; 47 | prime.push_back(i); 48 | } 49 | for (int j = 0; j < int(prime.si) && prime[j] <= spf[i] && i * prime[j] <= N; j++) 50 | spf[i * prime[j]] = prime[j]; 51 | } 52 | } 53 | ``` 54 | ## Prime factorization for a given number O(log n) 55 | 56 | - We can get all the prime factors of a given number in O(log n) by using the linear sieve 57 | 58 | ```C++ 59 | vector get_factors(int n) 60 | { 61 | vector ans; 62 | while (n != 1) 63 | { 64 | ans.push_back(spf[n]); 65 | n /= spf[n]; 66 | } 67 | return ans; 68 | } 69 | ``` -------------------------------------------------------------------------------- /Maths/mobius.md: -------------------------------------------------------------------------------- 1 | # Mobius Inversion 2 | 3 | - Refer to the pdf for the theory 4 | - [Counting Co-prime Pairs](https://cses.fi/problemset/task/2417) 5 | 6 | ```C++ 7 | const int N = 1e6 + 5; 8 | int spf[N + 1]; 9 | int mobi[N + 1]; 10 | lli cnt[N + 1]; 11 | vector prime; 12 | 13 | void linear_sieve() 14 | { 15 | //spf:Smallest prime factor 16 | for (int i = 2; i <= N; ++i) 17 | { 18 | if (spf[i] == 0) 19 | { 20 | spf[i] = i; 21 | prime.pb(i); 22 | } 23 | for (int j = 0; j < int(prime.si) && prime[j] <= spf[i] && i * prime[j] <= N; j++) 24 | spf[i * prime[j]] = prime[j]; 25 | } 26 | } 27 | 28 | void mobius() 29 | { 30 | for (int i = 1; i <= N; i++) 31 | { 32 | if (i == 1) 33 | mobi[i] = 1; 34 | else if (spf[i] == spf[i / spf[i]]) 35 | mobi[i] = 0; 36 | else 37 | mobi[i] = -1 * mobi[i / spf[i]]; 38 | } 39 | } 40 | ``` -------------------------------------------------------------------------------- /Maths/ncr.md: -------------------------------------------------------------------------------- 1 | # Factorial and nCr 2 | 3 | ```C++ 4 | const int N = 1e6 + 5; 5 | ll fac[N], invfac[N]; 6 | void fact() 7 | { 8 | invfac[0] = fac[0] = 1; 9 | for (int i = 1; i < N; i++) 10 | { 11 | fac[i] = (fac[i - 1] * i) % mod; 12 | invfac[i] = modi(fac[i]); 13 | } 14 | return; 15 | } 16 | 17 | ll ncr(ll a, ll b) 18 | { 19 | if (a < b || a < 0 || b < 0) 20 | return 0; 21 | return ((fac[a] * invfac[b]) % mod * invfac[a - b]) % mod; 22 | } 23 | 24 | int main() 25 | { 26 | kira; 27 | ll n, a, b; 28 | cin >> n; 29 | fact(); 30 | while (n--) 31 | { 32 | cin >> a >> b; 33 | cout << ncr(a, b) << endl; 34 | } 35 | return 0; 36 | } 37 | ``` -------------------------------------------------------------------------------- /Maths/no of divisors.cpp: -------------------------------------------------------------------------------- 1 | ll tau(ll num) 2 | { 3 | ll count = 0; 4 | ll pp = 1; 5 | while (num % 2 == 0) 6 | { 7 | count++; 8 | num /= 2; 9 | } 10 | pp *= (count + 1); 11 | for (ll i = 3; i <= sqrt(num); i += 2) 12 | { 13 | count = 0; 14 | while (num % i == 0) 15 | { 16 | count++; 17 | num /= i; 18 | } 19 | pp *= (count + 1); 20 | } 21 | if (num > 2) 22 | { 23 | pp *= 2; 24 | } 25 | return pp; 26 | } -------------------------------------------------------------------------------- /Maths/sumofdiv.cpp: -------------------------------------------------------------------------------- 1 | ll sigma(ll num) 2 | { 3 | ll count = 0; 4 | ll pp = 1; 5 | while (num % 2 == 0) 6 | { 7 | count++; 8 | num /= 2; 9 | } 10 | pp *= (pow(2, (count + 1)) - 1); 11 | for (ll i = 3; i <= sqrt(num); i += 2) 12 | { 13 | count = 0; 14 | while (num % i == 0) 15 | { 16 | count++; 17 | num /= i; 18 | } 19 | pp *= (pow(i, (count + 1)) - 1) / (i - 1); 20 | } 21 | if (num > 2) 22 | { 23 | pp *= (num + 1); 24 | } 25 | return pp; 26 | } 27 | -------------------------------------------------------------------------------- /Maths/totient.md: -------------------------------------------------------------------------------- 1 | # Euler-Totient Function 2 | 3 | ```C++ 4 | ll phi(ll n) 5 | { 6 | int res = n; 7 | for (int i = 2; i * i <= n; i++) 8 | { 9 | if (n % i == 0) 10 | { 11 | while (n % i == 0) 12 | n /= i; 13 | res -= res / i; 14 | } 15 | } 16 | if (n > 1) 17 | res -= res / n; 18 | return res; 19 | } 20 | ``` -------------------------------------------------------------------------------- /Polynomials/FFT.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tejas01101001/Competitive-coding/d0f29301ae5867d6ace451aa58771f3190589711/Polynomials/FFT.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Competitive-coding 2 | Some tutorials and templates 3 | -------------------------------------------------------------------------------- /STL/algolib.md: -------------------------------------------------------------------------------- 1 | # STL 2 | 3 | ## 1. sort(startaddress, endaddress) 4 | 5 | - startaddress: the address of the first element of the array 6 | - endaddress: the address of the last element of the array 7 | 8 | ```C++ 9 | int a[10]= {1, 5, 8, 9, 6, 7, 3, 4, 2, 0}; 10 | sort(a, a+10); 11 | ``` 12 | 13 | - So by default, sort() sorts an array in ascending order. 14 | - sort(a, a+n, greater()); 15 | - To sort in descending order 16 | 17 | ```C++ 18 | sort(vec.begin(),vec.end()) 19 | ``` 20 | 21 | ## 2. binary_search(startaddress, endaddress, valuetofind) 22 | 23 | ### NOTE: array must be sorted. 24 | 25 | - startaddress: the address of the first element of the array. 26 | - endaddress: the address of the last element of the array. 27 | - valuetofind: the target value which we have to search for 28 | 29 | ```C++ 30 | if (binary_search(a, a + n, 4)) 31 | cout << "\nElement found in the array"; 32 | ``` 33 | 34 | ## 3. Algorithm lib 35 | - sort(first_iterator, last_iterator) – To sort the given vector 36 | - reverse(first_iterator, last_iterator) – To reverse a vector. 37 | - *max_element (first_iterator, last_iterator) – To find the maximum element of a vector. 38 | - *min_element (first_iterator, last_iterator) – To find the minimum element of a vector. 39 | - accumulate(first_iterator, last_iterator, initial value of sum) – Does the summation of - - - vector elements 40 | 41 | ```C++ 42 | // Initializing vector with array values 43 | int arr[] = {10, 20, 5, 23 ,42 , 15}; 44 | int n = sizeof(arr)/sizeof(arr[0]); 45 | vector vect(arr, arr+n); 46 | 47 | sort(vect.begin(), vect.end());//5 10 15 20 23 42 48 | reverse(vect.begin(), vect.end());//42 23 20 15 10 5 49 | *max_element(vect.begin(), vect.end());// 42 50 | *min_element(vect.begin(), vect.end());//5 51 | accumulate(vect.begin(), vect.end(), 0);//115 52 | ``` 53 | 54 | - count(first_iterator, last_iterator,x) – 55 | To count the occurrences of x in vector. 56 | 57 | - find(first_iterator, last_iterator, x) – 58 | Points to last address of vector ((name_of_vector).end()) if element is not present in vector. 59 | 60 | ```C++ 61 | // Initializing vector with array values 62 | int arr[] = {10, 20, 5, 23 ,42, 20, 15}; 63 | int n = sizeof(arr)/sizeof(arr[0]); 64 | vector vect(arr, arr + n); 65 | 66 | count(vect.begin(), vect.end(), 20);//2 67 | find(vect.begin(), vect.end(),5); 68 | ``` 69 | 70 | - vec.erase(position to be deleted) – 71 | This erases selected element in vector and shifts and resizes the vector elements accordingly. 72 | 73 | - vec.erase(unique(vec.begin(),vec.end()),vec.end()) – 74 | This erases the duplicate occurrences in sorted vector in a single line. 75 | 76 | ```C++ 77 | // Initializing vector with array values 78 | int arr[] = {5, 20, 5, 23, 20, 20}; 79 | int n = sizeof(arr)/sizeof(arr[0]); 80 | vector vect(arr, arr+n); 81 | 82 | vect.erase(vect.begin()+1); 83 | //5 5 23 20 20 84 | //sort enables to use of unique. 85 | sort(vect.begin(), vect.end()); 86 | vect.erase(unique(vect.begin(),vect.end()),vect.end()); 87 | // 5 20 23 88 | ``` 89 | 90 | 91 | - distance(first_iterator,desired_position) – 92 | It returns the distance of desired position from the first iterator.This function is very useful while finding the index. 93 | 94 | `distance(vect.begin(),max_element(vect.begin(), vect.end()));` 95 | 96 | - next_permutation(first_iterator, last_iterator) – 97 | This modified the vector to its next permutation. 98 | 99 | - prev_permutation(first_iterator, last_iterator) – 100 | This modified the vector to its previous permutation. 101 | 102 | ```C++ 103 | next_permutation(vect.begin(), vect.end()); 104 | prev_permutation(vect.begin(), vect.end()); 105 | 106 | Given Vector is: 107 | 5 10 15 20 20 23 42 45 108 | Vector after performing next permutation: 109 | 5 10 15 20 20 23 45 42 110 | Vector after performing prev permutation: 111 | 5 10 15 20 20 23 42 45 112 | ``` 113 | 114 | - lower_bound(first_iterator, last_iterator, x) – 115 | returns an iterator pointing to the **first element** in the range [first,last) which has a value >=x 116 | 117 | - upper_bound(first_iterator, last_iterator, x) – 118 | returns an iterator pointing to the **first element** in the range [first,last) which has a value >x -------------------------------------------------------------------------------- /Search/BinSearch.md: -------------------------------------------------------------------------------- 1 | # Binary search: 2 | 3 | 1. Basic structure 4 | 5 | ```C++ 6 | ll l = 0, r = n - 1; 7 | while (l <= r) 8 | { 9 | ll mid = l + (r - l) / 2; 10 | if (a[mid] == x) 11 | return mid; 12 | if (a[mid] < x) 13 | l = mid + 1; 14 | else 15 | r = mid - 1; 16 | } 17 | return -1; 18 | ``` 19 | 20 | 2. Sometimes there is no array and we can still apply bins: 21 | 22 | - Is x is a square 23 | 24 | ```C++ 25 | l = 0; 26 | r = x; 27 | m = l + (r - l) / 2; 28 | m ^ 2 compared with x; 29 | ``` 30 | 31 | - Find first value >=x 32 | 33 | ```C++ 34 | x = 4 35 | F F T T T T T 36 | 2,3,5,6,8,10,12 37 | ``` 38 | 39 | - We have to keep on updating ans with better values. 40 | - Think of binary search as as series of true and false. 41 | - need to find boundary between the partially false and partially true. 42 | - prefix of true and suffix of false or the other way. 43 | 44 | ```C++ 45 | ll l = 0, r = n - 1; 46 | ll ans = -1; 47 | while (l <= r) 48 | { 49 | mid = l + (r - l) / 2; 50 | if (a[mid] >= x) 51 | { 52 | ans = a[mid]; 53 | r = mid - 1; 54 | } 55 | else 56 | l = mid + 1; 57 | } 58 | return ans; 59 | ``` 60 | 61 | - Rotated array find the smallest element. 62 | 63 | ```C++ 64 | T T T T T F F 65 | 6,7,9,15,19,2,3 66 | 67 | if (mid > a[n-1]) true; 68 | else false; 69 | ``` 70 | 71 | - The array increases and then decreases 72 | Find the maximum. 73 | 74 | ```C++ 75 | ? T T T T T T F F F F F 76 | 2,3,4,5,6,9,12,11,8,6,4,1 77 | 78 | can take first ? as T 79 | if(m == 0|| a[m] > a[m-1])then T 80 | else F 81 | look for last true 82 | ``` 83 | 84 | - Find sqrt with some precision 85 | 86 | ```C++ 87 | long double l = 0, r = x; 88 | while (r - l > epsilon) 89 | { 90 | mid = l + (r - l) / 2; 91 | if (mid * mid < x) 92 | l = mid; 93 | else 94 | r = mid; 95 | } 96 | return l + (r - l) / 2; 97 | ``` 98 | -------------------------------------------------------------------------------- /Search/bfs.md: -------------------------------------------------------------------------------- 1 | # Breadth First Search 2 | 3 | ```C++ 4 | const int N = 2e5 + 5; 5 | vector adj[N]; 6 | bool vis[N]; 7 | int dis[N]; 8 | 9 | void bfs(int x) 10 | { 11 | queue q; 12 | vis[x] = true; 13 | dis[x] = 0; 14 | q.push(x); 15 | while (!q.empty()) 16 | { 17 | int s = q.front(); 18 | q.pop(); 19 | 20 | for (auto u : adj[s]) 21 | { 22 | if (vis[u]) 23 | continue; 24 | vis[u] = true; 25 | dis[u] = dis[s] + 1; 26 | q.push(u); 27 | } 28 | } 29 | } 30 | ``` -------------------------------------------------------------------------------- /Search/dfs.md: -------------------------------------------------------------------------------- 1 | # Depth First Search 2 | 3 | ```C++ 4 | const int N = 2e5 + 5; 5 | vector adj[N]; 6 | vector v; 7 | bool vis[N]; 8 | int c = 0; 9 | int no_of_leaves = 0; 10 | 11 | void dfs(int s) 12 | { 13 | if (vis[s]) 14 | return; 15 | vis[s] = true; 16 | //process 17 | int f = 1; 18 | for (auto u : adj[s]) 19 | { 20 | if (vis[u]) 21 | continue; 22 | //process2 23 | dfs(u); 24 | f = 0; 25 | } 26 | if (f == 1) 27 | no_of_leaves++; 28 | } 29 | ``` -------------------------------------------------------------------------------- /Search/meet_in_the_middle.cpp: -------------------------------------------------------------------------------- 1 | 1)Meet in the middle is a technique where the search space is divided into two parts of about equal size. A separate search is performed for both of the parts,and finally the results of the searches are combined. 2 | The technique can be used if there is an efficient way to combine the results of the searches. In such a situation, the two searches may require less time than 3 | one large search. Typically, we can turn a factor of 2^n into a factor of 2^n/2 using the meet in the middle technique. 4 | 5 | //NO OF SUBSETS WITH SUM >=K 6 | const ll INF = 1e12; 7 | ll k; 8 | vector subset(vector &v) 9 | { 10 | ll n = v.si; 11 | vector sum; 12 | for (int i = 0; i < (1 << n); i++) 13 | { 14 | ll s = 0; 15 | for (int j = 0; j < n; j++) 16 | { 17 | if (i & (1 << j)) 18 | s += v[j]; 19 | } 20 | if (s <= k) 21 | { 22 | sum.pb(s); 23 | } 24 | } 25 | return sum; 26 | } 27 | int main() 28 | { 29 | kira; 30 | ll n, x; 31 | cin >> n >> k; 32 | vector a, b; 33 | forz(i, n) 34 | { 35 | cin >> x; 36 | if (i < n / 2) 37 | b.pb(x); 38 | else 39 | a.pb(x); 40 | } 41 | vector sa = subset(a); 42 | vector sb = subset(b); 43 | ll c = 0; 44 | sort(all(sb)); 45 | for (auto x : sa) 46 | { 47 | auto it=er(sb.be,sb.en,k-x); 48 | c+=it.S-it.F; 49 | } 50 | cout << c; 51 | return 0; 52 | } -------------------------------------------------------------------------------- /Search/subset.cpp: -------------------------------------------------------------------------------- 1 | for (int b = 0; b < (1 << n); b++) 2 | { 3 | vector subset; 4 | //IF THE ith BIT IS SET THEN IT BELONGS TO THE SUBSET 5 | for (int i = 0; i < n; i++) 6 | { 7 | if (b & (1 << i)) 8 | subset.pb(i); 9 | } 10 | } -------------------------------------------------------------------------------- /Search/ternary.md: -------------------------------------------------------------------------------- 1 | # Ternary Search 2 | ```C++ 3 | ll ternary(int lo, int hi) 4 | { 5 | //fucntion f should be unimodal 6 | //i.e convex or concave 7 | while (lo + 3 <= hi) 8 | { 9 | int m1 = lo + (hi - lo) / 3; 10 | int m2 = hi - (hi - lo) / 3; 11 | if (func(m1) <= func(m2)) 12 | hi = m2; 13 | else 14 | lo = m1; 15 | } 16 | ll ans = func(lo); 17 | for (int i = lo + 1; i <= hi; i++) 18 | ans = min(ans, func(i)); 19 | return ans; 20 | } 21 | ``` -------------------------------------------------------------------------------- /Segtree_Fenwick/Fenwick.md: -------------------------------------------------------------------------------- 1 | # Fenwick Tree 2 | 3 | 1. Even if the name of the structure is a binary indexed tree, 4 | it is usually represented as an array. 5 | 6 | 2. We assume that all arrays are (one-indexed), 7 | to make implementation easier. 8 | 9 | 3. Let p(k) denote the largest power of two that divides k . 10 | We store a binary indexed tree as an array tree such that 11 | fentree[k] = sum(k - p(k) + 1, k); 12 | 13 | 4. Using a binary indexed tree, any value of sum(1,k) 14 | can be calculated in O(log n) time, because a range [1,k] 15 | can always be divided into O(log n) ranges whose sums 16 | are stored in the tree. 17 | 18 | 5. sum(1, 7) = sum(1, 4) + sum(5, 6) + sum(7, 7) = fentree[4] + fentree[6] + fentree[7] 19 | 6. sum(a, b) = sum(1, b) - sum(1, a-1); 20 | 7. p(k) = k & -k; 21 | 22 | 8. The query function calculates the sum in (1, k) 23 | 9. The update function **increases** the array value at pos k by x. (x can be any integer) 24 | 25 | ```C++ 26 | const int N = 2e5 + 5; 27 | ll fentree[N]; 28 | 29 | ll query(ll k) 30 | { 31 | ll s = 0; 32 | while (k >= 1) 33 | { 34 | s += fentree[k]; 35 | k -= k & -k; 36 | } 37 | return s; 38 | } 39 | 40 | void update(ll k, ll x) 41 | { 42 | while (k <= n) 43 | { 44 | fentree[k] += x; 45 | k += k & -k; 46 | } 47 | } 48 | ``` 49 | 50 | 10. Time complexity of both the above functions is O(logn). 51 | 52 | ## Counting Inversions: 53 | 54 | 1. Use co-ordinate Compression to make the elements less than n 55 | 56 | ```C++ 57 | for (int i = 0; i < n; i++) 58 | { 59 | //add the no of elements less than i to the ans 60 | ans += query(a[i] - 1); 61 | update(a[i], 1); 62 | } 63 | ``` 64 | 65 | ## Find the kth element in the array: 66 | 67 | 1. Binary search the prefix sum in the BIT 68 | 69 | 2. [Multiset Codeforces](https://codeforces.com/contest/1354/submission/80572075) 70 | 71 | ```C++ 72 | int l = 1, r = n, id = -1; 73 | while (l <= r) 74 | { 75 | int mid = l + (r - l) / 2; 76 | if (query(mid) >= qk) 77 | { 78 | id = mid; 79 | r = mid - 1; 80 | } 81 | else 82 | l = mid + 1; 83 | } 84 | ``` 85 | 86 | ## Range updates and point queries 87 | 88 | 1. Update **adds x** at position k 89 | 2. To set position k as x use update(k, x-a[k]) 90 | 91 | ```C++ 92 | void update(ll k, ll x) 93 | { 94 | while (k <= n) 95 | { 96 | fentree[k] += x; 97 | k += k & -k; 98 | } 99 | } 100 | 101 | void range_upd(ll l, ll r, ll x) 102 | { 103 | update(l, x); 104 | update(r + 1, -x); 105 | } 106 | 107 | ll point_query(ll k) 108 | { 109 | ll s = 0; 110 | while (k >= 1) 111 | { 112 | s += fentree[k]; 113 | k -= k & -k; 114 | } 115 | return s; 116 | } 117 | ``` 118 | 119 | ## Point updates and Range queries 120 | 121 | ### [Kickstart Question](https://codingcompetitions.withgoogle.com/kickstart/round/000000000019ff43/0000000000337b4d) 122 | 123 | 1. Typically two fenwick trees are maintained 124 | 2. Query of type given `[l, r]` find 125 | 3. `a[l] + a[l+1]*2 + a[l+2]*3 + .... + a[r]*(r-l+1)` 126 | 127 | ```C++ 128 | ll query(ll l, ll r) 129 | { 130 | return query(r) - query(l - 1); 131 | } 132 | ``` 133 | 134 | 4. Maintain two trees 135 | ``` 136 | a[0] , a[1] , a[2] , a[3] , a[4] , ......... fentree[0] 137 | a[0]*0, a[1]*1, a[2]*2, a[3]*3, a[4]*4, ......... fentree[1] 138 | ``` 139 | 140 | 5. Suppose we want to query [3,5]: 141 | 6. fentree[1].query(3,5) - (2)*fentree[0].query(3,5) 142 | 143 | ``` 144 | ll qry(ll l, ll r) 145 | { 146 | return fentree[1].query(l, r) - (l - 1) * fentree[0].query(l, r); 147 | } 148 | ``` 149 | 150 | 7. Update i.e set the value at pos k as x 151 | 152 | ``` 153 | ll upd(ll k, ll x) 154 | { 155 | fentree[0].update(k, x - a[k]); 156 | fentree[1].update(k, k * (x - a[k])); 157 | a[k] = x; 158 | } 159 | ``` 160 | 161 | ## Range updates and Range Queries: 162 | 163 | [Refer CP Algorithms](https://cp-algorithms.com/data_structures/fenwick.html) 164 | 165 | ## 2D Fenwick Tree 166 | 167 | ```C++ 168 | const int N = 1e3 + 5; 169 | int fentree[N][N]; 170 | int n, m, q; 171 | 172 | void add(int x, int y, int val) 173 | { 174 | int y1; 175 | while (x <= m) 176 | { 177 | y1 = y; 178 | while (y1 <= n) 179 | { 180 | fentree[x][y1] += val; 181 | y1 += (y1 & -y1); 182 | } 183 | x += (x & -x); 184 | } 185 | } 186 | 187 | int query(int x, int y) 188 | { 189 | if (x == 0 || y == 0) 190 | return 0; 191 | 192 | int s = 0; 193 | int y1; 194 | while (x >= 1) 195 | { 196 | y1 = y; 197 | while (y1 >= 1) 198 | { 199 | s += fentree[x][y1]; 200 | y1 -= (y1 & -y1); 201 | } 202 | x -= (x & -x); 203 | } 204 | return s; 205 | } 206 | ``` -------------------------------------------------------------------------------- /Segtree_Fenwick/segtree.md: -------------------------------------------------------------------------------- 1 | # Non Recursive Segtree 2 | 3 | ## Segment tree with single element modification: 4 | 5 | ### Operation 1: Modify an element 6 | ### Operation 2: Sum over a interval [l,r) 7 | 8 | - Children of node i are 2i (left child) and 2i+1 (right child); 9 | - Array is zero based here 10 | - Actual array stored in t[n] to t[2n-1] 11 | 12 | ``` 13 | const ll N = // limit for array size 14 | ll n; // array size 15 | ll t[2 * N]; 16 | 17 | void build() 18 | { // build the tree 19 | for (int i = n - 1; i > 0; --i) 20 | t[i] = t[i << 1] + t[i << 1 | 1]; 21 | } 22 | 23 | void modify(ll p, ll value) 24 | { // set value at position p 25 | for (t[p += n] = value; p > 1; p >>= 1) 26 | t[p >> 1] = t[p] + t[p ^ 1]; 27 | } 28 | 29 | ll query(ll l, ll r) 30 | { // sum on interval [l, r] 31 | ll res = 0; 32 | r++; 33 | for (l += n, r += n; l < r; l >>= 1, r >>= 1) 34 | { 35 | if (l & 1) 36 | res += t[l++]; 37 | if (r & 1) 38 | res += t[--r]; 39 | } 40 | return res; 41 | } 42 | 43 | ``` 44 | 45 | - Before doing any queries we need to bulid the tree in O(n) 46 | 47 | 48 | ![Segtree View](https://i.imgur.com/GGBmcEP.png) 49 | 50 | - Refer the above image for query [3,11) 51 | 52 | ## General idea is the following: 53 | 54 | - If l the left interval border is odd (which is equivalent to l&1) 55 | then l is the right child of its parent. 56 | - Then our interval includes node l but doesnt include its parent. 57 | 58 | - So we add t[l] and move to the right of l parent by setting l = (l + 1) / 2. 59 | - If l is even, it is the left child, and the interval includes its parent as well 60 | (unless the right border interferes), 61 | 62 | - So we just move to it by setting l = l / 2. 63 | Similar argumentation is applied to the right border. 64 | - We stop once borders meet. 65 | 66 | - If n is not a power of 2 consider a set of balanced binary trees which can be shown to above tree. 67 | 68 | - Hence the above code works 69 | 70 | ## Modification on a interval, single element access 71 | 72 | `WE DONT NEED TO BULID THE TREE IN THIS CASE` 73 | 74 | ### Operation 1: Add a value to a range 75 | ### Operation 2: Compute an element at some pos 76 | 77 | ``` 78 | void modify(ll l,ll r,ll value) 79 | { 80 | for (l += n, r += n; l < r; l >>= 1, r >>= 1) 81 | { 82 | if (l & 1) 83 | t[l++] += value; 84 | if (r & 1) 85 | t[--r] += value; 86 | } 87 | } 88 | 89 | ll query(ll p) 90 | { 91 | ll res = 0; 92 | for (p += n; p > 0; p >>= 1) 93 | res += t[p]; 94 | return res; 95 | } 96 | ``` 97 | 98 | - But at some point we need to inspect all the elements in the array, 99 | we can push all the modications to the leaves. 100 | 101 | - After that we can just traverse elements starting with index n 102 | This way we can reduce the TC from O(nlogn) to O(n) 103 | 104 | `SIMILAR TO BUILD FUNCTION` 105 | ``` 106 | void push() 107 | { 108 | for (int i = 1; i < n; ++i) 109 | { 110 | t[i << 1] += t[i]; 111 | t[i << 1 | 1] += t[i]; 112 | t[i] = 0; 113 | } 114 | } 115 | ``` 116 | 117 | ## NON-commutative combiner functions: 118 | 119 | - We have considered commutative combiner functions like 120 | +, max, min, &, |, ^ 121 | 122 | - Initial query res to apt infinity while using mix,max 123 | 124 | `If combiner function is not commutative:` 125 | 126 | - We define structure S and combine function for it. 127 | In method build we just change + to this function. 128 | In modify we need to ensure the correct ordering of children, 129 | knowing that left child has even index. 130 | 131 | - When answering the query, we note that nodes corresponding 132 | to the left border are processed from left to right, 133 | while the right border moves from right to left. 134 | 135 | ``` 136 | void modify(int p, const S& value) 137 | { 138 | for (t[p += n] = value; p >>= 1;) 139 | t[p] = combine(t[p << 1], t[p << 1 | 1]); 140 | } 141 | 142 | S query(int l, int r) 143 | { 144 | S resl, resr; 145 | for (l += n, r += n; l < r; l >>= 1, r >>= 1) 146 | { 147 | if (l & 1) 148 | resl = combine(resl, t[l++]); 149 | if (r & 1) 150 | resr = combine(t[--r], resr); 151 | } 152 | return combine(resl, resr); 153 | } 154 | ``` 155 | 156 | ## Questions 157 | 158 | [Sereja and Brackets](https://codeforces.com/contest/380/submission/66448115) 159 | [Subarray Sum with queries](https://www.codechef.com/viewsolution/30682984) 160 | 161 | ### Subarray Sum with queries 162 | 163 | ```C++ 164 | struct node 165 | { 166 | ll sum, prefixsum, suffixsum, maxsum; 167 | }; 168 | 169 | const ll N = 1e6 + 5; 170 | node t[2 * N]; 171 | ll n; 172 | 173 | node combine(node a, node b) 174 | { 175 | ll total_sum = a.sum + b.sum; 176 | ll prefix_sum = max(a.prefixsum, a.sum + b.prefixsum); 177 | ll suffix_sum = max(b.suffixsum, b.sum + a.suffixsum); 178 | ll max_sum = max({prefix_sum, suffix_sum, a.maxsum, b.maxsum, a.suffixsum + b.prefixsum}); 179 | return {total_sum, prefix_sum, suffix_sum, max_sum}; 180 | } 181 | 182 | void build() 183 | { 184 | for (int i = n - 1; i > 0; --i) 185 | t[i] = combine(t[i << 1], t[i << 1 | 1]); 186 | } 187 | 188 | void modify(int p, const node &value) 189 | { 190 | for (t[p += n] = value; p >>= 1;) 191 | t[p] = combine(t[p << 1], t[p << 1 | 1]); 192 | } 193 | 194 | node query(int l, int r) 195 | { 196 | node resl = {0, 0, 0, 0}; 197 | node resr = {0, 0, 0, 0}; 198 | for (l += n, r += n; l < r; l >>= 1, r >>= 1) 199 | { 200 | if (l & 1) 201 | resl = combine(resl, t[l++]); 202 | if (r & 1) 203 | resr = combine(t[--r], resr); 204 | } 205 | return combine(resl, resr); 206 | } 207 | 208 | int main() 209 | { 210 | kira; 211 | 212 | ll q, x, l, r; 213 | cin >> n >> q; 214 | 215 | forz(i, n) 216 | { 217 | cin >> x; 218 | t[n + i] = {x, x, x, x}; 219 | } 220 | 221 | build(); 222 | 223 | while (q--) 224 | { 225 | cin >> l >> r; 226 | modify(l - 1, {r, r, r, r}); 227 | cout << query(0, n).maxsum << endl; 228 | } 229 | 230 | return 0; 231 | } 232 | ``` -------------------------------------------------------------------------------- /Sqrt/Mo.cpp: -------------------------------------------------------------------------------- 1 | 1)Lets say the block size is S. 2 | 3 | 2)If we look only look at all queries that with the left index in the same block. The queries are sorted by the right index. Therefore we will call add(cur_r) and remove(cur_r) only O(N) times for all these queries combined. This gives O(N/S*N) calls for all blocks. 4 | 5 | 3)The value of cur_l can change by at most O(S) during between two queries. Therefore we have an additional O(SQ) calls of add(cur_l) and remove(cur_l). 6 | 7 | 4)Block size of precisely N‾‾√ doesnt always offer the best runtime. For example, if N‾‾√=750 then it may happen that block size of 700 or 800 may run better. More importantly, dont compute the block size at runtime - make it const. Division by constants is well optimized by compilers. 8 | 9 | 5)In odd blocks sort the right index in ascending order and in even blocks sort it in descending order. This will minimize the movement of right pointer. 10 | 11 | struct query 12 | { 13 | int l, r, idx; 14 | }; 15 | 16 | const int N = 2e5 + 5; 17 | int a[N], cnt[N], ans[N]; 18 | map m; 19 | int len, res = 0; 20 | int n, q, ql, qr, y; 21 | vector mo; 22 | 23 | bool compare(query a, query b) 24 | { 25 | if (a.l / len != b.l / len) 26 | return a.l / len < b.l / len; 27 | 28 | //sort even blocks sorted by desc in odd by ascending 29 | //purely logical is the above process 30 | return ((a.l / len) & 1) ? (a.r < b.r) : (a.r > b.r); 31 | } 32 | 33 | void add(int idx) 34 | { 35 | if (cnt[a[idx]] == 0) 36 | res++; 37 | cnt[a[idx]]++; 38 | } 39 | void remove(int idx) 40 | { 41 | cnt[a[idx]]--; 42 | if (cnt[a[idx]] == 0) 43 | res--; 44 | } 45 | void compute() 46 | { 47 | //algo for zero based queries 48 | int l = 0, r = -1; 49 | for (query u : mo) 50 | { 51 | while (l > u.l) 52 | { 53 | l--; 54 | add(l); 55 | } 56 | while (r < u.r) 57 | { 58 | r++; 59 | add(r); 60 | } 61 | while (l < u.l) 62 | { 63 | remove(l); 64 | l++; 65 | } 66 | while (r > u.r) 67 | { 68 | remove(r); 69 | r--; 70 | } 71 | ans[u.idx] = res; 72 | } 73 | } 74 | int main() 75 | { 76 | kira; 77 | 78 | cin >> n >> q; 79 | forz(i, n) 80 | { 81 | cin >> y; 82 | if (m.count(y)) 83 | a[i] = m[y]; 84 | else 85 | { 86 | a[i] = int(m.si); 87 | m[y] = a[i]; 88 | } 89 | } 90 | 91 | len = int(sqrt(n + .0)) + 1; 92 | forz(i, q) 93 | { 94 | cin >> ql >> qr; 95 | mo.pb({ql - 1, qr - 1, i}); 96 | } 97 | sort(all(mo), compare); 98 | 99 | compute(); 100 | forz(i, q) p0(ans[i]); 101 | return 0; 102 | } -------------------------------------------------------------------------------- /Sqrt/mo_hilbert.cpp: -------------------------------------------------------------------------------- 1 | inline int64_t gilbertOrder(int x, int y, int pow, int rotate) 2 | { 3 | if (pow == 0) 4 | { 5 | return 0; 6 | } 7 | int hpow = 1 << (pow - 1); 8 | int seg = (x < hpow) ? ( 9 | (y < hpow) ? 0 : 3) 10 | : ( 11 | (y < hpow) ? 1 : 2); 12 | seg = (seg + rotate) & 3; 13 | const int rotateDelta[4] = {3, 0, 0, 1}; 14 | int nx = x & (x ^ hpow), ny = y & (y ^ hpow); 15 | int nrot = (rotate + rotateDelta[seg]) & 3; 16 | int64_t subSquareSize = int64_t(1) << (2 * pow - 2); 17 | int64_t ans = seg * subSquareSize; 18 | int64_t add = gilbertOrder(nx, ny, pow - 1, nrot); 19 | ans += (seg == 1 || seg == 2) ? add : (subSquareSize - add - 1); 20 | return ans; 21 | } 22 | 23 | struct query 24 | { 25 | int l, r, idx; 26 | int64_t ord; 27 | inline void calcOrder() 28 | { 29 | ord = gilbertOrder(l, r, 21, 0); 30 | } 31 | }; 32 | 33 | const int N = 2e5 + 5; 34 | vector adj[N]; 35 | vector v; 36 | int siz[N]; 37 | int pos[N]; 38 | int timer = 0; 39 | int a[N], cnt[N], ans[N], arr[N]; 40 | map m; 41 | int len, res = 0; 42 | int n, q, ql, qr, y; 43 | vector mo; 44 | 45 | void dfs(int s = 0, int e = -1) 46 | { 47 | siz[s] = 1; 48 | v.pb(s); 49 | for (auto u : adj[s]) 50 | { 51 | if (u == e) 52 | continue; 53 | dfs(u, s); 54 | siz[s] += siz[u]; 55 | } 56 | } 57 | 58 | bool compare(query a, query b) 59 | { 60 | return a.ord < b.ord; 61 | } 62 | 63 | void add(int idx) 64 | { 65 | if (cnt[a[idx]] == 0) 66 | res++; 67 | cnt[a[idx]]++; 68 | } 69 | void remove(int idx) 70 | { 71 | cnt[a[idx]]--; 72 | if (cnt[a[idx]] == 0) 73 | res--; 74 | } 75 | void compute() 76 | { 77 | //algo for zero based queries 78 | int l = 0, r = -1; 79 | for (query u : mo) 80 | { 81 | while (l > u.l) 82 | { 83 | l--; 84 | add(l); 85 | } 86 | while (r < u.r) 87 | { 88 | r++; 89 | add(r); 90 | } 91 | while (l < u.l) 92 | { 93 | remove(l); 94 | l++; 95 | } 96 | while (r > u.r) 97 | { 98 | remove(r); 99 | r--; 100 | } 101 | ans[u.idx] = res; 102 | } 103 | } 104 | int main() 105 | { 106 | kira; 107 | cin >> n; 108 | forz(i, n) 109 | { 110 | cin >> y; 111 | if (m.count(y)) 112 | arr[i] = m[y]; 113 | else 114 | { 115 | arr[i] = int(m.si); 116 | m[y] = arr[i]; 117 | } 118 | } 119 | int eu, ev; 120 | forz(i, n - 1) 121 | { 122 | cin >> eu >> ev; 123 | eu--; 124 | ev--; 125 | adj[eu].pb(ev); 126 | adj[ev].pb(eu); 127 | } 128 | 129 | dfs(); 130 | 131 | forz(i, n) 132 | { 133 | pos[v[i]] = i; 134 | a[i] = arr[v[i]]; 135 | } 136 | 137 | len = int(sqrt(n + .0)) + 1; 138 | 139 | forz(i, n) 140 | { 141 | ql = pos[i]; 142 | qr = pos[i] + siz[i] - 1; 143 | query x; 144 | x = {ql, qr, i}; 145 | x.calcOrder(); 146 | mo.pb(x); 147 | } 148 | sort(all(mo), compare); 149 | 150 | compute(); 151 | forz(i, n) p0(ans[i]); 152 | //run_time(); 153 | return 0; 154 | } -------------------------------------------------------------------------------- /Sqrt/sparse_table.cpp: -------------------------------------------------------------------------------- 1 | const int N = 2e5 + 5; 2 | int tlog[N]; 3 | void log_table() 4 | { 5 | for (int i = 2; i < N; i++) 6 | tlog[i] = tlog[i / 2] + 1; 7 | } 8 | 9 | vector> sparse_table(vector &a) 10 | { 11 | int n = int(a.si); 12 | int k = tlog[n] + 1; 13 | vector> sparse(k, vector(n)); 14 | 15 | sparse[0] = a; 16 | for (int row = 1; row < k; row++) 17 | { 18 | for (int i = 0; i + (1 << row) <= n; i++) 19 | { 20 | sparse[row][i] = min(sparse[row - 1][i], sparse[row - 1][i + (1 << (row - 1))]); 21 | } 22 | } 23 | 24 | return sparse; 25 | } 26 | ll query(vector> &v, int l, int r) 27 | { 28 | //minimum of a range [L,R] can be computed with: 29 | //zero based array 30 | int row = tlog[r - l + 1]; 31 | return min(v[row][l], v[row][r - (1 << row) + 1]); 32 | } 33 | 34 | int main() 35 | { 36 | kira; 37 | ll n; 38 | cin >> n; 39 | vector a(n); 40 | forz(i, n) cin >> a[i]; 41 | log_table(); 42 | vector> v = sparse_table(a); 43 | int q, l, r; 44 | cin>>q; 45 | while(q--) 46 | { 47 | cin>>l>>r; 48 | cout< sqrt(n) elements. 3 | 4 | int main() 5 | { 6 | kira; 7 | 8 | int n, q; 9 | cin >> n >> q; 10 | vector a(n); 11 | forz(i, n) cin >> a[i]; 12 | 13 | int len = int(sqrt(n + .0)) + 1; 14 | vector b(len); 15 | 16 | for (int i = 0; i < n; i++) 17 | { 18 | b[i / len] += a[i]; 19 | } 20 | 21 | int l, r; 22 | while (q--) 23 | { 24 | //l,r zero based in our algorithm 25 | cin >> l >> r; 26 | l--,r--; 27 | 28 | ll sum = 0; 29 | int low = l / len, high = r / len; 30 | 31 | if (low == high) 32 | { 33 | for (int i = l; i <= r; i++) 34 | sum += a[i]; 35 | } 36 | else 37 | { 38 | for (int i = l; i <= (low + 1) * len - 1; i++) 39 | sum += a[i]; 40 | for (int i = low + 1; i <= high - 1; i++) 41 | sum += b[i]; 42 | for (int i = high * len; i <= r; i++) 43 | sum += a[i]; 44 | } 45 | cout << sum << endl; 46 | } 47 | return 0; 48 | } -------------------------------------------------------------------------------- /Stack_Queue/max_histogram.cpp: -------------------------------------------------------------------------------- 1 | ll histogram(vector v) 2 | { 3 | int n = int(v.si); 4 | vector a; 5 | a.pb(-1); 6 | for (auto x : v) 7 | a.pb(x); 8 | 9 | stack s; 10 | ll ans = 0; 11 | s.push({-1, 0}); 12 | 13 | for (int i = 1; i <= n; i++) 14 | { 15 | while (a[i] < s.top().F) 16 | { 17 | pll p = s.top(); 18 | s.pop(); 19 | ans = max(ans, (i - s.top().S - 1) * p.F); 20 | } 21 | s.push({a[i], i}); 22 | } 23 | 24 | while (int(s.si) > 1) 25 | { 26 | pll p = s.top(); 27 | s.pop(); 28 | ans = max(ans, p.F * (n - s.top().S)); 29 | } 30 | 31 | return ans; 32 | } 33 | -------------------------------------------------------------------------------- /Stack_Queue/max_one_rectangle.cpp: -------------------------------------------------------------------------------- 1 | ll histogram(vector v) 2 | { 3 | int n = int(v.si); 4 | vector a; 5 | a.pb(-1); 6 | for (auto x : v) 7 | a.pb(x); 8 | 9 | stack s; 10 | ll ans = 0; 11 | s.push({-1, 0}); 12 | 13 | for (int i = 1; i <= n; i++) 14 | { 15 | while (a[i] < s.top().F) 16 | { 17 | pll p = s.top(); 18 | s.pop(); 19 | ans = max(ans, (i - s.top().S - 1) * p.F); 20 | } 21 | s.push({a[i], i}); 22 | } 23 | 24 | while (int(s.si) > 1) 25 | { 26 | pll p = s.top(); 27 | s.pop(); 28 | ans = max(ans, p.F * (n - s.top().S)); 29 | } 30 | 31 | return ans; 32 | } 33 | 34 | ll max_one_matrix(vector> a) 35 | { 36 | int n = int(a.si); 37 | int m = int(a[0].si); 38 | vector v = a[0]; 39 | ll ans = histogram(v); 40 | for (int i = 1; i < n; i++) 41 | { 42 | for (int j = 0; j < m; j++) 43 | { 44 | if (a[i][j] == 0) 45 | v[j] = 0; 46 | else 47 | v[j]++; 48 | } 49 | ans = max(ans, histogram(v)); 50 | } 51 | return ans; 52 | } -------------------------------------------------------------------------------- /Strings/KMP.cpp: -------------------------------------------------------------------------------- 1 | int pi[100]; 2 | 3 | void lps(string s) 4 | { 5 | int n = int(s.si); 6 | for (int q = 1; q < n; q++) 7 | { 8 | int k = pi[q - 1]; 9 | 10 | while (k > 0 && s[q] != s[k]) 11 | k = pi[k - 1]; 12 | 13 | pi[q] = k + (s[k] == s[q] ? 1 : 0); 14 | } 15 | } 16 | 17 | vector kmp_occurances(string t, string p) 18 | { 19 | string s = p + '#' + t; 20 | int n = int(s.si); 21 | int m = int(p.si); 22 | 23 | lps(s); 24 | vector v; 25 | 26 | for (int i = m + 1; i < n; i++) 27 | { 28 | if (pi[i] == m) 29 | { 30 | v.pb(i - 2 * m); 31 | } 32 | } 33 | 34 | return v; 35 | } 36 | -------------------------------------------------------------------------------- /Strings/Reverse_BWT.cpp: -------------------------------------------------------------------------------- 1 | // https://www.geeksforgeeks.org/inverting-burrows-wheeler-transform/ 2 | 3 | string s; 4 | cin >> s; 5 | vector v; 6 | vector a[26]; 7 | int n = s.size(); 8 | for (int i = 0; i < n; i++) 9 | { 10 | if (s[i] == '#') 11 | v.push_back(i); 12 | else 13 | a[s[i] - 'a'].push_back(i); 14 | } 15 | for (int i = 0; i < 26; i++) 16 | { 17 | for (auto j : a[i]) 18 | v.push_back(j); 19 | } 20 | string ans; 21 | int i = v[v[0]]; 22 | while (s[i] != '#') 23 | { 24 | ans += s[i]; 25 | i = v[i]; 26 | } 27 | cout << ans; -------------------------------------------------------------------------------- /Strings/Z_algo.cpp: -------------------------------------------------------------------------------- 1 | Z Algorithm 2 | 3 | 1)Thus, z[k] = p tells us that s[0. . . p−1] equals s[k. . . k+ p−1]. 4 | 2)At each position k, we first check the value of z[k−x]. If k+z[k−x] < y, 5 | we know that z[k] = z[k−x]. However, if k+z[k−x] ≥ y, s[0. . . y−k] equals 6 | s[k. . . y], and to determine the value of z[k] we need to compare the 7 | substrings character by character. 8 | 9 | ll n=s.si; 10 | vectorz(n); 11 | ll x=0,y=0; 12 | for(int i=1;i= 1; i--) 19 | { 20 | if (match(t.substr(0, i), s)) 21 | return i; 22 | } 23 | return 0; 24 | } 25 | 26 | void dfa(string s) 27 | { 28 | int m = int(s.size()); 29 | vector v(m + 1, ""); 30 | for (int i = 1; i <= m; i++) 31 | { 32 | v[i] = v[i - 1]; 33 | v[i] += s[i - 1]; 34 | } 35 | for (int i = 0; i <= m; i++) 36 | { 37 | for (int j = 0; j <= 25; j++) 38 | { 39 | //'A' uppercase chars considered 40 | phi[i][j] = presuf(s, v[i] + char('A' + j)); 41 | if (i == m) 42 | phi[i][j] = m; 43 | } 44 | } 45 | return; 46 | } 47 | -------------------------------------------------------------------------------- /Strings/hashing.cpp: -------------------------------------------------------------------------------- 1 | Hashing 2 | 3 | 1)hash(s)=∑s[i]⋅p^i(mod m) i=[0,n-1] 4 | 2)if the input is composed of only lowercase letters of English alphabet, p=31 is a good choice. If the input may contain both uppercase and lowercase letters, then p=53 is a possible choice. 5 | 3)Resonable to take p as prime even m prime. 6 | 4)m should be large 7 | 5)m=1e9+9; 8 | 6)Converting a→0 is not a good idea, because then the hashes of the strings a, aa, aaa, … all evaluate to 0.Hence convert a to 1. 9 | 10 | vectorpro(n),h(n+1,0); 11 | pro[0]=1; 12 | for(int i=1;i=1;l--) 24 | { 25 | ll pre,cur,suf; 26 | pre=(h[l]*pro[n-1])%m; 27 | suf=(h[n]+m-h[n-l])%m; 28 | suf=(suf*pro[l-1])%m; 29 | for(int i=1;i<=n-l-1;i++) 30 | { 31 | cur=(h[i+l]+m-h[i])%m; 32 | cur=(cur*pro[n-i-1])%m; 33 | } 34 | } 35 | 36 | substrings of length l 37 | for h[i...j]=h[j]-h[i-1]; 38 | multiply it by pro[n-i-2]; 39 | in short : 40 | for h[a]-h[b]; 41 | multiply it by pro[n-1-b]; 42 | 43 | 8)There is a really easy trick to get better probabilities. We can just compute two different hashes for each string (by using two different p, and/or different m, and compare these pairs instead. If m is about 1e9 for each of the two hash functions, than this is more or less equivalent as having one hash function with m≈10e18. When comparing 1e6 strings with each other, the probability that at least one collision happens is now reduced to ≈1e(-6). 44 | 45 | 9)sometimes take p as 13331 and remove the mod p should be ll 46 | a)Strings x and y are compared with each other. The probability of 47 | a collision is 1/m assuming that all hash values are equally probable 48 | m ideal:1e9 49 | b)A string x is compared with strings y1, y2, . . . , yn. 50 | m ideal:1e12 51 | c)All pairs of strings x1, x2, . . . , xn are compared with each other. 52 | m ideal:1e18(remove mod) 53 | -------------------------------------------------------------------------------- /Strings/manacher.cpp: -------------------------------------------------------------------------------- 1 | Manacher Algo 2 | 3 | 1)Finds all sub-palindromes in O(n) 4 | 2)Convert given string s to t where t starts and ends with 5 | deliminaters like ($ and @) and each char of s is seperated 6 | by another deliminater like #. 7 | 8 | string s: abababa 9 | 10 | $ # a # b # a # b # a # b # a # @ string t 11 | 0 0 1 0 3 0 5 0 7 0 5 0 3 0 1 0 0 p array 12 | 13 | 3)Construct the p[] array using the following algo 14 | 15 | string manacher(string s) 16 | { 17 | string t = "$"; 18 | ll n = s.si; 19 | forz(i, n) 20 | { 21 | t += "#"; 22 | t += s[i]; 23 | } 24 | t+="#@"; 25 | ll len = t.si; 26 | ll p[len] = {0}; 27 | ll center = 0, right = 0; 28 | for (int i = 1; i < len-1; i++) 29 | { 30 | ll mirror = 2 * center - i; 31 | if (i < right) 32 | p[i] = min(p[mirror], right - i); 33 | while (t[i + (1 + p[i])] == t[i - (1 + p[i])]) 34 | p[i]++; 35 | if (i + p[i] > right) 36 | { 37 | center = i; 38 | right = i + p[i]; 39 | } 40 | } 41 | ll length=-1,in=-1; 42 | for(int i=1;ilength) 45 | { 46 | length=p[i]; 47 | in=i; 48 | } 49 | } 50 | return s.substr((in-1-length)/2,length); 51 | } 52 | -------------------------------------------------------------------------------- /Strings/suffix_array.cpp: -------------------------------------------------------------------------------- 1 | vector suffix_array(string s) 2 | { 3 | //O(nlog^2(n)) 4 | s += "$"; 5 | int n = int(s.si); 6 | 7 | //pos is the starting pos of suffix 8 | //eqc is the equivalence class for a string 9 | //a is used to store the strings as a form of numbers 10 | 11 | vector pos(n), eqc(n); 12 | vector a(n); 13 | 14 | for (int i = 0; i < n; i++) 15 | a[i] = {s[i], i}; 16 | sort(all(a)); 17 | 18 | for (int i = 0; i < n; i++) 19 | pos[i] = a[i].S; 20 | eqc[pos[0]] = 0; 21 | 22 | for (int i = 1; i < n; i++) 23 | { 24 | eqc[pos[i]] = eqc[pos[i - 1]]; 25 | if (a[i].F != a[i - 1].F) 26 | eqc[pos[i]]++; 27 | } 28 | 29 | int k = 0; 30 | while ((1 << k) < n) 31 | { 32 | //Stop the loop when we have n distinct eqc 33 | vector> a(n); 34 | for (int i = 0; i < n; i++) 35 | { 36 | a[i] = {{eqc[i], eqc[(i + (1 << k)) % n]}, i}; 37 | } 38 | sort(all(a)); 39 | 40 | for (int i = 0; i < n; i++) 41 | pos[i] = a[i].S; 42 | eqc[pos[0]] = 0; 43 | 44 | for (int i = 1; i < n; i++) 45 | { 46 | eqc[pos[i]] = eqc[pos[i - 1]]; 47 | if (a[i].F != a[i - 1].F) 48 | eqc[pos[i]]++; 49 | } 50 | k++; 51 | } 52 | return pos; 53 | } -------------------------------------------------------------------------------- /Strings/suffix_array_fast.cpp: -------------------------------------------------------------------------------- 1 | void count_sort(vector &pos, vector &eqc) 2 | { 3 | int n = int(pos.size()); 4 | vector cnt(n, 0); 5 | 6 | for (auto x : eqc) 7 | cnt[x]++; 8 | 9 | vector pos_new(n), start_id(n); 10 | start_id[0] = 0; 11 | 12 | for (int i = 1; i < n; i++) 13 | { 14 | start_id[i] = start_id[i - 1] + cnt[i - 1]; 15 | } 16 | 17 | for (auto x : pos) 18 | { 19 | int i = eqc[x]; 20 | pos_new[start_id[i]] = x; 21 | start_id[i]++; 22 | } 23 | 24 | pos = pos_new; 25 | return; 26 | } 27 | 28 | vector suffix_array(string s) 29 | { 30 | //O(nlog(n)) 31 | s += "$"; 32 | int n = int(s.si); 33 | 34 | //pos is the starting pos of suffix 35 | //eqc is the equivalence class for a string 36 | 37 | vector pos(n), eqc(n); 38 | vector a(n); 39 | 40 | for (int i = 0; i < n; i++) 41 | a[i] = {s[i], i}; 42 | sort(all(a)); 43 | 44 | for (int i = 0; i < n; i++) 45 | pos[i] = a[i].S; 46 | eqc[pos[0]] = 0; 47 | 48 | for (int i = 1; i < n; i++) 49 | { 50 | eqc[pos[i]] = eqc[pos[i - 1]]; 51 | if (a[i].F != a[i - 1].F) 52 | eqc[pos[i]]++; 53 | } 54 | 55 | int k = 0; 56 | while ((1 << k) < n) 57 | { 58 | //Position shifted to preserve order of right halfs. 59 | //When transition form k-->k+1 is done 60 | 61 | for (int i = 0; i < n; i++) 62 | { 63 | pos[i] = (pos[i] - (1 << k) + n) % n; 64 | } 65 | 66 | //Sort the left halfs using counting sort 67 | count_sort(pos, eqc); 68 | 69 | vector eqc_new(n); 70 | eqc_new[pos[0]] = 0; 71 | 72 | for (int i = 1; i < n; i++) 73 | { 74 | pii prev = {eqc[pos[i - 1]], eqc[(pos[i - 1] + (1 << k)) % n]}; 75 | pii now = {eqc[pos[i]], eqc[(pos[i] + (1 << k)) % n]}; 76 | eqc_new[pos[i]] = eqc_new[pos[i - 1]]; 77 | if (prev != now) 78 | eqc_new[pos[i]]++; 79 | } 80 | eqc = eqc_new; 81 | k++; 82 | } 83 | return pos; 84 | } -------------------------------------------------------------------------------- /Strings/suffix_lcp.cpp: -------------------------------------------------------------------------------- 1 | void count_sort(vector &pos, vector &eqc) 2 | { 3 | int n = int(pos.size()); 4 | vector cnt(n, 0); 5 | 6 | for (auto x : eqc) 7 | cnt[x]++; 8 | 9 | vector pos_new(n), start_id(n); 10 | start_id[0] = 0; 11 | 12 | for (int i = 1; i < n; i++) 13 | { 14 | start_id[i] = start_id[i - 1] + cnt[i - 1]; 15 | } 16 | 17 | for (auto x : pos) 18 | { 19 | int i = eqc[x]; 20 | pos_new[start_id[i]] = x; 21 | start_id[i]++; 22 | } 23 | 24 | pos = pos_new; 25 | return; 26 | } 27 | 28 | vector> suffix_lcp(string s) 29 | { 30 | //First vector returned is suffix_array 31 | //Second vector returned is lcp_array 32 | //O(nlog(n)) 33 | s += "$"; 34 | int n = int(s.si); 35 | 36 | //pos is the starting pos of suffix 37 | //eqc is the equivalence class for a string 38 | 39 | vector pos(n), eqc(n); 40 | vector a(n); 41 | 42 | for (int i = 0; i < n; i++) 43 | a[i] = {s[i], i}; 44 | sort(all(a)); 45 | 46 | for (int i = 0; i < n; i++) 47 | pos[i] = a[i].S; 48 | eqc[pos[0]] = 0; 49 | 50 | for (int i = 1; i < n; i++) 51 | { 52 | eqc[pos[i]] = eqc[pos[i - 1]]; 53 | if (a[i].F != a[i - 1].F) 54 | eqc[pos[i]]++; 55 | } 56 | 57 | int k = 0; 58 | while ((1 << k) < n) 59 | { 60 | //Position shifted to preserve order of right halfs. 61 | //When transition form k-->k+1 is done 62 | 63 | for (int i = 0; i < n; i++) 64 | { 65 | pos[i] = (pos[i] - (1 << k) + n) % n; 66 | } 67 | 68 | //Sort the left halfs using counting sort 69 | count_sort(pos, eqc); 70 | 71 | vector eqc_new(n); 72 | eqc_new[pos[0]] = 0; 73 | 74 | for (int i = 1; i < n; i++) 75 | { 76 | pii prev = {eqc[pos[i - 1]], eqc[(pos[i - 1] + (1 << k)) % n]}; 77 | pii now = {eqc[pos[i]], eqc[(pos[i] + (1 << k)) % n]}; 78 | eqc_new[pos[i]] = eqc_new[pos[i - 1]]; 79 | if (prev != now) 80 | eqc_new[pos[i]]++; 81 | } 82 | eqc = eqc_new; 83 | k++; 84 | } 85 | 86 | vector lcp(n); 87 | k = 0; 88 | for (int i = 0; i < n - 1; i++) 89 | { 90 | int pos_i = eqc[i]; 91 | int j = pos[pos_i - 1]; 92 | while (s[i + k] == s[j + k]) 93 | k++; 94 | lcp[pos_i] = k; 95 | k = max(k - 1, 0); 96 | } 97 | //lcp[i]=lcp(s[i..],s[j...]) 98 | //lcp indexed form 1...n-1 99 | 100 | return {pos, lcp}; 101 | } -------------------------------------------------------------------------------- /Strings/trie.cpp: -------------------------------------------------------------------------------- 1 | struct trie 2 | { 3 | int cnt; 4 | trie *link[26]; 5 | trie() 6 | { 7 | for (int i = 0; i < 26; i++) 8 | link[i] = NULL; 9 | cnt = 0; 10 | } 11 | }; 12 | 13 | trie *root; 14 | 15 | void insert(string s) 16 | { 17 | trie *curr = root; 18 | for (auto c : s) 19 | { 20 | if (!curr->link[c - 'a']) 21 | curr->link[c - 'a'] = new trie(); 22 | curr = curr->link[c - 'a']; 23 | } 24 | curr->cnt++; 25 | } -------------------------------------------------------------------------------- /Strings/trie.md: -------------------------------------------------------------------------------- 1 | # Trie 2 | 3 | ```C++ 4 | struct trie 5 | { 6 | int cnt; 7 | trie *link[26]; 8 | trie() 9 | { 10 | for (int i = 0; i < 26; i++) 11 | link[i] = NULL; 12 | cnt = 0; 13 | } 14 | }; 15 | 16 | trie *root; 17 | 18 | void insert(string s) 19 | { 20 | trie *curr = root; 21 | for (auto c : s) 22 | { 23 | if (!curr->link[c - 'a']) 24 | curr->link[c - 'a'] = new trie(); 25 | curr = curr->link[c - 'a']; 26 | } 27 | curr->cnt++; 28 | } 29 | ``` -------------------------------------------------------------------------------- /Techs/compress.cpp: -------------------------------------------------------------------------------- 1 | //Co ordinate compression method: 2 | //n Segments: 3 | //l,r; 4 | 5 | vector>v; 6 | v.pb({l,+1}); 7 | v.pb({r+1,-1}); 8 | sort(all(v)); 9 | ll k=2*n-1; 10 | ll c=0; 11 | forz(i,k) 12 | { 13 | c+=v[i].S; 14 | if(v[i].F!=v[i+1].F) 15 | { 16 | then c no of seg covers pts (v[i+1].F-v[i].F) in number 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Template.cpp: -------------------------------------------------------------------------------- 1 | //https://codeforces.com/contest/1359/problem/A 2 | //Author: BrownieTK 3 | 4 | //#pragma GCC optimize("O3") 5 | 6 | #include 7 | using namespace std; 8 | 9 | #include 10 | #include 11 | using namespace __gnu_pbds; 12 | 13 | //========================Debug====================================== 14 | 15 | void __print(int x) { cerr << x; } 16 | void __print(long x) { cerr << x; } 17 | void __print(long long x) { cerr << x; } 18 | void __print(unsigned x) { cerr << x; } 19 | void __print(unsigned long x) { cerr << x; } 20 | void __print(unsigned long long x) { cerr << x; } 21 | void __print(float x) { cerr << x; } 22 | void __print(double x) { cerr << x; } 23 | void __print(long double x) { cerr << x; } 24 | void __print(char x) { cerr << '\'' << x << '\''; } 25 | void __print(const char *x) { cerr << '\"' << x << '\"'; } 26 | void __print(const string &x) { cerr << '\"' << x << '\"'; } 27 | void __print(bool x) { cerr << (x ? "true" : "false"); } 28 | 29 | template 30 | void __print(const pair &x) 31 | { 32 | cerr << '{'; 33 | __print(x.first); 34 | cerr << ','; 35 | __print(x.second); 36 | cerr << '}'; 37 | } 38 | template 39 | void __print(const T &x) 40 | { 41 | int f = 0; 42 | cerr << '{'; 43 | for (auto &i : x) 44 | cerr << (f++ ? "," : ""), __print(i); 45 | cerr << "}"; 46 | } 47 | void _print() { cerr << "]\n"; } 48 | template 49 | void _print(T t, V... v) 50 | { 51 | __print(t); 52 | if (sizeof...(v)) 53 | cerr << ", "; 54 | _print(v...); 55 | } 56 | #ifdef local 57 | #define debug(x...) \ 58 | cerr << "[" << #x << "] = ["; \ 59 | _print(x) 60 | #else 61 | #define debug(x...) 62 | #endif 63 | 64 | //========================TypeDefs=================================== 65 | 66 | typedef long long int ll; 67 | typedef unsigned long long int ull; 68 | typedef long double ldb; 69 | 70 | typedef pair pll; 71 | typedef pair pii; 72 | typedef pair pil; 73 | 74 | //=========================MACROS==================================== 75 | 76 | #define pb push_back 77 | #define popb pop_back() 78 | #define pf push_front 79 | #define popf pop_front() 80 | #define si size() 81 | #define be begin() 82 | #define en end() 83 | #define all(v) v.be, v.en 84 | #define mp make_pair 85 | #define mt make_tuple 86 | #define acc(v) accumulate(all(v), 0) 87 | #define F first 88 | #define S second 89 | 90 | #define forz(i, n) for (int i = 0; i < n; i++) 91 | #define fore(i, m, n) for (int i = m; i <= n; i++) 92 | #define rforz(i, n) for (int i = n - 1; i >= 0; i--) 93 | #define rfore(i, m, n) for (int i = n; i >= m; i--) 94 | 95 | #define deci(n) fixed << setprecision(n) 96 | #define high(n) __builtin_popcount(n) 97 | #define highll(n) __builtin_popcountll(n) 98 | #define parity(n) __builtin_parity(n) 99 | #define clz(n) __builtin_clz(n) 100 | #define clzll(n) __builtin_clzll(n) 101 | #define ctz(n) __builtin_ctz(n) 102 | 103 | #define bset(a, p) ((a) | (1ll << (p))) 104 | #define bchk(a, p) ((a) & (1ll << (p))) 105 | #define bxor(a, p) ((a) ^ (1ll << (p))); 106 | #define brem(a, p) (bchk(a, p) ? (bxor(a, p)) : (a)) 107 | 108 | #define lb lower_bound 109 | #define ub upper_bound 110 | #define er equal_range 111 | 112 | #define findnot find_first_not_of 113 | 114 | #define maxe *max_element 115 | #define mine *min_element 116 | 117 | #define mod 1000000007 118 | #define mod2 998244353 119 | #define PI 3.1415926535897932384 120 | #define INF LLONG_MAX 121 | 122 | #define gcd __gcd 123 | #define kira ios::sync_with_stdio(0), cin.tie(0), cout.tie(0) 124 | 125 | #define endl "\n" 126 | #define p0(a) cout << a << " " 127 | #define p1(a) cout << a << endl 128 | #define p2(a, b) cout << a << " " << b << endl 129 | #define p3(a, b, c) cout << a << " " << b << " " << c << endl 130 | #define p4(a, b, c, d) cout << a << " " << b << " " << c << " " << d << endl 131 | 132 | #define oset tree, rb_tree_tag, tree_order_statistics_node_update> 133 | #define osetlli tree, rb_tree_tag, tree_order_statistics_node_update> 134 | 135 | #define ofk order_of_key 136 | #define fbo find_by_order 137 | //member functions : 138 | //1. order_of_key(k) : number of elements sbtriectly lesser than k 139 | //2. find_by_order(k) : k-th element in the set 140 | 141 | //==============================FUNCTIONS=========================================== 142 | 143 | auto clk = clock(); 144 | mt19937_64 rang(chrono::high_resolution_clock::now().time_since_epoch().count()); 145 | void run_time() 146 | { 147 | #ifdef local 148 | cout << endl; 149 | cout << "Time elapsed: " << (double)(clock() - clk) / CLOCKS_PER_SEC << endl; 150 | #endif 151 | return; 152 | } 153 | 154 | inline ll power(ll x, ll y, ll p = mod) 155 | { 156 | ll res = 1; 157 | x = x % p; 158 | while (y > 0) 159 | { 160 | if (y & 1) 161 | res = (res * x) % p; 162 | y = y >> 1; 163 | x = (x * x) % p; 164 | } 165 | return res; 166 | } 167 | 168 | inline ll modadd(ll a, ll b, ll m = mod) 169 | { 170 | a += b; 171 | if (a >= m) 172 | a -= m; 173 | return a; 174 | } 175 | 176 | inline ll modmul(ll a, ll b, ll m = mod) 177 | { 178 | return ((a % m) * (b % m)) % m; 179 | } 180 | 181 | inline ll modi(ll a, ll m = mod) { return power(a, m - 2, m); } 182 | 183 | //================================CODE============================================= 184 | 185 | int main() 186 | { 187 | kira; 188 | 189 | run_time(); 190 | return 0; 191 | } -------------------------------------------------------------------------------- /Trees/Centroid.cpp: -------------------------------------------------------------------------------- 1 | const int N = 2e5 + 5; 2 | int n, nodes, eu, ev; 3 | int siz[N], par_centroid[N]; 4 | set adj[N]; 5 | 6 | void dfs(int s, int e) 7 | { 8 | nodes++; 9 | siz[s] = 1; 10 | for (auto u : adj[s]) 11 | { 12 | if (u == e) 13 | continue; 14 | dfs(u, s); 15 | siz[s] += siz[u]; 16 | } 17 | } 18 | 19 | int centroid(int s, int e) 20 | { 21 | for (auto u : adj[s]) 22 | { 23 | if (u == e) 24 | continue; 25 | if (siz[u] > nodes / 2) 26 | return centroid(u, s); 27 | } 28 | return s; 29 | } 30 | 31 | void decompose(int s, int e) 32 | { 33 | nodes = 0; 34 | dfs(s, s); 35 | int node = centroid(s, s); 36 | par_centroid[node] = e; 37 | for (auto u : adj[node]) 38 | { 39 | adj[u].erase(node); 40 | decompose(u,node); 41 | } 42 | } 43 | 44 | int main() 45 | { 46 | kira; 47 | cin >> n; 48 | forz(i, n - 1) 49 | { 50 | cin >> eu >> ev; 51 | adj[eu].insert(ev); 52 | adj[ev].insert(eu); 53 | } 54 | decompose(1, 0); 55 | run_time(); 56 | return 0; 57 | } -------------------------------------------------------------------------------- /Trees/LCA _O(1).pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tejas01101001/Competitive-coding/d0f29301ae5867d6ace451aa58771f3190589711/Trees/LCA _O(1).pdf -------------------------------------------------------------------------------- /Trees/LCA.cpp: -------------------------------------------------------------------------------- 1 | 2 | const int N = 4e5 + 5; 3 | int tlog[N], dis[N], early[N]; 4 | vector> v; 5 | int n, q; 6 | vector adj[N]; 7 | vector euler, new_old; 8 | 9 | void log_table() 10 | { 11 | for (int i = 2; i < N; i++) 12 | tlog[i] = tlog[i / 2] + 1; 13 | } 14 | 15 | void sparse_table(vector &a) 16 | { 17 | int n = int(a.si); 18 | int k = tlog[n] + 1; 19 | vector> sparse(k, vector(n)); 20 | 21 | sparse[0] = a; 22 | for (int row = 1; row < k; row++) 23 | { 24 | for (int i = 0; i + (1 << row) <= n; i++) 25 | { 26 | sparse[row][i] = min(sparse[row - 1][i], sparse[row - 1][i + (1 << (row - 1))]); 27 | } 28 | } 29 | 30 | v = sparse; 31 | return; 32 | } 33 | 34 | int lca(int x, int y) 35 | { 36 | //minimum of a range [L,R] can be computed with: 37 | //zero based array 38 | int l = early[x]; 39 | int r = early[y]; 40 | if (l > r) 41 | swap(l, r); 42 | 43 | int row = tlog[r - l + 1]; 44 | return new_old[min(v[row][l], v[row][r - (1 << row) + 1])]; 45 | } 46 | 47 | int dist(int x, int y) 48 | { 49 | int temp = lca(x, y); 50 | return (dis[x] + dis[y] - 2 * dis[temp]); 51 | } 52 | //EULER TOUR OF A TREE TAKES 2*N-1 space; 53 | 54 | void dfs(int s = 1, int e = 0, int h = 0) 55 | { 56 | int new_index = int(new_old.si); 57 | new_old.pb(s); 58 | early[s] = int(euler.si); 59 | euler.pb(new_index); 60 | dis[s] = h; 61 | 62 | for (auto u : adj[s]) 63 | { 64 | if (u == e) 65 | continue; 66 | dfs(u, s, h + 1); 67 | euler.pb(new_index); 68 | } 69 | } 70 | 71 | void precompute() 72 | { 73 | dfs(); 74 | log_table(); 75 | sparse_table(euler); 76 | } 77 | 78 | int main() 79 | { 80 | kira; 81 | int x, y; 82 | cin >> n >> q; 83 | 84 | forz(i, n - 1) 85 | { 86 | cin >> x >> y; 87 | adj[x].pb(y); 88 | adj[y].pb(x); 89 | } 90 | 91 | precompute(); 92 | while (q--) 93 | { 94 | cin >> x >> y; 95 | cout << dist(x, y) << endl; 96 | } 97 | return 0; 98 | } 99 | -------------------------------------------------------------------------------- /Trees/TreeDSU.cpp: -------------------------------------------------------------------------------- 1 | // With DSU on tree, we can answer queries of this type: 2 | // How many vertices in the subtree of vertex v have some property in O(nlog n) time (for all queries)? 3 | 4 | 5 | const int N = 2e5 + 5; 6 | int sz[N]; 7 | bool big[N]; 8 | int cnt[N]; 9 | int col[N]; 10 | vector adj[N]; 11 | int sz[maxn]; 12 | void getsz(int v, int p){ 13 | sz[v] = 1; // every vertex has itself in its subtree 14 | for(auto u : g[v]) 15 | if(u != p){ 16 | getsz(u, v); 17 | sz[v] += sz[u]; // add size of child u to its parent(v) 18 | } 19 | } 20 | 21 | // Function to be changed according to question 22 | void add(int curr, int prev, int val) 23 | { 24 | // Contribution of the curr node 25 | cnt[col[curr]] += val; 26 | 27 | // Contribution of all the children (bigchild may or maynot be included) 28 | for (auto child : adj[curr]) 29 | { 30 | if (child != prev && !big[child]) 31 | add(child, curr, val); 32 | } 33 | } 34 | 35 | ll getans(int curr) 36 | { 37 | ll ans = 38 | return ans; 39 | } 40 | 41 | // Get the size of each subtree 42 | void getsz(int curr, int prev) 43 | { 44 | sz[curr] = 1; 45 | for (auto child : adj[curr]) 46 | { 47 | if (child == prev) 48 | continue; 49 | 50 | getsz(child, curr); 51 | sz[curr] += sz[child]; 52 | } 53 | } 54 | 55 | void dfs(int curr, int prev, int keep) 56 | { 57 | // Find the biggest child in terms of size of subtree rooted at child 58 | int mx = -1, bigchild = -1; 59 | for (auto child : adj[curr]) 60 | { 61 | if (child != prev && sz[child] > mx) 62 | { 63 | mx = sz[child]; 64 | bigchild = child; 65 | } 66 | } 67 | 68 | // Run the dfs on smaller children first 69 | // We are going to delete their contribution them after their use. 70 | for (auto child : adj[curr]) 71 | { 72 | if (child != prev && child != bigchild) 73 | dfs(child, curr, 0); 74 | } 75 | 76 | // Run the DFS on the bigger child 77 | if (bigchild != -1) 78 | { 79 | dfs(bigchild, curr, 1); 80 | big[bigchild] = 1; 81 | } 82 | 83 | // All the contribution of bigchild subtree is stored here 84 | 85 | add(curr, prev, 1); // Contribution of node curr and the smaller subtrees is due to add function 86 | 87 | // Now we have the required info for subtree rooted at curr 88 | getans(curr); 89 | 90 | // Reset the big bool value 91 | if (bigchild != -1) 92 | big[bigchild] = 0; 93 | 94 | // Clear the contribution of subtree rooted at curr if it is smaller child of some node 95 | if (keep == 0) 96 | add(curr, prev, -1); 97 | } -------------------------------------------------------------------------------- /Trees/center_tree.cpp: -------------------------------------------------------------------------------- 1 | const int N = 2e5 + 5; 2 | vector adj[N], path; 3 | int dis[N]; 4 | int pre[N]; 5 | int n; 6 | 7 | void dfs(int s, int e) 8 | { 9 | for (auto u : adj[s]) 10 | { 11 | if (u == e) 12 | continue; 13 | pre[u] = s; 14 | dis[u] = dis[s] + 1; 15 | dfs(u, s); 16 | } 17 | } 18 | 19 | pii far() 20 | { 21 | pii p = {-1, -1}; 22 | for (int i = 1; i <= n; i++) 23 | { 24 | if (p.F < dis[i]) 25 | { 26 | p.F = dis[i]; 27 | p.S = i; 28 | } 29 | } 30 | return p; 31 | } 32 | 33 | vector center() 34 | { 35 | memset(dis, 0, sizeof(dis)); 36 | dfs(1, -1); 37 | pii next = far(); 38 | memset(dis, 0, sizeof(dis)); 39 | for(int i=1;i<=n;i++)pre[i]=-1; 40 | int far_node = next.S; 41 | dfs(far_node, -1); 42 | next = far(); 43 | for (int j = next.S; pre[j] != -1; j = pre[j]) 44 | { 45 | path.pb(j); 46 | } 47 | path.pb(far_node); 48 | int dia = next.F; 49 | dia++; 50 | if (dia % 2) 51 | return {path[dia / 2]}; 52 | return {path[dia / 2], path[dia / 2 - 1]}; 53 | } -------------------------------------------------------------------------------- /Trees/diameter.cpp: -------------------------------------------------------------------------------- 1 | 1)To find a diameter of a tree we run dfs/bfs twice to find the node which is farthest form a given arbitary node when we run dfs/bfs from that node to find the farthest node from that node. 2 | 3 | 2)This distance is the diameter of tree. 4 | 5 | const int N = 2e5 + 5; 6 | vector adj[N]; 7 | ll dis[N]; 8 | void dfs(int s, int e) 9 | { 10 | for (auto u : adj[s]) 11 | { 12 | if (u == e) 13 | continue; 14 | dis[u] = dis[s] + 1; 15 | dfs(u, s); 16 | } 17 | } 18 | pair far(ll n) 19 | { 20 | pair p = {-1, -1}; 21 | for (int i = 1; i <= n; i++) 22 | { 23 | if (p.F < dis[i]) 24 | { 25 | p.F = dis[i]; 26 | p.S = i; 27 | } 28 | } 29 | return p; 30 | } 31 | int main() 32 | { 33 | kira; 34 | ll n, u, v; 35 | cin >> n; 36 | forz(i, n - 1) 37 | { 38 | cin >> u >> v; 39 | adj[u].pb(v); 40 | adj[v].pb(u); 41 | } 42 | dfs(1, -1); 43 | pair next = far(n); 44 | memset(dis, 0, sizeof(dis)); 45 | dfs(next.S, -1); 46 | next = far(n); 47 | cout << next.F; 48 | return 0; 49 | } -------------------------------------------------------------------------------- /Trees/lca_bin.cpp: -------------------------------------------------------------------------------- 1 | const int N = 2e5 + 5; 2 | const int l = ceil(log2(N)); 3 | vector adj[N]; 4 | int tin[N], tout[N], n; 5 | int up[N][l + 1]; 6 | int timer; 7 | 8 | void dfs(int s, int e) 9 | { 10 | tin[s] = timer++; 11 | up[s][0] = e; 12 | for (int i = 1; i <= l; i++) 13 | { 14 | up[s][i] = up[up[s][i - 1]][i - 1]; 15 | } 16 | 17 | for (auto u : adj[s]) 18 | { 19 | if (u == e) 20 | continue; 21 | dfs(u, s); 22 | } 23 | 24 | tout[s] = timer++; 25 | } 26 | 27 | bool isancestor(int u, int v) 28 | { 29 | return (tin[u] <= tin[v] && tout[u] >= tout[v]); 30 | } 31 | 32 | int lca(int u, int v) 33 | { 34 | if (isancestor(u, v)) 35 | return u; 36 | if (isancestor(v, u)) 37 | return v; 38 | 39 | for (int i = l; i >= 0; i--) 40 | { 41 | if (!isancestor(up[u][i], v)) 42 | u = up[u][i]; 43 | } 44 | return up[u][0]; 45 | } 46 | 47 | int query(int s, int k) 48 | { 49 | for (int i = l; i >= 0; i--) 50 | { 51 | if (k & (1 << i)) 52 | s = up[s][i]; 53 | } 54 | if (s == 0) 55 | s = -1; 56 | return s; 57 | } 58 | 59 | int main() 60 | { 61 | kira; 62 | int x, q; 63 | cin >> n >> q; 64 | forz(i, n - 1) 65 | { 66 | cin >> x; 67 | adj[i + 2].pb(x); 68 | adj[x].pb(i + 2); 69 | } 70 | 71 | dfs(1, 1); 72 | 73 | int u, v; 74 | forz(i, q) 75 | { 76 | cin >> u >> v; 77 | cout << lca(u, v) << endl; 78 | } 79 | run_time(); 80 | return 0; 81 | } -------------------------------------------------------------------------------- /Trees/mo_tree_hilbert.cpp: -------------------------------------------------------------------------------- 1 | inline int64_t gilbertOrder(int x, int y, int pow, int rotate) 2 | { 3 | if (pow == 0) 4 | { 5 | return 0; 6 | } 7 | int hpow = 1 << (pow - 1); 8 | int seg = (x < hpow) ? ( 9 | (y < hpow) ? 0 : 3) 10 | : ( 11 | (y < hpow) ? 1 : 2); 12 | seg = (seg + rotate) & 3; 13 | const int rotateDelta[4] = {3, 0, 0, 1}; 14 | int nx = x & (x ^ hpow), ny = y & (y ^ hpow); 15 | int nrot = (rotate + rotateDelta[seg]) & 3; 16 | int64_t subSquareSize = int64_t(1) << (2 * pow - 2); 17 | int64_t ans = seg * subSquareSize; 18 | int64_t add = gilbertOrder(nx, ny, pow - 1, nrot); 19 | ans += (seg == 1 || seg == 2) ? add : (subSquareSize - add - 1); 20 | return ans; 21 | } 22 | 23 | struct query 24 | { 25 | int l, r, lca, idx; 26 | bool flag; 27 | int64_t ord; 28 | 29 | inline void calcOrder() 30 | { 31 | ord = gilbertOrder(l, r, 16, 0); 32 | } 33 | }; 34 | 35 | const int N = 2e5 + 5; 36 | const int l = ceil(log2(N)); 37 | int up[N][l+1], tin[N], tout[N]; 38 | int cnt[N], a[N], ans[N]; 39 | bool chk[N]; 40 | vector adj[N]; 41 | vector euler; 42 | vector mo; 43 | int n, q, eu, ev, timer = 0; 44 | int k; 45 | 46 | void dfs(int s, int e) 47 | { 48 | euler.pb(s); 49 | tin[s] = timer++; 50 | 51 | up[s][0] = e; 52 | for (int i = 1; i <= l; i++) 53 | { 54 | up[s][i] = up[up[s][i - 1]][i - 1]; 55 | } 56 | 57 | for (auto u : adj[s]) 58 | { 59 | if (u == e) 60 | continue; 61 | dfs(u, s); 62 | } 63 | euler.pb(s); 64 | tout[s] = timer++; 65 | } 66 | 67 | bool isancestor(int u, int v) 68 | { 69 | return (tin[u] <= tin[v] && tout[u] >= tout[v]); 70 | } 71 | 72 | int LCA(int u, int v) 73 | { 74 | if (isancestor(u, v)) 75 | return u; 76 | if (isancestor(v, u)) 77 | return v; 78 | 79 | for (int i = l; i >= 0; i--) 80 | { 81 | if (!isancestor(up[u][i], v)) 82 | u = up[u][i]; 83 | } 84 | return up[u][0]; 85 | } 86 | 87 | bool compare(query a, query b) 88 | { 89 | return a.ord < b.ord; 90 | } 91 | 92 | query make_query(int a, int b, int idx) 93 | { 94 | if (tin[a] > tin[b]) 95 | swap(a, b); 96 | 97 | int lca = LCA(a, b); 98 | query need; 99 | 100 | if (a == lca) 101 | need = {tin[a], tin[b], lca, idx, 0}; 102 | need = {tout[a], tin[b], lca, idx, 1}; 103 | 104 | need.calcOrder(); 105 | debug(need.ord); 106 | return need; 107 | } 108 | 109 | int res; 110 | void check(int node) 111 | { 112 | //DONT COUNT NODE IF IT APPEARS TWICE 113 | if (!chk[node]) 114 | { 115 | cnt[a[node]]++; 116 | if (cnt[a[node]] == 1) 117 | res++; 118 | } 119 | else 120 | { 121 | cnt[a[node]]--; 122 | if (cnt[a[node]] == 0) 123 | res--; 124 | } 125 | chk[node] ^= 1; 126 | } 127 | void compute() 128 | { 129 | //algo for zero based queries 130 | res = 0; 131 | int l = 0, r = -1; 132 | for (query u : mo) 133 | { 134 | while (l > u.l) 135 | check(euler[--l]); 136 | while (r < u.r) 137 | check(euler[++r]); 138 | while (l < u.l) 139 | check(euler[l++]); 140 | while (r > u.r) 141 | check(euler[r--]); 142 | 143 | if (u.flag) 144 | { 145 | check(u.lca); 146 | ans[u.idx] = res; 147 | check(u.lca); 148 | } 149 | else 150 | { 151 | ans[u.idx] = res; 152 | } 153 | } 154 | } 155 | int main() 156 | { 157 | kira; 158 | cin >> n >> q; 159 | map m; 160 | ll y; 161 | for (int i = 1; i <= n; i++) 162 | { 163 | cin >> y; 164 | if (m.count(y)) 165 | a[i] = m[y]; 166 | else 167 | { 168 | a[i] = m.size(); 169 | m[y] = a[i]; 170 | } 171 | } 172 | forz(i, n - 1) 173 | { 174 | cin >> eu >> ev; 175 | adj[eu].pb(ev); 176 | adj[ev].pb(eu); 177 | } 178 | dfs(1, 1); 179 | 180 | int ql, qr, qk; 181 | forz(i, q) 182 | { 183 | cin >> ql >> qr; 184 | mo.pb(make_query(ql, qr, i)); 185 | } 186 | sort(all(mo), compare); 187 | 188 | compute(); 189 | for (int i = 0; i < q; i++) 190 | p1(ans[i]); 191 | return 0; 192 | } -------------------------------------------------------------------------------- /Trees/mo_trees.cpp: -------------------------------------------------------------------------------- 1 | struct query 2 | { 3 | int l, r, lca, idx; 4 | bool flag; 5 | }; 6 | 7 | const int N = 2e5 + 5; 8 | const int l = ceil(log2(N)); 9 | int up[N][l+1], tin[N], tout[N]; 10 | int cnt[N], a[N], ans[N]; 11 | bool chk[N]; 12 | vector adj[N]; 13 | vector euler; 14 | vector mo; 15 | int n, q, eu, ev, timer = 0; 16 | int len, k; 17 | 18 | void dfs(int s, int e) 19 | { 20 | euler.pb(s); 21 | tin[s] = timer++; 22 | 23 | up[s][0] = e; 24 | for (int i = 1; i <= l; i++) 25 | { 26 | up[s][i] = up[up[s][i - 1]][i - 1]; 27 | } 28 | 29 | for (auto u : adj[s]) 30 | { 31 | if (u == e) 32 | continue; 33 | dfs(u, s); 34 | } 35 | euler.pb(s); 36 | tout[s] = timer++; 37 | } 38 | 39 | bool isancestor(int u, int v) 40 | { 41 | return (tin[u] <= tin[v] && tout[u] >= tout[v]); 42 | } 43 | 44 | int LCA(int u, int v) 45 | { 46 | if (isancestor(u, v)) 47 | return u; 48 | if (isancestor(v, u)) 49 | return v; 50 | 51 | for (int i = l; i >= 0; i--) 52 | { 53 | if (!isancestor(up[u][i], v)) 54 | u = up[u][i]; 55 | } 56 | return up[u][0]; 57 | } 58 | 59 | bool compare(query a, query b) 60 | { 61 | if (a.l / len != b.l / len) 62 | return a.l / len < b.l / len; 63 | 64 | return ((a.l / len) & 1) ? (a.r < b.r) : (a.r > b.r); 65 | } 66 | 67 | query make_query(int a, int b, int idx) 68 | { 69 | if (tin[a] > tin[b]) 70 | swap(a, b); 71 | 72 | int lca = LCA(a, b); 73 | 74 | if (a == lca) 75 | return {tin[a], tin[b], lca, idx, 0}; 76 | return {tout[a], tin[b], lca, idx, 1}; 77 | } 78 | 79 | int res; 80 | void check(int node) 81 | { 82 | //DONT COUNT NODE IF IT APPEARS TWICE 83 | if (!chk[node]) 84 | { 85 | cnt[a[node]]++; 86 | if (cnt[a[node]] == 1) 87 | res++; 88 | } 89 | else 90 | { 91 | cnt[a[node]]--; 92 | if (cnt[a[node]] == 0) 93 | res--; 94 | } 95 | chk[node] ^= 1; 96 | } 97 | void compute() 98 | { 99 | //algo for zero based queries 100 | int l = 0, r = -1; 101 | res = 0; 102 | for (query u : mo) 103 | { 104 | while (l > u.l) 105 | check(euler[--l]); 106 | while (r < u.r) 107 | check(euler[++r]); 108 | while (l < u.l) 109 | check(euler[l++]); 110 | while (r > u.r) 111 | check(euler[r--]); 112 | 113 | if (u.flag) 114 | { 115 | check(u.lca); 116 | ans[u.idx] = res; 117 | check(u.lca); 118 | } 119 | else 120 | { 121 | ans[u.idx] = res; 122 | } 123 | } 124 | } 125 | int main() 126 | { 127 | kira; 128 | cin >> n >> q; 129 | mapm; 130 | ll y; 131 | for (int i = 1; i <= n; i++) 132 | { 133 | cin >> y; 134 | if(m.count(y))a[i]=m[y]; 135 | else 136 | { 137 | a[i]=m.size(); 138 | m[y]=a[i]; 139 | } 140 | } 141 | forz(i, n - 1) 142 | { 143 | cin >> eu >> ev; 144 | adj[eu].pb(ev); 145 | adj[ev].pb(eu); 146 | } 147 | dfs(1, 1); 148 | 149 | int ql, qr, qk; 150 | forz(i, q) 151 | { 152 | cin >> ql >> qr ; 153 | mo.pb(make_query(ql, qr, i)); 154 | } 155 | len = int(sqrt(n + 0.5)) + 1; 156 | sort(all(mo), compare); 157 | 158 | compute(); 159 | for (int i = 0; i < q; i++) 160 | p1(ans[i]); 161 | return 0; 162 | } -------------------------------------------------------------------------------- /Trees/prufer.cpp: -------------------------------------------------------------------------------- 1 | 1)The Prüfer code is a way of encoding a labeled tree with n vertices using a sequence of n−2 integers in the interval [0;n−1]. This encoding also acts as a bijection between all spanning trees of a complete graph and the numerical sequences. 2 | 3 | 2)The Prüfer code is constructed as follows. We will repeat the following procedure n−2 times: we select the leaf of the tree with the smallest number, remove it from the tree, and write down the number of the vertex that was connected to it. After n−2 iterations there will only remain 2 vertices, and the algorithm ends. 4 | 5 | 3)After constructing the Prüfer code two vertices will remain. One of them is the highest vertex n−1, but nothing else can be said about the other one. 6 | 7 | 4)Each vertex appears in the Prüfer code exactly a fixed number of times - its degree minus one. This can be easily checked, since the degree will get smaller every time we record its label in the code, and we remove it once the degree is 1. For the two remaining vertices this fact is also true. 8 | 9 | //================Build prufer========================= 10 | 11 | void dfs(int v) 12 | { 13 | for (int u : adj[v]) 14 | { 15 | if (u != parent[v]) 16 | { 17 | parent[u] = v; 18 | dfs(u); 19 | } 20 | } 21 | } 22 | 23 | vector prufer_code() 24 | { 25 | int n = adj.size(); 26 | parent.resize(n); 27 | parent[n - 1] = -1; 28 | dfs(n - 1); 29 | 30 | int ptr = -1; 31 | vector degree(n); 32 | for (int i = 0; i < n; i++) 33 | { 34 | degree[i] = adj[i].size(); 35 | if (degree[i] == 1 && ptr == -1) 36 | ptr = i; 37 | } 38 | 39 | vector code(n - 2); 40 | int leaf = ptr; 41 | for (int i = 0; i < n - 2; i++) 42 | { 43 | int next = parent[leaf]; 44 | code[i] = next; 45 | if (--degree[next] == 1 && next < ptr) 46 | { 47 | leaf = next; 48 | } 49 | else 50 | { 51 | ptr++; 52 | while (degree[ptr] != 1) 53 | ptr++; 54 | leaf = ptr; 55 | } 56 | } 57 | 58 | return code; 59 | } 60 | 61 | //====================DECODE=========================== 62 | 63 | vector prufer_decode(vector code) 64 | { 65 | ll n = code.si + 2; 66 | vector deg(n + 1, 1); 67 | for (auto x : code) 68 | deg[x]++; 69 | ll in = 1; 70 | while (deg[in] != 1) 71 | in++; 72 | ll leaf = in; 73 | vector edges; 74 | for (auto x : code) 75 | { 76 | edges.pb({leaf, x}); 77 | if (--deg[x] == 1 && x < in) 78 | leaf = x; 79 | else 80 | { 81 | in++; 82 | while (deg[in] != 1) 83 | in++; 84 | leaf = in; 85 | } 86 | } 87 | edges.pb({leaf, n}); 88 | return edges; 89 | } -------------------------------------------------------------------------------- /Trees/subtree.cpp: -------------------------------------------------------------------------------- 1 | 1)Size of subtrees of each node can be calulated by the following. 2 | 3 | const int N = 2e5 + 5; 4 | vector adj[N]; 5 | ll subtree[N]; 6 | void dfs(int s,int e) 7 | { 8 | subtree[s]=1; 9 | for(auto u:adj[s]) 10 | { 11 | if(u==e)continue; 12 | dfs(u,s); 13 | subtree[s]+=subtree[u]; 14 | } 15 | } -------------------------------------------------------------------------------- /learn.md: -------------------------------------------------------------------------------- 1 | # Key points while solving questions 2 | 3 | 1. Read Constraints First. 4 | 2. If constraints around 1e4 can use bitset. 5 | 3. Disconnected components common property to be found 6 | use a dummy node. 7 | 4. If A1 and An are adjacent double the array. 8 | 5. Use stack to find left and right boundaries. 9 | 6. For Mathematical problems workout small cases. 10 | 7. Check for small inputs and hence pigeonhole priciple. 11 | 8. Think like a brute force solution first. 12 | 9. Think the problems in backward direction. 13 | 10. For cyclic shifts of permutations use position indexing. 14 | 11. Primes upto 1e7 always use linear sieve. 15 | 12. Constructive problems make partitions. 16 | 13. Problems with a edge contributions can be solved using DSU. -------------------------------------------------------------------------------- /learn.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tejas01101001/Competitive-coding/d0f29301ae5867d6ace451aa58771f3190589711/learn.pdf --------------------------------------------------------------------------------