├── .gitignore ├── LICENSE ├── README.md └── src ├── KMP.cpp ├── Z_algorithm_max_prefix_match.cpp ├── aggreate_sqrt_distinct_values.cpp ├── aggregate_cyclic_function.cpp ├── all_pair_shortest_path_binary_exponentation.cpp ├── all_pair_shortest_path_floyd_warshall.cpp ├── bellman_ford.cpp ├── bigint_library.cpp ├── binary_indexed_tree.cpp ├── binary_indexed_tree_2D.cpp ├── binary_indexed_tree_order_stat.cpp ├── binary_indexed_tree_range_query_range_update.cpp ├── binary_trie_max_xor.cpp ├── bitmask.cpp ├── bridges_in_graph.cpp ├── clean.bat ├── closest_max_element_before_after_index_using_stack.cpp ├── connected_component_in_graph.cpp ├── convexhull.cpp ├── cycle_detection_in_graph.cpp ├── dijkstra_using_priority_queue.cpp ├── dijsktra_dense_graphs.cpp ├── disjoint_set.cpp ├── disjoint_set_with_undo_operation.cpp ├── dynamic_programming_templates.cpp ├── dynamic_string_using_treap.cpp ├── edit_distance_levenstein_dynamic_programming.cpp ├── euler_phi_euler_totient_function.cpp ├── factorial_preprocessing.cpp ├── fast_fourier_transform_fft.cpp ├── fast_readInt_writeInt_function.cpp ├── generate_all_palindromes.cpp ├── heap_using_multiset_max_min_insert_erase_update.cpp ├── heavy_light_decomposition_weighted_edges (hld).cpp ├── heavy_light_decomposition_wieghted_vertices(hld).cpp ├── int2string_string2int.cpp ├── isConnected_using_bfs.cpp ├── karatsuba_polynomial_multiplication.cpp ├── kruskal_min_spanning_tree.cpp ├── kth_ancestor_tree.cpp ├── kth_shortest_path_between_nodes_graph.cpp ├── linear_recurrence_matrix_exponentiation.cpp ├── linearize_tree_subtree_aggregate_query.cpp ├── longest_increasing_subsequence_lis_binary_search.cpp ├── lowest_common_ancestor_lca.cpp ├── lucas_combinatorics.cpp ├── max_bipartite_matching_hopcroft_karp.cpp ├── max_flow_network_dinic_algorithm.cpp ├── merge_sort_count_inversion.cpp ├── merge_sort_trees.cpp ├── merge_sort_trees_order_stat_query.cpp ├── misc ├── online_median_heaps.cpp └── radix_sort.cpp ├── mo_algorithm_offline_range_query.cpp ├── mobeius_function.cpp ├── monotone_priority_queue.cpp ├── multiply_detect_overflow.cpp ├── multiply_longlong_integers.cpp ├── non_bipartite_check.cpp ├── number_paths_length_k.cpp ├── obselete ├── knuth_morris_pratt_string_matching.cpp └── suffix_array.cpp ├── orderstat_rank_query_augmented_bst.cpp ├── palindrome_longest_subsequence.cpp ├── path_nearly_complete_binary_tree.cpp ├── power_binary_exponentiation.cpp ├── primality_check_fermat.cpp ├── prime_factor_count.cpp ├── prime_sieve.cpp ├── quick_select_order_stat_linear.cpp ├── rabin_karp.cpp ├── range_minimum_query_sparse_table.cpp ├── scanline_merge_overlapping_intervals.cpp ├── segement_trees_max_index_element_in_l_r_greater_than_k.cpp ├── segment_tree_2D.cpp ├── segment_tree_custom_merge_function.cpp ├── segment_tree_dynamic_reverse_subarray_using_treap.cpp ├── segment_tree_dynamic_using_treaps.cpp ├── segment_tree_persistent.cpp ├── segment_tree_persistent_order_stat.cpp ├── segment_tree_range_query_point_update.cpp ├── segment_tree_range_query_range_update_lazy_propogation.cpp ├── segment_trees_interative_fast.cpp ├── segmented_sieve_large_primes.cpp ├── string_hashing.cpp ├── string_hashing_dynamic_segment_trees.cpp ├── strongly_connected_components_kosaraju.cpp ├── subtree size and level.cpp ├── ternary_search.cpp ├── topological_sort_kosaraju.cpp ├── tree_dfs_preorder_postorder_isInSubtree.cpp ├── tree_diameter.cpp ├── trees_path_query_sparse_tables.cpp ├── trie_insertion_deleteion.cpp └── untested-codes ├── aho_corasick.cpp └── suffix_array.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.o 3 | *.obj 4 | 5 | # Executables 6 | *.exe 7 | *.out 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Swapnil Saxena 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Competitive-Programming-Repository 2 | Collection of algorithms and data structures in C++ used widely in Competitive programming contests. 3 | 4 | ### The following topics are covered: 5 | 6 | #### Range Updates and Queries 7 | * **Range Aggregate Queries** : 8 | * *Binary Indexed Trees (BIT)* : 9 | * [Point Update Range Query](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/binary_indexed_tree.cpp) 10 | * [Range Update Range Query](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/binary_indexed_tree_range_query_range_update.cpp) 11 | * [Order Statistic Query](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/binary_indexed_tree_order_stat.cpp) 12 | * [2D Binary Indexed Trees](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/binary_indexed_tree_2D.cpp) 13 | * *Segment Trees (SegTree)* : 14 | * [Point Update Range Query](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/segment_tree_range_query_point_update.cpp) 15 | * [Fast Iterative Segtrees](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/segment_trees_interative_fast.cpp) 16 | * [Range Update Point Query - Lazy Propogation](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/segment_tree_range_query_range_update_lazy_propogation.cpp) 17 | * [Max subsegment sum in range](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/segment_tree_custom_merge_function.cpp) 18 | * [2D Segment Trees](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/segment_tree_2D.cpp) 19 | * [Dynamic Segment Trees - Insertion/Deletion between elements](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/segment_tree_dynamic_using_treaps.cpp) 20 | * [Dynamic Segment Trees - Reverse a segment](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/segment_tree_dynamic_reverse_subarray_using_treap.cpp) 21 | * *Merge Sort Trees* : 22 | * [Merge sort trees](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/merge_sort_trees.cpp) 23 | * [Merge sort trees - Order Statistics](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/merge_sort_trees_order_stat_query.cpp) 24 | * *Sparse Table* : 25 | * [Range Minimum Query](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/range_minimum_query_sparse_table.cpp) 26 | * *Mo Algorithm* : 27 | * [Mo Algorithm - Arrays](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/mo_algorithm_offline_range_query.cpp) 28 | * **Dynamic Programming** : 29 | * *Dynamic Programming Templates* : 30 | * [Digit DP / Bitwise DP](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/dynamic_programming_templates.cpp) 31 | * *Standard DP Problems* : 32 | * [Longest Increasing Subsequence](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/longest_increasing_subsequence_lis_binary_search.cpp) 33 | * [Longest Palindromic Subsequence](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/palindrome_longest_subsequence.cpp) 34 | * [Levenstein Distance / Edit Distance](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/edit_distance_levenstein_dynamic_programming.cpp) 35 | * **Graphs** : 36 | * *Single Source Shortest Path Algorithms* : 37 | * [Dijkstra in dense graphs](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/dijsktra_dense_graphs.cpp) 38 | * [Dijkstra using priority queue](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/dijkstra_using_priority_queue.cpp) 39 | * [Kth Shortest Path between Nodes using Dijkstra](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/kth_shortest_path_between_nodes_graph.cpp) 40 | * [Bellman Ford Negative cycle detection](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/bellman_ford.cpp) 41 | * *All Pair shortest path* : 42 | * [Using Binary exponentiation](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/all_pair_shortest_path_binary_exponentation.cpp) 43 | * [Floyd Warshall](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/all_pair_shortest_path_floyd_warshall.cpp) 44 | * *Cycle Detection* : 45 | * [Cycle detection in Undirected/Directed Graphs](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/cycle_detection_in_graph.cpp) 46 | * *Minimum Spanning tree* : 47 | * [Kruskal Algorithm](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/kruskal_min_spanning_tree.cpp) 48 | * *Topological Sort / Strongly Connected Component* : 49 | * [Topological Sort](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/topological_sort_kosaraju.cpp) 50 | * [Strongly Connected Component](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/strongly_connected_components_kosaraju.cpp) 51 | * *Maxflow/Matching* : 52 | * [Hopkroft Karp Max Matching](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/max_bipartite_matching_hopcroft_karp.cpp) 53 | * [Dinic Max Flow](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/max_flow_network_dinic_algorithm.cpp) 54 | * *Misc* : 55 | * [Bridges in Graph](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/bridges_in_graph.cpp) 56 | * [Connectivity](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/isConnected_using_bfs.cpp) 57 | * [Bipartite Check](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/non_bipartite_check.cpp) 58 | * **Trees** : 59 | * *Ancestor queries* : 60 | * [Lowest Common Ancestor](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/lowest_common_ancestor_lca.cpp) 61 | * [Kth Ancestor](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/kth_ancestor_tree.cpp) 62 | * *Path queries* : 63 | * [Sparse Table *](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/trees_path_query_sparse_tables.cpp) 64 | * [Heavy Light Decomposition Weighted Nodes](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/heavy_light_decomposition_wieghted_vertices(hld).cpp) 65 | * [Heavy Light Decomposition Weighted Edges](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/heavy_light_decomposition_weighted_edges%20(hld).cpp) 66 | * *Misc* : 67 | * [Diameter of Tree](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/tree_diameter.cpp) 68 | * [Preorder/Postorder stamps, Is it in Subtree?](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/tree_dfs_preorder_postorder_isInSubtree.cpp) 69 | * **Binary Exponentiation** : 70 | * [Calculate n^m using Binary exponentiation](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/power_binary_exponentiation.cpp) 71 | * [Solving Linear Recurrences](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/linear_recurrence_matrix_exponentiation.cpp) 72 | * **Strings** : 73 | * *String Algorithms* : 74 | * [Z Algorithm](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/Z_algorithm_max_prefix_match.cpp) 75 | * [KMP algorithm](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/KMP.cpp) 76 | * [Rolling String Hashing](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/string_hashing.cpp) 77 | * [Rolling String Hashing for Dynamic Strings](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/string_hashing_dynamic_segment_trees.cpp) 78 | * *String Data Structures* : 79 | * [Suffix Array *](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/untested-codes/suffix_array.cpp) 80 | * **Sorting** : 81 | * [Merge Sort](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/merge_sort_count_inversion.cpp) 82 | * [Quick Select](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/quick_select_order_stat_linear.cpp) 83 | * **Fast Input/Output, String/Integer Conversion** : 84 | * [Fast Input/Output](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/fast_readInt_writeInt_function.cpp) 85 | * [String/Integer Conversion](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/int2string_string2int.cpp) 86 | * **Misc. Data Structures** : 87 | * [Disjoint Set](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/disjoint_set.cpp) 88 | * [Disjoint Set (Supports Undo Operation)](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/disjoint_set_with_undo_operation.cpp) 89 | * [Max/Min Priority Queue with update](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/heap_using_multiset_max_min_insert_erase_update.cpp) 90 | * [Binary Trie for xor maximization/minimization](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/binary_trie_max_xor.cpp) 91 | * [Bigint *](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/bigint_library.cpp) 92 | * [Augmented Binary Tree for order statistics and rank query](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/orderstat_rank_query_augmented_bst.cpp) 93 | * [Monotone Priority Queue](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/monotone_priority_queue.cpp) 94 | * [Trie](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/trie_insertion_deleteion.cpp) 95 | * **Persistent Data Structures** : 96 | * *Persistent Segment Trees (SegTree)* : 97 | * [Persistent Segment Tree](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/segment_tree_persistent.cpp) 98 | * [Persistent Segment Tree - Order Statistics](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/segment_tree_persistent_order_stat.cpp) 99 | * **Number Theory Algorithms** : 100 | * *Primality Check* : 101 | * [Fermat's Primality Check](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/primality_check_fermat.cpp) 102 | * *Sieve* : 103 | * [Sieve of Eratosthenes](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/prime_sieve.cpp) 104 | * [Segmented Sieve for large primes](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/segmented_sieve_large_primes.cpp) 105 | * [Counting Prime Factors](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/prime_factor_count.cpp) 106 | * *Polynomial Multiplication* : 107 | * [Fast Fourier Tranform](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/fast_fourier_transform_fft.cpp) 108 | * [Karatsuba](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/karatsuba_polynomial_multiplication.cpp) 109 | * *Misc* : 110 | * [Combinatorial and Catalan - Factorial preprocessing](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/factorial_preprocessing.cpp) 111 | * [Mobeius Function](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/mobeius_function.cpp) 112 | * [Euler Totient Function](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/euler_phi_euler_totient_function.cpp) 113 | * [Lucas Theorm - Combinatorics](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/lucas_combinatorics.cpp) 114 | * **Computational Geometry** : 115 | * [Convex Hull](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/convexhull.cpp) 116 | * **Misc** : 117 | * [Sum of floor(x) with x=1:n](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/aggreate_sqrt_distinct_values.cpp) 118 | * [Sum of cyclic functions *](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/aggregate_cyclic_function.cpp) 119 | * [Closest larger element before/after every element](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/closest_max_element_before_after_index_using_stack.cpp) 120 | * [Multiply Long Long Integers](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/multiply_longlong_integers.cpp) 121 | * [Multiply Long Long Integers - Overflow detection](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/multiply_detect_overflow.cpp) 122 | * [Scanline - Merge intersecting intervals](https://github.com/dragonslayerx/Competitive-Programming-Repository/blob/master/src/scanline_merge_overlapping_intervals.cpp) 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /src/KMP.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | /* 6 | * get prefix list 7 | */ 8 | vector computePrefix(string str) { 9 | 10 | int m=int(str.length()); 11 | vector prefix(m); 12 | for(int i=1,k=0;i0&&str[i]!=str[k]) 15 | k=prefix[k-1]; 16 | if(str[k]==str[i]) 17 | prefix[i]=++k; 18 | else 19 | prefix[i]=k; 20 | } 21 | 22 | return prefix; 23 | } 24 | 25 | void KMP(string &str, string pat) { 26 | int m = int(str.length()); 27 | int n = int(pat.length()); 28 | vector longestPrefix = computePrefix(pat); 29 | 30 | for (int i = 0, k = 0; i < m; ++i) { 31 | if (k > 0 && pat[k] != str[i]) 32 | k = longestPrefix[k - 1]; 33 | if (str[i] == pat[k]) 34 | ++k; 35 | if (k == n) { 36 | cout << i - n + 1 << "\n"; 37 | //more than one pattern 38 | k = longestPrefix[k - 1]; 39 | } 40 | 41 | } 42 | } 43 | 44 | int main() { 45 | string s,p; 46 | cin>>s>>p; 47 | KMP(s,p); 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /src/Z_algorithm_max_prefix_match.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Z function 3 | * Usage: calculateZfunc O(|S|) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | class Z { 12 | public: 13 | static vector calculateZfunc(const string &s) 14 | { 15 | int L = 0, R = 0; 16 | int n = s.size(); 17 | vector Zf(n); 18 | for (int i = 1; i < n; i++){ 19 | if (R < i) { 20 | int j, k; 21 | for (j = i, k = 0; j < n && (s[j] == s[k]); j++, k++); 22 | L = i; 23 | R = j-1; 24 | Zf[i] = R - i + 1; 25 | } else { 26 | int p = i - L; 27 | if (Zf[p] >= R-i+1) { 28 | int j, k; 29 | for (j = R+1, k = R-i+1; j < n && (s[j] == s[k]); j++, k++) 30 | L = i; 31 | R = j-1; 32 | Zf[i] = R - i + 1; 33 | } else { 34 | Zf[i] = Zf[p]; 35 | } 36 | } 37 | 38 | } 39 | return Zf; 40 | } 41 | }; 42 | 43 | int main() 44 | { 45 | string s = "ddcdddc"; 46 | cerr << s << endl; 47 | vector Zf = Z::calculateZfunc(s); 48 | for (int i = 0; i < Zf.size(); i++) { 49 | cout << Zf[i] << " "; 50 | } 51 | cout << endl; 52 | } 53 | -------------------------------------------------------------------------------- /src/aggreate_sqrt_distinct_values.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Sum of floor(n/1) + floor(n/2) + floor(n/3) + ... + floor(n/n) 3 | * Usage: See below. O(sqrt(n)) 4 | * Note: This method can be extended to any function that takes only O(sqrt(n)) distinct values. 5 | * Source: https://github.com/dragonslayerx 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | const int MOD = 1e9 + 7 ; 14 | 15 | int main() { 16 | long long n; 17 | scanf("%lld", &n); 18 | long long answer = 0; 19 | int i; 20 | for (i = 1; (long long)i*i <= n; i++) { 21 | answer += n/i; 22 | answer %= MOD; 23 | } 24 | i--; 25 | for (int j = 1; n/(j+1) >= i; j++) { 26 | answer += (((n/j - n/(j+1)) % MOD) * j) % MOD; 27 | answer %= MOD; 28 | } 29 | printf("%lld\n", answer); 30 | } 31 | -------------------------------------------------------------------------------- /src/aggregate_cyclic_function.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Calculate aggregate of k terms in a cyclic function 3 | * Note: cycle length must be small. 4 | * getNext and getCyclicFuncfion must be overridden accordingly. 5 | * Assumption: seed is considered as the 0th element of the sequence 6 | * Source: https://github.com/dragonslayerx 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | long long getNext(long long x) { 16 | return x + 1; 17 | } 18 | 19 | long long getCyclic(long long x) { 20 | return x % 5; 21 | } 22 | 23 | long long getSum(long long seed, long long k) { 24 | const int INF = 1e9; 25 | long long cycleLength = INF, cycleStart = -1; 26 | map index; 27 | index[getCyclic(seed)] = 0; 28 | { 29 | long long x = seed; 30 | for (int i = 1; i <= k; i++) { 31 | x = getNext(x); 32 | long long c = getCyclic(x); 33 | if (index.count(c)) { 34 | cycleStart = index[c]; 35 | cycleLength = i-cycleStart; 36 | break; 37 | } else { 38 | index[c] = i; 39 | } 40 | } 41 | } 42 | long long sum = 0; 43 | { 44 | if (cycleLength == INF) { 45 | sum += getCyclic(seed); 46 | long long x = seed; 47 | for (int i = 1; i <= k; i++) { 48 | x = getNext(x); 49 | sum += getCyclic(x); 50 | } 51 | } else { 52 | k++; 53 | long long x = seed; 54 | for (int i = 1; i <= cycleStart; i++) { 55 | sum += getCyclic(x); 56 | x = getNext(x); 57 | k--; 58 | } 59 | 60 | long long turns = k/cycleLength; 61 | long long rem = k%cycleLength; 62 | 63 | long long cycleSum = 0, remSum = 0; 64 | for (int i = 0; i < cycleLength; i++) { 65 | long long c = getCyclic(x); 66 | cycleSum += c;// modify here 67 | if (i < rem) { 68 | remSum += c; // modify here 69 | } 70 | x = getNext(x); 71 | } 72 | sum += turns * cycleSum + remSum; 73 | } 74 | } 75 | return sum; 76 | } 77 | 78 | int main() { 79 | cout << getSum(1, 6) << endl; 80 | } 81 | -------------------------------------------------------------------------------- /src/all_pair_shortest_path_binary_exponentation.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: All pair shortest paths (Returns a matrix A where A[i][j] is the M-length shortest path from vertex i to vertex j) 3 | * Usage: getShortestPath O(N^3 log M) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | const int MAX = 100; 12 | const int INF = 1e9; 13 | 14 | void multiply(int A[][MAX], int B[][MAX], int n) { 15 | int C[MAX][MAX]; 16 | for(int i = 0; i < n; i++) { 17 | for (int j = 0; j < n; j++) { 18 | C[i][j] =INF; 19 | } 20 | } 21 | for (int i = 0; i < n; i++) { 22 | for (int j = 0; j < n; j++) { 23 | for (int k = 0; k < n; k++) { 24 | if (A[i][k] != INF && B[k][j] != INF) { 25 | C[i][j] = min(C[i][j], A[i][k] + B[k][j]); 26 | } 27 | } 28 | } 29 | } 30 | for (int i = 0; i < n; i++) { 31 | for (int j = 0; j < n; j++) { 32 | A[i][j] = C[i][j]; 33 | } 34 | } 35 | } 36 | 37 | void getShortestPath(int A[][MAX], int B[][MAX], const int n, int m) { 38 | if (m == 1)return; 39 | getShortestPath(A, B, n, m/2); 40 | multiply(A, A, n); 41 | if (m & 1) multiply(A, B, n); 42 | } 43 | 44 | int main() { 45 | int N; 46 | scanf("%d", &N); 47 | int Adj[MAX][MAX]; 48 | for (int i = 0; i < N; i++) { 49 | for (int j = 0; j < N; j++) { 50 | Adj[i][j]=INF; 51 | } 52 | Adj[i][i] = 0; 53 | } 54 | int countEdges; 55 | scanf("%d", &countEdges); 56 | for (int i = 0; i < countEdges; i++) { 57 | int u, v, w; 58 | scanf("%d%d%d", &u, &v, &w); 59 | u--, v--; 60 | Adj[u][v] = Adj[v][u] = w; 61 | } 62 | 63 | int Dist[MAX][MAX]; 64 | for (int i = 0; i < N; i++) { 65 | for (int j = 0; j < N; j++) { 66 | Dist[i][j]=Adj[i][j]; 67 | } 68 | } 69 | getShortestPath(Dist, Adj, N, N); 70 | for (int i = 0; i < N; i++) { 71 | for (int j = 0; j < N; j++) { 72 | printf("%5d", Dist[i][j]); 73 | } 74 | printf("\n"); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/all_pair_shortest_path_floyd_warshall.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Floyd Warshall (Find the all pair shortest path distances) 3 | * Usage: See below O(N^3) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | const int MAX = 100; 12 | const int INF = 1e9 + 5; 13 | int main(){ 14 | int n; 15 | cin >> n; 16 | int Adj[MAX][MAX]; 17 | for (int i = 0; i < n; i++) { 18 | for (int j = 0; j < n; j++) { 19 | Adj[i][j] = INF; 20 | } 21 | Adj[i][i] = 0; 22 | } 23 | 24 | int countEdges; 25 | cin >> countEdges; 26 | for (int i = 0; i < countEdges; i++) { 27 | int a, b; 28 | int w; 29 | cin >> a >> b >> w; 30 | a--, b--; 31 | Adj[a][b] = min(Adj[a][b], w); 32 | Adj[b][a] = min(Adj[b][a], w); 33 | } 34 | 35 | int dist[MAX][MAX]; 36 | for (int i = 0; i < n; i++) { 37 | for (int j = 0; j < n; j++) { 38 | dist[i][j] = Adj[i][j]; 39 | } 40 | } 41 | // Floyd Warshall Algorithm 42 | for (int k = 0; k < n; k++) { 43 | for (int i = 0; i < n; i++) { 44 | for (int j = 0; j < n; j++) { 45 | if (dist[i][k] != INF and dist[k][j] != INF) { 46 | if (dist[i][j] > dist[i][k] + dist[k][j]) { 47 | dist[i][j] = dist[i][k] + dist[k][j]; 48 | } 49 | } 50 | } 51 | } 52 | } 53 | 54 | for (int i = 0; i < n; i++) { 55 | for (int j = 0; j < n; j++) { 56 | cout << dist[i][j] << " "; 57 | } 58 | cout << endl; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/bellman_ford.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Descrption: BellmanFord (Finds the shortest path from source s to all vertices v. Detects a negative weight cycle if present.) 3 | * Usage: See below O(V E) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | const int MAX = 100; 13 | const int INF = 1e9+5; 14 | 15 | struct edges { 16 | int u; 17 | int v; 18 | long long w; 19 | edges(int u, int v, long long w): u(u), v(v), w(w) {} 20 | }; 21 | 22 | int main(){ 23 | int n, m; 24 | scanf("%d %d", &n, &m); 25 | 26 | vector edge; 27 | 28 | for (int i = 0; i < m; i++) { 29 | int a, b; 30 | long long w; 31 | scanf("%d%d%lld", &a, &b, &w); 32 | edge.push_back(edges(a, b, w)); 33 | } 34 | 35 | int parent[MAX]; 36 | long long dist[MAX]; 37 | for (int i = 0; i < n; i++) { 38 | parent[i] = 0; 39 | dist[i] = INF; 40 | } 41 | 42 | dist[0] = 0; // distance of source node = 0 43 | for (int i = 0; i < n-1; i++) { 44 | for (int j = 0; j < edge.size(); j++) { 45 | int u = edge[j].u; 46 | int v = edge[j].v; 47 | long long w = edge[j].w; 48 | if (dist[u] != INF) { 49 | if (dist[v] > dist[u] + w){ 50 | dist[v] = dist[u] + w; 51 | parent[v] = u; 52 | } 53 | } 54 | } 55 | } 56 | 57 | bool negCycleExists = false; 58 | for (int j = 0; j < edge.size(); j++) { 59 | int u = edge[j].u; 60 | int v = edge[j].v; 61 | long long w = edge[j].w; 62 | if (dist[v] > (dist[u] + w)) { 63 | negCycleExists = true; 64 | break; 65 | } 66 | } 67 | 68 | if (negCycleExists) { 69 | cout << "Negative Cycle Exists"; 70 | } else { 71 | for (int i = 0; i < n; i++) { 72 | cout << i << "=>" << dist[i] << endl; 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/bigint_library.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Description: BigInt (Big Integer library) 3 | * Usage: See constructors, operators like +, -, *, /, >, >=, <, <=, ==, toString 4 | * Note: Remove references '&' in overloaded operators for chaining operations. 5 | * Source: https://github.com/dragonslayerx 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | using namespace std; 13 | 14 | class Bigint { 15 | 16 | const static int MAX = 100005; 17 | char x[MAX]; 18 | int length; 19 | 20 | void align(char *X, int numDigits) { 21 | int length = strlen(X); 22 | for (int i = length; i < numDigits; i++) X[i]='0'; 23 | X[numDigits]='\0'; 24 | } 25 | 26 | int add(char *X, int lenX, char *Y, int lenY, int carry, char *Z) { 27 | int maxLen = max(lenX, lenY); 28 | align(X, maxLen); align(Y, maxLen); 29 | for (int i = 0; i < maxLen; i++) { 30 | int num = (X[i]-'0') + (Y[i]-'0') + carry; 31 | Z[i] = num%10 + '0'; 32 | carry = num / 10; 33 | } 34 | if (carry) Z[maxLen++] = carry+'0'; 35 | Z[maxLen] = '\0'; 36 | 37 | //Put everything back to original state 38 | X[lenX]='\0'; Y[lenY]='\0'; 39 | 40 | return maxLen; 41 | } 42 | 43 | int substract(char *X, int lenX, char *Y, int lenY, char *Z){ 44 | int maxLen = max(lenX, lenY); 45 | align(X, maxLen); align(Y, maxLen); 46 | for (int i = 0; i < maxLen; i++) Y[i]=('9'-Y[i])+'0'; 47 | int len = add(X, lenX, Y, maxLen, 1, Z); 48 | Z[len--] = '\0'; 49 | 50 | //Put everything back to original state 51 | for (int i = 0; i < maxLen; i++) Y[i]=('9'-Y[i])+'0'; 52 | X[lenX]='\0'; Y[lenY]='\0'; 53 | 54 | return len; 55 | } 56 | 57 | int multiply(char *X, int lenX, char *Y, int lenY, char *Z) { 58 | if (lenX < lenY) { 59 | swap(X, Y); swap(lenX, lenY); 60 | } 61 | char result[MAX]; 62 | int lenZ = 0; 63 | for (int i = 0; Y[i]; i++) { 64 | int digit = Y[i]-'0'; 65 | int carry = 0, size = 0; 66 | for (int j = 0; X[j]; j++) { 67 | int val = ((X[j]-'0')*digit) + carry; 68 | carry = val/10; 69 | val %= 10; 70 | result[size++] = val+'0'; 71 | } 72 | if (carry) result[size++] = carry + '0'; 73 | result[size]='\0'; 74 | 75 | for (int j = size; j >= 0; j--) result[j+i] = result[j]; 76 | for (int j = 0; j < i; j++) result[j]='0'; 77 | 78 | char finalResult[MAX]; 79 | lenZ = add(result, size+i, Z, lenZ, 0, finalResult); 80 | strcpy(Z, finalResult); 81 | } 82 | return lenZ; 83 | } 84 | 85 | template 86 | int divideNmodulo(char *X, int lenX, T divisor, char *Z, T &modulo) { 87 | int remainder = 0; 88 | int size = 0; 89 | for(int i = lenX-1; i >= 0; i--){ 90 | remainder *= 10; 91 | remainder += X[i]- '0'; 92 | Z[size++] = remainder/divisor + '0'; 93 | remainder %= divisor; 94 | } 95 | Z[size]='\0'; 96 | reverse(Z, Z+size); 97 | modulo = remainder; 98 | return size; 99 | } 100 | 101 | // Relational Operations 102 | bool equals(char *X, int lenX, char *Y, int lenY) { 103 | int maxLen = max(lenX, lenY); 104 | align(X, maxLen); align(Y, maxLen); 105 | for (int i = maxLen; i >= 0; i--) { 106 | if (X[i] != Y[i]) return false; 107 | } 108 | 109 | //Put everything back to original state 110 | X[lenX] = '\0'; Y[lenY] = '\0'; 111 | 112 | return true; 113 | } 114 | 115 | bool greater(char *X, int lenX, char *Y, int lenY) { 116 | int maxLen = max(lenX, lenY); 117 | align(X, maxLen); align(Y, maxLen); 118 | for (int i = maxLen - 1; i >= 0; i--) { 119 | if (X[i] > Y[i]) return true; 120 | if (X[i] < Y[i]) return false; 121 | } 122 | 123 | //Put everything back to original state 124 | X[lenX] = '\0'; Y[lenY] = '\0'; 125 | 126 | return false; 127 | } 128 | 129 | public: 130 | //Constructors 131 | Bigint() { 132 | x[0]='0'; x[1]='\0'; 133 | length=1; 134 | } 135 | 136 | Bigint(string s) { 137 | length = s.size(); 138 | for (int i=0, j=length-1; i < s.size(); i++, j--) x[j]=s[i]; 139 | x[length]='\0'; 140 | } 141 | 142 | Bigint(int v) { 143 | int size = 0; 144 | while (v) { 145 | x[size++] = v % 10 + '0'; 146 | v /= 10; 147 | } 148 | x[size]='\0'; 149 | length = size; 150 | } 151 | 152 | //Arithmetic Operations 153 | Bigint operator +(Bigint &b) { 154 | Bigint r; 155 | r.length = add(this->x, this->length, b.x, b.length, 0, r.x); 156 | return r; 157 | } 158 | 159 | Bigint operator *(Bigint &b) { 160 | Bigint r; 161 | r.length = multiply(this->x, this->length, b.x, b.length, r.x); 162 | return r; 163 | } 164 | 165 | Bigint operator -(Bigint &b) { 166 | Bigint r; 167 | r.length = substract(this->x, this->length, b.x, b.length, r.x); 168 | return r; 169 | } 170 | 171 | Bigint operator /(int divisor) { 172 | Bigint r; 173 | int modulo = 0; 174 | r.length = divideNmodulo(this->x, this->length, divisor, r.x, modulo); 175 | return r; 176 | } 177 | 178 | int operator %(int divisor) { 179 | Bigint r; 180 | int modulo = 0; 181 | r.length = divideNmodulo(this->x, this->length, divisor, r.x, modulo); 182 | return modulo; 183 | } 184 | 185 | // Relational Operators 186 | bool operator ==(Bigint &b) { 187 | return equals(this->x, this->length, b.x, b.length); 188 | } 189 | 190 | bool operator >(Bigint &b) { 191 | return greater(this->x, this->length, b.x, b.length); 192 | } 193 | 194 | bool operator >=(Bigint &b) { 195 | return (((*this)>b) || ((*this)==b)); 196 | } 197 | 198 | bool operator <(Bigint &b) { 199 | return !((*this)>=b); 200 | } 201 | 202 | bool operator <=(Bigint &b) { 203 | return !((*this)>b); 204 | } 205 | 206 | 207 | string trimZeros(string &s) { 208 | int start = 0; 209 | while (s[start]=='0') start++; 210 | return s.substr(start); 211 | } 212 | 213 | string toString() { 214 | string s(x, x+length); 215 | reverse(s.begin(), s.end()); 216 | s = trimZeros(s); 217 | if(s.length() == 0) 218 | return "0"; 219 | return s; 220 | } 221 | 222 | friend std::ostream& operator<<(ostream &o, Bigint v) { 223 | o << v.toString(); 224 | return o; 225 | } 226 | }; 227 | 228 | int main() { 229 | Bigint A("123456789"); // Construct Bigint using string representation 230 | Bigint B(987654321); // Construct Bigint using integer representation 231 | Bigint C("456789"); 232 | Bigint D("0"); 233 | cout << "A * B: " << A * B << endl; // Overridden ostream 234 | cout << "A * B + C: " << A * B + C << endl; // Chaining operations 235 | cout << "(A > B): " << (A > B) << endl; 236 | cout << "D: " << D << endl; 237 | // logical operations 238 | if (A > B) cout << "A is greater than B" << endl; 239 | if (B > A) cout << "B is greater than A" << endl; 240 | if (A == B) cout << "A is equal to B" << endl; 241 | } 242 | -------------------------------------------------------------------------------- /src/binary_indexed_tree.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: BIT (Returns associative operation like sum for a prefix query i.e. say sum[1...i]) 3 | * Usage: query O(lg(N)), update O(lg(N)) 4 | * Note: Use 1-based indexing. 5 | * Source: https://github.com/dragonslayerx 6 | */ 7 | 8 | #define MAX 100005 9 | long long bit[MAX]; 10 | 11 | long long query(int indx){ 12 | long long sum = 0; 13 | while (indx) { 14 | sum += bit[indx]; 15 | indx -= (indx & -indx); 16 | } 17 | return sum; 18 | } 19 | 20 | void update(int indx, int x){ 21 | assert(indx != 0); 22 | while (indx < MAX) { 23 | bit[indx] += x; 24 | indx += (indx & -indx); 25 | } 26 | } 27 | 28 | int main() { 29 | int n; 30 | cin >> n; 31 | vector a(n); 32 | for (int i = 1; i <= n; i++) { 33 | cin >> a[i]; 34 | update(i, a[i]); 35 | } 36 | int q; 37 | cin >> q; 38 | while (q--) { 39 | int choice; 40 | cin >> choice; 41 | if (choice) { 42 | int l, r; 43 | cin >> l >> r; 44 | cout << query(r) - query(l-1) << endl; 45 | } else { 46 | int p; 47 | long long x; 48 | cin >> p >> x; 49 | update(p, x); 50 | } 51 | } 52 | } 53 | 54 | -------------------------------------------------------------------------------- /src/binary_indexed_tree_2D.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Bit 2D: Support point updates and associative operations like sum over a 2-D matrix 3 | * Complexity: lg(n) per query and update 4 | * Usage: query and update. Indexes should be 1-based 5 | * Source: https://github.com/dragonslayerx 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | using namespace std; 14 | 15 | #define MAX 1010 16 | 17 | long long bit[MAX][MAX]; 18 | bool grid[MAX][MAX]; 19 | 20 | long long queryx(int x, int y){ 21 | long long sum = 0; 22 | while (y) { 23 | sum += bit[x][y]; 24 | y -= y & -y; 25 | } 26 | return sum; 27 | } 28 | 29 | long long query(int x, int y){ 30 | long long sum = 0; 31 | while (x) { 32 | sum += queryx(x, y); 33 | x -= x & -x; 34 | } 35 | return sum; 36 | } 37 | 38 | void updatex(int x, int y, int v){ 39 | while (y < MAX) { 40 | bit[x][y] += v; 41 | y += y & -y; 42 | } 43 | } 44 | 45 | void update(int x, int y, int v){ 46 | while (x < MAX) { 47 | updatex(x, y, v); 48 | x += x & -x; 49 | } 50 | } 51 | 52 | int main() 53 | { 54 | int tc; 55 | scanf("%d", &tc); 56 | for (int t = 1; t <= tc; t++) { 57 | memset(bit, 0, sizeof(bit)); 58 | memset(grid, 0, sizeof(grid)); 59 | 60 | printf("Case %d:\n", t); 61 | int q; 62 | scanf("%d", &q); 63 | while (q--) { 64 | int ch; 65 | scanf("%d", &ch); 66 | if (ch == 0) { 67 | int x, y; 68 | scanf("%d%d", &x, &y); 69 | x++, y++; 70 | if (!grid[x][y]) { 71 | update(x, y, 1); 72 | grid[x][y] = 1; 73 | } 74 | } else if (ch == 1) { 75 | int x1, y1, x2, y2; 76 | scanf("%d%d%d%d", &x1, &y1, &x2, &y2); 77 | x1++, y1++, x2++, y2++; 78 | printf("%d\n", query(x2, y2) - query(x2, y1-1) - query(x1-1, y2) + query(x1-1, y1-1)); 79 | } 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/binary_indexed_tree_order_stat.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: BIT Orderstat (Returns Kth order statistic). 3 | * Usage: update O(lg(N)), statquery O(lg^2(N)) 4 | * Note: Perform range compression if range is large. 5 | * Source: https://github.com/dragonslayerx 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | const int MAX = 100005; 14 | typedef long long ll; 15 | 16 | ll bit[MAX]; 17 | 18 | ll query(int indx){ 19 | ll sum = 0; 20 | while (indx) { 21 | sum += bit[indx]; 22 | indx -= (indx & -indx); 23 | } 24 | return sum; 25 | } 26 | 27 | void update(ll indx, ll x){ 28 | while (indx < MAX) { 29 | bit[indx] += x; 30 | indx += (indx & -indx); 31 | } 32 | } 33 | 34 | int statquery(int k){ 35 | int low = 0, high = MAX-1, ans = 0; 36 | while (low <= high) { 37 | int mid = low + ((high - low)>>1); 38 | int qr = query(mid); 39 | if (qr >= k) {ans = mid, high = mid - 1;} 40 | else if (qr < k) low = mid + 1; 41 | } 42 | return ans; 43 | } 44 | 45 | int main() { 46 | int n; 47 | scanf("%d", &n); 48 | for (int i = 0; i < n; i++) { 49 | char choice[2]; 50 | scanf("%s", &choice); 51 | if (choice[0]=='i') { 52 | int value; 53 | scanf("%d", &value); 54 | assert(value >= 1); 55 | update(value, 1); 56 | } else { 57 | int k; 58 | scanf("%d", &k); 59 | printf("%d\n", statquery(k)); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/binary_indexed_tree_range_query_range_update.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | const int MOD = 1000000000+7; 7 | const int INF = 1000000000+5; 8 | 9 | /** 10 | * Description: BIT RURQ (Support range queries and range updates of 1-D array) 11 | * Usage: query O(lg(N)), update O(lg(N)) 12 | * Source: https://github.com/dragonslayerx 13 | * Note: Use 1-based indexing 14 | */ 15 | 16 | // Remember to use 1 based indexing 17 | class BIT { 18 | static const int MAX = 100005; 19 | public: 20 | static long long query(long long *bit, int indx) 21 | { 22 | long long sum = 0; 23 | while (indx) { 24 | sum += bit[indx]; 25 | indx -= (indx & -indx); 26 | } 27 | return sum; 28 | } 29 | 30 | static void update(long long *bit, int indx, long long x) 31 | { 32 | while (indx < MAX) { 33 | bit[indx] += x; 34 | indx += (indx & -indx); 35 | } 36 | } 37 | }; 38 | 39 | class BitRPRQ { 40 | static const int MAX = 100005; 41 | long long B1[MAX]; 42 | long long B2[MAX]; 43 | 44 | public: 45 | BitRPRQ() { 46 | memset(B1, 0, sizeof(B1)); 47 | memset(B2, 0, sizeof(B2)); 48 | } 49 | 50 | long long Rquery(int p){ 51 | long long tempB1 = BIT::query(B1, p); 52 | long long tempB2 = BIT::query(B2, p); 53 | long long sum = tempB1 * p + tempB2; 54 | return sum; 55 | } 56 | 57 | long long Rupdate(int l, int r, long long v){ 58 | BIT::update(B1, l, v); 59 | BIT::update(B1, r+1, -v); 60 | BIT::update(B2, l, -((l-1)*v)); 61 | BIT::update(B2, r+1, r*v); 62 | } 63 | }; 64 | 65 | int main() { 66 | int t; 67 | scanf("%d", &t); 68 | while (t--) { 69 | int n, q; 70 | scanf("%d%d", &n, &q); 71 | BitRPRQ B; 72 | while (q--) { 73 | int choice; 74 | scanf("%d", &choice); 75 | int p, q; 76 | long long v; 77 | scanf("%d%d", &p, &q); 78 | if (choice==0) { 79 | long long v; 80 | scanf("%lld", &v); 81 | B.Rupdate(p, q, v); 82 | } else { 83 | long long Answer = B.Rquery(q)-B.Rquery(p-1); 84 | printf("%lld\n", Answer); 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/binary_trie_max_xor.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Max Xor queries : Find maximum xor of an integer with a set of integers 3 | * Usage: insert O(lg(N)), erase O(lg(N)), maximize O(lg(N)) 4 | * Assumption: range of elements should be less than 2^45 5 | * Source: https://github.com/dragonslayerx 6 | */ 7 | 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | int size=0; 13 | struct node { 14 | node *left; 15 | node *right; 16 | int count; 17 | node() { 18 | left = right = NULL; 19 | count = 0; 20 | } 21 | } pool[5000005]; 22 | 23 | class Trie { 24 | #define MAXB 45 25 | node *root; 26 | Trie() { 27 | root = &pool[size++]; 28 | } 29 | 30 | node* create_new_node(){ 31 | node *t = &pool[size++]; 32 | return t; 33 | } 34 | 35 | void tostring(char *s, long long x){ 36 | int i; 37 | long long j; 38 | for (j = 1LL << MAXB, i = 0; j > 0; j >>= 1, i++) { 39 | s[i] = ((x & j) != 0) + '0'; 40 | } 41 | s[i] = '\0'; 42 | } 43 | 44 | void insert_trie(char *s){ 45 | node *t = root; 46 | for (int i = 0; s[i]; i++) { 47 | if (s[i] == '0') { 48 | if (t->left == NULL) { 49 | t->left = create_new_node(); 50 | } 51 | t = t->left; 52 | } else { 53 | if (t->right == NULL) { 54 | t->right = create_new_node(); 55 | } 56 | t = t->right; 57 | } 58 | t->count++; 59 | } 60 | } 61 | 62 | void erase_trie(char *s){ 63 | node *t = root; 64 | for (int i = 0; s[i]; i++) { 65 | if (s[i] == '0') { 66 | t = t->left; 67 | } else { 68 | t = t->right; 69 | } 70 | t->count--; 71 | } 72 | } 73 | 74 | public: 75 | long long maximize(long long x){ 76 | char s[50]; 77 | tostring(s, x); 78 | long long answer = 0; 79 | node *t = root; 80 | for (int i = 0; s[i]; i++) { 81 | answer <<= 1; 82 | if (s[i] == '0') { 83 | if (t->right == NULL || (t->right->count==0)) { 84 | t = t->left; 85 | } else { 86 | t = t->right; 87 | answer |= 1; 88 | } 89 | } else { 90 | if (t->left == NULL || (t->left->count==0)) { 91 | t = t->right; 92 | } else { 93 | t = t->left; 94 | answer |= 1; 95 | } 96 | } 97 | } 98 | return answer; 99 | } 100 | 101 | void insert(long long x){ 102 | char s[50]; 103 | tostring(s, x); 104 | insert_trie(s); 105 | } 106 | 107 | void erase(long long x) { 108 | char s[50]; 109 | tostring(s, x); 110 | erase_trie(s); 111 | } 112 | }; 113 | 114 | int main() { 115 | } 116 | -------------------------------------------------------------------------------- /src/bitmask.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Bitmask (Support set, unset and get bit operation) 3 | * Usage: set O(1), unset O(1), get O(1) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | class Bitmask { 8 | int mask; 9 | public: 10 | Bitmask() { 11 | mask = 0; 12 | } 13 | void set(int i) { 14 | mask |= (1 << i); 15 | } 16 | void unset(int i) { 17 | mask &= ~(1 << i); 18 | } 19 | int get(int i) { 20 | return (mask & (1 << i)); 21 | } 22 | const int operator [](int i) { 23 | return get(i); 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /src/bridges_in_graph.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description : Bridges (Find bridges in a graph) 3 | * Usage: See below O(V) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | using namespace std; 14 | 15 | #define INVALID_NUMBER -1 16 | #define INVALID_EDGE -1 17 | 18 | typedef vector > > graph; 19 | 20 | 21 | vector bridges; 22 | vector low; 23 | vector dfsNumbers; 24 | graph G; 25 | 26 | void calculateBridges(int currentNode, int &time, int parentEdge=INVALID_EDGE) { 27 | if(dfsNumbers[currentNode]==INVALID_NUMBER) 28 | { 29 | dfsNumbers[currentNode]=low[currentNode]=(++time); 30 | for(list >::const_iterator i=G[currentNode].begin();i!=G[currentNode].end();i++) 31 | { 32 | int currentEdge=i->second; 33 | if(currentEdge!=parentEdge){ 34 | int destination = i->first; 35 | calculateBridges(destination, time, currentEdge); 36 | if(low[destination]>dfsNumbers[currentNode]) { 37 | bridges.push_back(currentEdge); 38 | } 39 | low[currentNode]=min(low[currentNode],low[destination]); 40 | } 41 | } 42 | } 43 | } 44 | 45 | 46 | bool isVisited[100005]; 47 | int dfs(vector > &G, int u){ 48 | isVisited[u] = 1; 49 | int members = 1; 50 | for (int i = 0; i < G[u].size(); i++) { 51 | if (!isVisited[G[u][i]]) { 52 | members += dfs(G, G[u][i]); 53 | } 54 | } 55 | return members; 56 | } 57 | 58 | int main(){ 59 | ios::sync_with_stdio(false); 60 | 61 | int n,m; 62 | cin>>n>>m; 63 | 64 | low.resize(n); 65 | dfsNumbers.resize(n,INVALID_NUMBER); 66 | 67 | vector > edges; 68 | vector > Td(n); 69 | 70 | G.resize(n); 71 | for(int i=0;i>a>>b; 74 | a--, b--; 75 | edges.push_back(make_pair(a, b)); 76 | 77 | G[a].push_back(make_pair(b,i)); 78 | G[b].push_back(make_pair(a,i)); 79 | } 80 | 81 | bridges.reserve(m); 82 | int initialTime = 0; 83 | for(int i=0;i 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | int main() { 15 | int n; 16 | cin >> n; 17 | vector a(n); 18 | for (int i = 0; i < n; i++) { 19 | cin >> a[i]; 20 | } 21 | 22 | const int max = 100005; 23 | int after[max], before[max]; 24 | stack > S, T; 25 | for (int i = 0; i < n; i++) { 26 | while (!S.empty() && (S.top().first <= a[i])) S.pop(); 27 | if (S.empty()) { 28 | before[i] = -1; 29 | } else { 30 | before[i] = S.top().second; 31 | } 32 | S.push(make_pair(a[i], i)); 33 | } 34 | 35 | for (int i = n-1; i >= 0; i--) { 36 | while (!T.empty() && (T.top().first <= a[i])) T.pop(); 37 | if (T.empty()) { 38 | after[i] = n; 39 | } else { 40 | after[i] = T.top().second; 41 | } 42 | T.push(make_pair(a[i], i)); 43 | } 44 | 45 | cout << "Before:" << endl; 46 | for (int i = 0; i < n; i++) { 47 | cout << before[i] << " "; 48 | } 49 | cout << endl; 50 | 51 | cout << "After:" << endl; 52 | for (int i = 0; i < n; i++) { 53 | cout << after[i] << " "; 54 | } 55 | cout << endl; 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/connected_component_in_graph.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description : Connected Components (Find the connected components in graph) 3 | * Usage: dfs O(V) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | const int MAX = 100005; 8 | 9 | bool isVisited[MAX]; 10 | vector > G; 11 | vector col; 12 | vector components[MAX]; 13 | 14 | int dfs(int u, int color){ 15 | isvisited[u] = 1; 16 | col[u] = color; 17 | components[color].push_back(u); 18 | int members = 1; 19 | for (int i = 0; i < G[u].size(); i++) { 20 | if (!isvisited[G[u][i]]) { 21 | members += dfs(G[u][i], color); 22 | } 23 | } 24 | return members; 25 | } 26 | 27 | memset(isVisited, 0, sizeof(isVisited)); 28 | int size=0; 29 | for (int i = 0; i < n; i++) { 30 | if (!isVisited[i]) { 31 | dfs(i, size); 32 | size++; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/convexhull.cpp: -------------------------------------------------------------------------------- 1 | /// A C++ program to find convex hull of a set of points. 2 | #include 3 | using namespace std; 4 | 5 | class Point 6 | { 7 | public: 8 | int x, y; 9 | }; 10 | 11 | int find_orientation(Point p, Point q, Point r) 12 | { 13 | int val = (q.y - p.y) * (r.x - q.x) - 14 | (q.x - p.x) * (r.y - q.y); 15 | 16 | if (val == 0) return 0; 17 | return (val > 0)? 1: 2; 18 | } 19 | 20 | void convexHull(Point points[], int n) 21 | { 22 | if (n < 3) return; 23 | vector hull; 24 | int l = 0; 25 | for (int i = 1; i < n; i++) 26 | if (points[i].x < points[l].x) 27 | l = i; 28 | int p = l, q; 29 | do 30 | { 31 | hull.push_back(points[p]); 32 | q = (p+1)%n; 33 | for (int i = 0; i < n; i++) 34 | { 35 | if (find_orientation(points[p], points[i], points[q]) == 2) 36 | q = i; 37 | } 38 | p = q; 39 | 40 | } while (p != l); 41 | for (int i = 0; i < hull.size(); i++) 42 | cout << "(" << hull[i].x << ", " 43 | << hull[i].y << ")\n"; 44 | } 45 | 46 | int main() 47 | { 48 | Point points[] = {{0, 3}, {2, 2}, {1, 1}, {2, 1}, 49 | {3, 0}, {0, 0}, {3, 3}}; 50 | int n = sizeof(points)/sizeof(points[0]); 51 | convexHull(points, n); 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /src/cycle_detection_in_graph.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Cycle Detection (Detects a cycle in a directed or undirected graph.) 3 | * Usage: O(V) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | const int MAX = 100005; 14 | 15 | enum Color { 16 | gray, white, black 17 | }; 18 | 19 | typedef vector< vector > Graph; 20 | bool detectCycle(Graph &G, bool isUndirected) 21 | { 22 | Color isVisited[MAX] = {white}; 23 | int parent[MAX]; 24 | stack S; 25 | for (int i = 0; i < G.size(); i++) { 26 | if (isVisited[i] == black) continue; 27 | S.push(i); 28 | while (!S.empty()) { 29 | int u = S.top(); 30 | S.pop(); 31 | if (isVisited[u] == gray) { 32 | isVisited[u] = black; 33 | } else { 34 | S.push(u); 35 | isVisited[u] = gray; 36 | for (int i = 0; i < G[u].size(); i++) { 37 | int v = G[u][i]; 38 | if (isVisited[v] == white) { 39 | parent[v] = u; 40 | S.push(v); 41 | } else if (isVisited[v] == gray and (!isUndirected or v != parent[u])) { 42 | return true; 43 | } 44 | } 45 | } 46 | } 47 | } 48 | } 49 | 50 | int main() { 51 | int v, e; 52 | cin >> v >> e; 53 | Graph G(v); 54 | for (int i = 0; i < e; i++) { 55 | int a, b; 56 | cin >> a >> b; 57 | a--, b--; 58 | G[a].push_back(b); 59 | } 60 | cout << detectCycle(G, false) << endl; 61 | } 62 | -------------------------------------------------------------------------------- /src/dijkstra_using_priority_queue.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Dijkstra (Find shortest path from single source) 3 | * Usage: dijkstra O((V + E) lg(V)) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | const int MAX = 100050; 7 | const int INF = 1e9; 8 | 9 | void dijkstra(vector< vector< pair > > &G, int vertexCount, int src, int dist[]){ 10 | priority_queue, vector >, greater > > pq; 11 | bool isvisited[MAX]; 12 | 13 | for (int i = 0; i < vertexCount; i++) { 14 | dist[i] = INF; 15 | isvisited[i] = false; 16 | } 17 | 18 | dist[src] = 0; 19 | pq.push(make_pair(0, src)); 20 | while (!pq.empty()){ 21 | pair tp = pq.top(); 22 | pq.pop(); 23 | int node = tp.second; 24 | int d = tp.first; 25 | if (!isvisited[node]) { 26 | isvisited[node] = true; 27 | for (int i = 0; i < G[node].size(); i++) { 28 | int v = G[node][i].first; 29 | int w = G[node][i].second; 30 | if (dist[v] > d + w) { 31 | dist[v] = d + w; 32 | pq.push(make_pair(dist[v], v)); 33 | } 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/dijsktra_dense_graphs.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Dijkstra (Find shortest path from single source in dense graph) 3 | * Usage: dijkstra O(V^2) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | const int MAX = 1005 8 | const int INF = 1e9 9 | 10 | void dijkstra(int v, int source, int path_estimate[], int W[][MAX]) { 11 | bool isvisited[MAX]; 12 | for (int i = 0; i < v; i++) { 13 | isvisited[i] = false; 14 | path_estimate[i] = INF; 15 | } 16 | 17 | path_estimate[source] = 0; 18 | for (int i = 0; i < v; i++) { 19 | int mindist = INF, vertex; 20 | for (int j = 0; j < v; j++) { 21 | if (!isvisited[j] && mindist > path_estimate[j]) { 22 | mindist = path_estimate[j]; 23 | vertex = j; 24 | } 25 | } 26 | isvisited[vertex] = true; 27 | for (int i = 0; i < v; i++) { 28 | if (!isvisited[i]) { 29 | if (path_estimate[i] > path_estimate[vertex] + W[vertex][i]) { 30 | path_estimate[i] = path_estimate[vertex] + W[vertex][i]; 31 | } 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/disjoint_set.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Disjoint Set. 3 | * Usage: See below O(lg(N)) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | class Disjoint_Set { 14 | private: 15 | vector P; 16 | vector rank; 17 | public: 18 | Disjoint_Set(int n){ 19 | P.resize(n); 20 | rank.resize(n); 21 | for (int i = 0; i < n; i++) { 22 | P[i] = i; 23 | } 24 | } 25 | 26 | void merge(int node_x, int node_y){ 27 | int rep_x = find(node_x); 28 | int rep_y = find(node_y); 29 | if (rank[rep_x] > rank[rep_y]) { 30 | P[rep_y] = rep_x; 31 | } else { 32 | P[rep_x] = rep_y; 33 | if (rank[rep_x] == rank[rep_y]){ 34 | rank[rep_y]++; 35 | } 36 | } 37 | } 38 | 39 | int find(int node){ 40 | while (node != P[node]) { 41 | node = P[node]; 42 | } 43 | return node; 44 | } 45 | }; 46 | -------------------------------------------------------------------------------- /src/disjoint_set_with_undo_operation.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description : DisjointSet (Makes a set of sets, merge sets, set membership, no. of sets, undo last operation) 3 | * Usage: find O(lg(N)), merge O(lg(N)), undo O(1), getComponents O(1) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | class DisjointSet { 8 | const static int MAX = 100005; 9 | 10 | int parent[MAX], rank[MAX]; 11 | int components; 12 | vector O; 13 | public: 14 | DisjointSet(int n) { 15 | components=n; 16 | for (int i = 0; i < n; i++) { 17 | parent[i] = i; 18 | rank[i]=1; 19 | } 20 | } 21 | 22 | int find(int u) { 23 | while (u != parent[u]) { 24 | u = parent[u]; 25 | } 26 | return u; 27 | } 28 | 29 | void merge(int a, int b) { 30 | int parentA = find(a), parentB = find(b); 31 | if (parentA == parentB) { 32 | O.push_back(-1); 33 | } else { 34 | if (rank[parentA] > rank[parentB]) { 35 | parent[parentB] = parentA; 36 | O.push_back(parentB); 37 | } else { 38 | parent[parentA] = parentB; 39 | O.push_back(parentA); 40 | if (rank[parentA]==rank[parentB]) { 41 | rank[parentB]++; 42 | } 43 | } 44 | components--; 45 | } 46 | } 47 | 48 | int getComponents() { 49 | return components; 50 | } 51 | 52 | void undo() { 53 | assert(!O.empty()); 54 | int delta = O.back(); 55 | O.pop_back(); 56 | if (delta!=-1) { 57 | parent[delta]=delta; 58 | components++; 59 | } 60 | } 61 | }; -------------------------------------------------------------------------------- /src/dynamic_programming_templates.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Dp, Digit-DP, Binary Exponentiation DP templates. 3 | * Source: https://github.com/dragonslayerx 4 | */ 5 | 6 | long long dp[][]; 7 | bool exist[][]; 8 | 9 | long long solve(){ 10 | if () { 11 | return; 12 | } 13 | if(!exist[][]){ 14 | long long answer = 0; 15 | 16 | dp[][] = answer; 17 | exist[][] = true; 18 | } 19 | return dp[][]; 20 | } 21 | 22 | /** 23 | * Description: Digit DP 24 | */ 25 | 26 | template string toString(T value){ 27 | string s; 28 | while (value) { 29 | s.push_back(value % 10 + '0'); 30 | value /= 10; 31 | } 32 | s.push_back('0'); 33 | reverse(s.begin(), s.end()); 34 | return s; 35 | } 36 | 37 | bool exist[][][]; 38 | long long dp[][][]; 39 | 40 | long long solve(const string &s, int digit, bool bound, ){ 41 | if (digit == s.size()) { 42 | return; 43 | } 44 | if (!exist[digit][bound][]) { 45 | int maxDigit = (bound)? s[digit]-'0': 9; 46 | long long answer = 0; 47 | for (int i = 0; i <= maxDigit; i++) { 48 | int newBound = (bound && ((s[digit] - '0') == i)); 49 | answer += solve(s, digit+1, newBound, ); 50 | } 51 | dp[digit][bound][]= answer; 52 | exist[digit][bound][] = true; 53 | } 54 | return dp[digit][bound][]; 55 | } 56 | 57 | /** 58 | * Description: Binary exponentiation DP (Non standard) 59 | * Note: Most of the same target problems can be solved through matrix exponentiation. 60 | * It helped me once doing a Div2-E (http://codeforces.com/problemset/problem/621/E) 61 | */ 62 | 63 | long long dp[105][105] = {}; 64 | 65 | const int maxl = 40; 66 | for (int i = 1; i <= maxl; i++) { 67 | for (int j1 = 0; j1 < x; j1++) { 68 | for (int j2 = 0; j2 < x; j2++) { 69 | ll l = 1LL<<(i-1); 70 | int newmod = (j1 * power(10, l, x) + j2) % x; 71 | dp[i][newmod] += (dp[i-1][j1] * dp[i-1][j2]) % MOD; 72 | dp[i][newmod] %= MOD; 73 | } 74 | } 75 | } 76 | 77 | long long ways[2][105] = {}; 78 | bool flag = true; 79 | int current = 0, prev = 1; 80 | for (int i = 0; i <= maxl; i++) { 81 | if (b & (1LL<= 0; i--) { 111 | if (x & (1LL << i)) A.push_back('1'); 112 | else A.push_back('0'); 113 | } 114 | return A; 115 | } 116 | 117 | string A, B, C; 118 | bool exist[105][2][2][2]; 119 | long long dp[105][2][2][2]; 120 | 121 | long long solve(int idx, bool b1, bool b2, bool b3){ 122 | if (idx == 64) { 123 | return 1; 124 | } 125 | if (!exist[idx][b1][b2][b3]) { 126 | int max1 = 1, max2 = 1; 127 | if (b1) max1 = A[idx] - '0'; 128 | if (b2) max2 = B[idx] - '0'; 129 | long long answer = 0; 130 | for (int i = 0; i <= max1; i++) { 131 | for (int j = 0; j <= max2; j++) { 132 | int result_bit = (i ^ j); // Expression here 133 | int nb1 = b1 && ((A[idx] - '0') == i); 134 | int nb2 = b2 && ((B[idx] - '0') == j); 135 | int nb3 = (b3 && (result_bit == (D[idx] - '0'))); 136 | if (b3) { 137 | if (result_bit <= D[idx] - '0') answer += solve(idx+1, nb1, nb2, nb3); 138 | } else { 139 | answer += solve(idx+1, nb1, nb2, nb3); 140 | } 141 | if (answer >= MOD) answer -= MOD; 142 | } 143 | } 144 | } 145 | exist[idx][b1][b2][b3] = true; 146 | dp[idx][b1][b2][b3] = answer; 147 | } 148 | return dp[idx][b1][b2][b3]; 149 | } 150 | 151 | int main(){ 152 | long long a, b, c; 153 | scanf("%lld%lld%lld", &a, &b, &c); 154 | A = toBinaryString(a); B = toBinaryString(b); C = toBinaryString(c); 155 | printf("%lld\n", solve(0, true, true, true, true)); 156 | } 157 | -------------------------------------------------------------------------------- /src/dynamic_string_using_treap.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Dynamic strings (Support for insert, delete of substring at arbitary position in a string) 3 | * Usage: insert_substring, remove_substring, get_substring O(lg(N)) per character 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | struct { 14 | int tree_size; // Size of the subtree rooted at node 15 | int p; // Priority of node 16 | char val; // Value of node 17 | node *left, *right; 18 | }; 19 | 20 | class Treap { 21 | node *root; 22 | 23 | int get_size(node *subtree_root){ 24 | if (subtree_root == NULL) return 0; 25 | else return subtree_root->tree_size; 26 | } 27 | 28 | node* left_rotate(node *y, node *x){ 29 | int a_size = get_size(y->left); 30 | int b_size = get_size(x->left); 31 | int c_size = get_size(x->right); 32 | 33 | x->tree_size = c_size + a_size + b_size + 2; 34 | y->tree_size = a_size + b_size + 1; 35 | 36 | node *b = x->left; 37 | x->left = y; 38 | y->right = b; 39 | return x; 40 | } 41 | 42 | node* right_rotate(node *x, node *y){ 43 | int a_size = get_size(y->left); 44 | int b_size = get_size(y->right); 45 | int c_size = get_size(x->right); 46 | 47 | y->tree_size = c_size + a_size + b_size + 2; 48 | x->tree_size = b_size + c_size + 1; 49 | 50 | node *b = y->right; 51 | y->right = x; 52 | x->left = b; 53 | return y; 54 | } 55 | 56 | node *merge(node *left_treap, node *right_treap){ 57 | if (left_treap == NULL) return right_treap; 58 | if (right_treap== NULL) return left_treap; 59 | if (left_treap->p < right_treap->p) { 60 | left_treap->tree_size += get_size(right_treap); 61 | left_treap->right = merge(left_treap->right, right_treap); 62 | return left_treap; 63 | } else { 64 | right_treap->tree_size += get_size(left_treap); 65 | right_treap->left = merge(right_treap->left, left_treap); 66 | return right_treap; 67 | } 68 | } 69 | 70 | node* _insert(node *subtree_root, int pos, node *new_node) 71 | { 72 | if (subtree_root == NULL) return new_node; 73 | subtree_root->tree_size += 1; 74 | if (pos <= get_size(subtree_root->left)) { 75 | subtree_root->left = _insert(subtree_root->left, pos, new_node); 76 | if (subtree_root->p > subtree_root->left->p) { 77 | return right_rotate(subtree_root, subtree_root->left); 78 | } 79 | } else { 80 | pos -= get_size(subtree_root->left) + 1; 81 | subtree_root->right = _insert(subtree_root->right, pos, new_node); 82 | if (subtree_root->p > subtree_root->right->p) { 83 | return left_rotate(subtree_root, subtree_root->right); 84 | } 85 | } 86 | return subtree_root; 87 | } 88 | 89 | char _get_node(node *subtree_root, int pos) 90 | { 91 | if (pos >= subtree_root->tree_size) return '#'; 92 | if (pos == get_size(subtree_root->left)) 93 | return subtree_root->val; 94 | if (pos < get_size(subtree_root->left)) { 95 | return _get_node(subtree_root->left, pos); 96 | } else { 97 | pos = pos - get_size(subtree_root->left) - 1; 98 | return _get_node(subtree_root->right, pos); 99 | } 100 | } 101 | 102 | node* _erase(node *subtree_root, int pos){ 103 | if (pos >= subtree_root->tree_size) return subtree_root; 104 | if (pos == get_size(subtree_root->left)) { 105 | return merge(subtree_root->left, subtree_root->right); 106 | } 107 | subtree_root->tree_size -= 1; 108 | if (pos < get_size(subtree_root->left)) { 109 | subtree_root->left = _erase(subtree_root->left, pos); 110 | } else { 111 | pos = pos - get_size(subtree_root->left) - 1; 112 | subtree_root->right = _erase(subtree_root->right, pos); 113 | } 114 | return subtree_root; 115 | } 116 | 117 | pair split(node *subtree_root, int pos){ 118 | node* new_node = (node*) malloc(sizeof(node)); 119 | new_node->val = '#'; 120 | new_node->p = -1; 121 | new_node->left = new_node->right = NULL; 122 | root = _insert(subtree_root, pos, new_node); 123 | return make_pair(root->left, root->right); 124 | } 125 | 126 | int get_random(){ 127 | return rand() * rand(); 128 | } 129 | 130 | void _inorder(node *subtree_root){ 131 | if (subtree_root == NULL) return; 132 | _inorder(subtree_root->left); 133 | cout << subtree_root->val; 134 | _inorder(subtree_root->right); 135 | } 136 | 137 | 138 | public: 139 | Treap(){ 140 | root = NULL; 141 | } 142 | 143 | void insert(int pos, char val){ 144 | node *new_node = (node*)malloc(sizeof(node)); 145 | new_node->val = val; 146 | new_node->tree_size = 1; 147 | new_node->p = get_random(); 148 | new_node->left = new_node->right = NULL; 149 | root = _insert(root, pos, new_node); 150 | } 151 | 152 | void erase(int pos){ 153 | root = _erase(root, pos); 154 | } 155 | 156 | void remove_substring(int pos, int length){ 157 | pair A = split(root, pos); 158 | pair B = split(A.second, length); 159 | root = merge(A.first, B.second); 160 | } 161 | 162 | void insert_substring(int pos, char *s){ 163 | int n = strlen(s); 164 | for (int i = 0; i < n; i++) { 165 | insert(pos, s[i]); 166 | pos++; 167 | } 168 | } 169 | 170 | string get_substring(int pos, int len){ 171 | string tmp; 172 | for (int i = pos; i < pos+len; i++) { 173 | tmp.push_back(get_node(i)); 174 | } 175 | return tmp; 176 | } 177 | 178 | char get_node(int pos){ 179 | return _get_node(root, pos); 180 | } 181 | 182 | void inorder(){ 183 | _inorder(root); 184 | } 185 | }; 186 | 187 | char a[300005]; 188 | 189 | int main() 190 | { 191 | Treap T; 192 | int q; 193 | scanf("%d", &q); 194 | while (q--) { 195 | int pos; 196 | char choice[5]; 197 | scanf("%s%d", choice, &pos); 198 | if (choice[0] == '+') { 199 | scanf("%s", a); 200 | T.insert_substring(pos, a); 201 | } else { 202 | pos--; 203 | int len; 204 | scanf("%d", &len); 205 | printf("%s\n", T.get_substring(pos, len).c_str()); 206 | } 207 | } 208 | } 209 | -------------------------------------------------------------------------------- /src/edit_distance_levenstein_dynamic_programming.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Edit distance (Find the levenstein distance between two strings) 3 | * Usage: solve O(NM) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | int d[2][1005]; 8 | int solve(string &s, string &t){ 9 | int prev = 0, current = 1; 10 | for (int i = 0; i <= s.size(); i++){ 11 | for (int j = 0; j <= t.size(); j++){ 12 | if (i == 0) d[current][j]=j; 13 | else if (j == 0) d[current][j]=i; 14 | else { 15 | d[current][j] = min(d[prev][j]+1, d[current][j-1]+1); 16 | if (s[i-1]==t[j-1]) { 17 | d[current][j] = min(d[current][j], d[prev][j-1]); 18 | } else { 19 | d[current][j] = min(d[current][j], d[prev][j-1]+1); 20 | } 21 | } 22 | } 23 | swap(prev, current); 24 | } 25 | return d[prev][t.size()]; 26 | } 27 | -------------------------------------------------------------------------------- /src/euler_phi_euler_totient_function.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Euler Totient function 3 | * Usage: See below 4 | * Note: The code is taken from http://www.geeksforgeeks.org/eulers-totient-function/ 5 | * Source: https://github.com/dragonslayerx 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | vector isprime; 15 | vector primes; 16 | 17 | void sieve(int n){ 18 | isprime.resize(n, 1); 19 | for (int i = 2; i < n; i++) { 20 | if (isprime[i]) { 21 | for (int j = 2; i*j < n; j++) { 22 | isprime[i*j] = 0; 23 | } 24 | } 25 | } 26 | for (int i = 2; i < n; i++) 27 | if (isprime[i])primes.push_back(i); 28 | } 29 | 30 | int phi(const int n){ 31 | if ( n < 2 ) 32 | return 0; 33 | if (isprime[n] ) 34 | return n-1; 35 | if ( n & 1 == 0 ) { 36 | int m = n >> 1; 37 | return !(m & 1) ? phi(m)<<1 : phi(m); 38 | } 39 | for ( std::vector::iterator p = primes.begin(); p != primes.end() && *p <= n; ++p ){ 40 | int m = *p; 41 | if ( n % m ) continue; 42 | 43 | // phi is multiplicative 44 | int o = n/m; 45 | int d = __gcd(m, o); 46 | return d==1? phi(m)*phi(o) : phi(m)*phi(o)*d/phi(d); 47 | } 48 | } 49 | 50 | int main() 51 | { 52 | sieve(1000005); 53 | vector ephi(1000005); 54 | for (int i = 1; i <= 1000005; i++) 55 | ephi[i] = phi(i); 56 | 57 | ios::sync_with_stdio(false); 58 | int t; 59 | cin >> t; 60 | while (t--) { 61 | int n, m; 62 | cin >> n >> m; 63 | if (m > n) {cout << 0 << endl; continue;} 64 | int k = n/m; 65 | long long answer = 0; 66 | for (int i = 1; i <= k; i++) { 67 | answer += ephi[i]; 68 | } 69 | cout << answer + 1 << endl; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/factorial_preprocessing.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Preprocessing for finding factorial and inverse factorial. Support efficient binomial coefficient, Catalan no. calculation. 3 | * Complexity: initfact O(N), 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | 8 | #define MOD 1000000007 9 | #define MAX 2000010 10 | long long fact[MAX]; 11 | long long ifact[MAX]; 12 | long long power(long long n,int m){ 13 | if(m==0) return 1; 14 | long long x=power(n,m/2); 15 | if(m%2==0) return (x*x)%MOD; 16 | else return (((x*x)%MOD)*n)%MOD; 17 | } 18 | 19 | void initfact(int n,long long fact[],long long ifact[]){ 20 | int i; 21 | fact[0]=1; 22 | for(i=1;i<=n;i++) 23 | fact[i] = i*fact[i-1]%MOD; 24 | ifact[n] = power(fact[n],MOD-2); 25 | for(i=n;i>0;i--) 26 | ifact[i-1] = ifact[i]*i%MOD; 27 | } 28 | 29 | #define C(n, r) ((((fact[n]*ifact[r])%MOD)*ifact[n - r])%MOD) 30 | #define Catalan(n) ((((fact[2*n]*ifact[n])%MOD)*ifact[n+1])%MOD) 31 | -------------------------------------------------------------------------------- /src/fast_fourier_transform_fft.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: FFT (Fast Fourier Transform for fast polynomail multiplication) 3 | * Usage: multiply O(N) 4 | * Note: The code is taken from http://e-maxx.ru/algo/fft_multiply 5 | * Source: https://github.com/dragonslayerx 6 | */ 7 | 8 | //taken from e-maxx.ru 9 | typedef complex base; 10 | 11 | void fft (vector & a, bool invert) { 12 | int n = (int) a.size(); 13 | 14 | for (int i=1, j=0; i> 1; 16 | for (; j>=bit; bit>>=1) 17 | j -= bit; 18 | j += bit; 19 | if (i < j) 20 | swap (a[i], a[j]); 21 | } 22 | 23 | for (int len=2; len<=n; len<<=1) { 24 | double ang = 2*PI/len * (invert ? -1 : 1); 25 | base wlen (cos(ang), sin(ang)); 26 | for (int i=0; i & a, const vector & b, vector & res) { 44 | vector fa (a.begin(), a.end()), fb (b.begin(), b.end()); 45 | size_t n = 1; 46 | while (n < max (a.size(), b.size())) n <<= 1; 47 | n <<= 1; 48 | fa.resize (n), fb.resize (n); 49 | 50 | fft (fa, false), fft (fb, false); 51 | for (size_t i=0; i 17 | inline void readInt(T &n){ 18 | n = 0; 19 | bool flag=1; 20 | char c; 21 | int sign=1; 22 | while (1){ 23 | c = GETCHAR(); 24 | if(c=='-') sign=-1; 25 | else if(c>='0'&&c<='9') {n = n * 10 + c - '0';flag=0;} 26 | else if(flag!=1) break; 27 | } 28 | n *= sign; 29 | } 30 | 31 | 32 | template 33 | inline void writeInt(T x) { 34 | bool sign = false; 35 | if (x < 0) { 36 | x = -x; 37 | } 38 | bool flag = false; 39 | char buf[20]; 40 | int i = 0; 41 | while (x > 0) { 42 | flag = true; 43 | buf[i++] = x % 10 + '0'; 44 | x /= 10; 45 | } 46 | if (flag) { 47 | if (sign) PUTCHAR('-'); 48 | i--; 49 | for (; i >=0; i--) { 50 | PUTCHAR(buf[i]); 51 | } 52 | } else { 53 | PUTCHAR('0'); 54 | } 55 | } -------------------------------------------------------------------------------- /src/generate_all_palindromes.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | /** 7 | * Description: Generate all palindromes haing 'numDigits' digits 8 | * Usage: generatePalindromes 9 | * Source: https://github.com/dragonslayerx 10 | */ 11 | 12 | long long toInt(string x){ 13 | long long sum = 0; 14 | for (int i = 0; i < x.size(); i++) { 15 | sum *= 10; 16 | sum += (x[i]-'0'); 17 | } 18 | return sum; 19 | } 20 | 21 | void fillDigits(int begin, int end, string&s, vector &palindrome){ 22 | if (begin > end) { 23 | string t = s; 24 | reverse(t.begin(), t.end()); 25 | if (s[0] != '0') { 26 | palindrome.push_back(toInt(s + t)); 27 | } 28 | } else if (begin == end) { 29 | string t = s; 30 | reverse(t.begin(), t.end()); 31 | for (int i = 0; i <= 9; i++) { 32 | s.push_back(i + '0'); 33 | if (s[0] != '0') { 34 | palindrome.push_back(toInt(s + t)); 35 | } 36 | s.pop_back(); 37 | } 38 | } else { 39 | for (int i = 0; i <= 9; i++) { 40 | s.push_back(i + '0'); 41 | fillDigits(begin+1, end-1, s, palindrome); 42 | s.pop_back(); 43 | } 44 | } 45 | } 46 | 47 | vector generatePalindromes(int numDigits) { 48 | vector palindrome; 49 | string s; 50 | for (int i = 1; i <= numDigits; i++) { 51 | fillDigits(0, i-1, s, palindrome); 52 | } 53 | return palindrome; 54 | } 55 | 56 | int main() { 57 | vector palindromes = generatePalindromes(3); 58 | for (int i = 0; i < palindromes.size(); i++) { 59 | cout << palindromes[i] << ", "; 60 | } 61 | cout << endl; 62 | } 63 | -------------------------------------------------------------------------------- /src/heap_using_multiset_max_min_insert_erase_update.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: A MaxMin priority queue that supports erase operation. 3 | * Usage: insert O(lg(N)), erase O(lg(N)), maxElement O(lg(N)), minElement O(lg(N)) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | template 13 | class Heap { 14 | map lookup; 15 | multiset< pair > prQ; 16 | public: 17 | void insert(Tk key, Tv val) { 18 | lookup[key] = val; 19 | prQ.insert(make_pair(val, key)); 20 | } 21 | 22 | void update(Tk key, Tv val) { 23 | typename multiset::iterator it = prQ.find(make_pair(lookup[key], key)); 24 | prQ.erase(it); 25 | lookup[key] = val; 26 | prQ.insert(make_pair(val, key)); 27 | } 28 | 29 | void erase(Tk key) { 30 | typename multiset::iterator it = prQ.find(make_pair(lookup[key], key)); 31 | prQ.erase(it); 32 | lookup.erase(key); 33 | } 34 | 35 | pair maxElement() { 36 | return *prQ.rbegin(); 37 | } 38 | 39 | pair minElement() { 40 | return *prQ.begin(); 41 | } 42 | }; 43 | 44 | int main() { 45 | Heap H; 46 | H.insert(1, 5); 47 | H.insert(2, 4); 48 | H.insert(3, 9); 49 | H.insert(4, 7); 50 | cout << H.minElement().first << " " << H.minElement().second << endl; 51 | } 52 | -------------------------------------------------------------------------------- /src/heavy_light_decomposition_weighted_edges (hld).cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Heavy Light decomposition: Perform point updates and aggregate queries over path between two nodes in a tree in case edges are weighted 3 | * Complexity: O(lg^2(N)) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | using namespace std; 16 | 17 | 18 | const long long INF = 1000000000000000005LL; 19 | 20 | long long mul(long long a, long long b) { 21 | pair s, t, result; 22 | t.first = a / 1000000000; 23 | t.second = a % 1000000000; 24 | 25 | s.first = b / 1000000000; 26 | s.second = b % 1000000000; 27 | 28 | long long r1, r2, r3, r4; 29 | 30 | r1 = t.first * s.first; 31 | r2 = t.first * s.second; 32 | r3 = t.second * s.first; 33 | r4 = t.second * s.second; 34 | 35 | if (r1 && (r2 || r3 || r4)) return INF; 36 | else if ((r2 + r3) > 1000000000) return INF; 37 | else if ((r2 + r3)*1000000000 + r4 > INF) return INF; 38 | else return (r2 + r3)*1000000000 + r4; 39 | } 40 | 41 | class HLD 42 | { 43 | public: 44 | typedef vector > tree; 45 | private: 46 | tree &T; 47 | 48 | void doHLD(int cur=0) 49 | { 50 | chainNumber[cur]=chainSize.size()-1; 51 | chainPosition[cur]=chainSize.back(); 52 | chainSize.back()++; 53 | 54 | int maxTreeSize=numeric_limits::min(); 55 | int maxTreeSizeNode=-1; 56 | 57 | for(list::iterator i=T[cur].begin();i!=T[cur].end();i++) 58 | if(nodeLevel[*i]>nodeLevel[cur]) 59 | if(maxTreeSize::iterator i=T[cur].begin();i!=T[cur].end();i++) 70 | if(nodeLevel[*i]>nodeLevel[cur]) 71 | if(*i!=maxTreeSizeNode) 72 | { 73 | chainSize.push_back(0); 74 | chainHead.push_back(cur); 75 | doHLD(*i); 76 | } 77 | } 78 | 79 | void calculateTreeSize(int node) 80 | { 81 | treeSize[node]=1; 82 | for(list::iterator i=T[node].begin();i!=T[node].end();i++) 83 | { 84 | if(nodeLevel[*i]>nodeLevel[node]) 85 | { 86 | calculateTreeSize(*i); 87 | treeSize[node]+=treeSize[*i]; 88 | } 89 | } 90 | } 91 | 92 | public: 93 | vector chainHead; 94 | vector chainNumber; 95 | vector chainPosition; 96 | vector chainSize; 97 | vector nodeLevel; 98 | vector treeSize; 99 | HLD(tree &t,int start=0):T(t) 100 | { 101 | chainHead.reserve(T.size()); 102 | chainNumber.resize(T.size()); 103 | chainPosition.resize(T.size()); 104 | chainSize.reserve(T.size()); 105 | nodeLevel.resize(T.size(),-1); 106 | treeSize.resize(T.size()); 107 | 108 | 109 | chainSize.push_back(0); 110 | chainHead.push_back(-1); 111 | // bfs for finding the level of the node 112 | 113 | queue Q; 114 | nodeLevel[start]=0; 115 | Q.push(start); 116 | while(!Q.empty()) 117 | { 118 | int current=Q.front(); 119 | Q.pop(); 120 | for(list::iterator i=T[current].begin();i!=T[current].end();i++) 121 | { 122 | if(nodeLevel[*i]==-1) 123 | { 124 | nodeLevel[*i]=nodeLevel[current]+1; 125 | Q.push(*i); 126 | } 127 | } 128 | } 129 | 130 | // dfs 131 | calculateTreeSize(start); 132 | doHLD(start); 133 | } 134 | size_t chainCount() const 135 | { 136 | return chainSize.size(); 137 | } 138 | }; 139 | 140 | template class segmentTree 141 | { 142 | public: 143 | typedef T value_type; 144 | 145 | private: 146 | vector tree; 147 | MF mergeFunction; 148 | UN updateNode; 149 | size_t sz; 150 | 151 | bool inRange(size_t queryLeft,size_t queryRight,size_t nodeLeft,size_t nodeRight) const 152 | { 153 | if(nodeLeft > nodeRight || nodeLeft > queryRight || nodeRight < queryLeft) 154 | return false; 155 | return true; 156 | } 157 | 158 | size_t leftChild(size_t node) 159 | { 160 | return (node<<1)+1; 161 | } 162 | size_t rightChild(size_t node) 163 | { 164 | return (node<<1)+2; 165 | } 166 | 167 | void buildTree(const vector &A,size_t low,size_t high, size_t node) 168 | { 169 | 170 | if(low==high) 171 | tree[node]=A[low]; 172 | else if(low>high) 173 | return; 174 | else 175 | { 176 | buildTree(A,low,(low+high)/2,leftChild(node)); 177 | buildTree(A,(low+high)/2+1,high,rightChild(node)); 178 | tree[node]=mergeFunction(tree[leftChild(node)],tree[rightChild(node)]); 179 | } 180 | } 181 | 182 | value_type query(size_t queryLeft,size_t queryRight,size_t nodeLeft,size_t nodeRight,size_t node) 183 | { 184 | if(nodeLeft>=queryLeft&&nodeRight<=queryRight) 185 | return tree[node]; 186 | else 187 | { 188 | bool leftInRange=inRange(queryLeft,queryRight,nodeLeft,(nodeLeft+nodeRight)/2); 189 | bool rightInRange=inRange(queryLeft,queryRight,(nodeLeft+nodeRight)/2+1,nodeRight); 190 | 191 | if(leftInRange&&!rightInRange) 192 | return query(queryLeft,queryRight,nodeLeft,(nodeLeft+nodeRight)/2,leftChild(node)); 193 | 194 | else if(!leftInRange&&rightInRange) 195 | return query(queryLeft,queryRight,(nodeLeft+nodeRight)/2+1,nodeRight,rightChild(node)); 196 | 197 | else 198 | return mergeFunction(query(queryLeft,queryRight,nodeLeft,(nodeLeft+nodeRight)/2,leftChild(node)),query(queryLeft,queryRight,(nodeLeft+nodeRight)/2+1,nodeRight,rightChild(node))); 199 | } 200 | } 201 | 202 | void update(size_t queryLeft,size_t queryRight,size_t nodeLeft,size_t nodeRight,size_t node,value_type value) 203 | { 204 | if(!inRange(queryLeft,queryRight,nodeLeft,nodeRight)) 205 | return; 206 | 207 | if(nodeLeft==nodeRight) 208 | tree[node]=updateNode(tree[node],value); 209 | else 210 | { 211 | update(queryLeft,queryRight,nodeLeft,(nodeLeft+nodeRight)/2,leftChild(node),value); 212 | update(queryLeft,queryRight,(nodeLeft+nodeRight)/2+1,nodeRight,rightChild(node),value); 213 | 214 | tree[node]=mergeFunction(tree[leftChild(node)],tree[rightChild(node)]); 215 | } 216 | } 217 | 218 | public: 219 | segmentTree() 220 | { 221 | sz=0; 222 | } 223 | 224 | segmentTree(size_t size,value_type initial=value_type()) 225 | { 226 | assign(size,initial); 227 | } 228 | 229 | segmentTree(const vector &A) 230 | { 231 | clear(); 232 | assign(A); 233 | } 234 | 235 | void assign(size_t size,value_type initial=value_type()) 236 | { 237 | clear(); 238 | sz=size; 239 | tree.resize(4*size,initial); 240 | } 241 | 242 | void assign(const vector &A) // assumes vector to be 0 indexed 243 | { 244 | assign(A.size()); 245 | buildTree(A,0,A.size()-1,0); 246 | } 247 | 248 | void clear() 249 | { 250 | sz=0; 251 | tree.clear(); 252 | } 253 | 254 | void update(size_t pos,const value_type &value) 255 | { 256 | update(pos,pos,0,sz-1,0,value); 257 | } 258 | 259 | value_type query(size_t low,size_t high) 260 | { 261 | return query(low,high,0,sz-1,0); 262 | } 263 | ~segmentTree() 264 | { 265 | clear(); 266 | } 267 | }; 268 | struct updateNode 269 | { 270 | long long operator()(int node, long long newValue) 271 | { 272 | return newValue; 273 | } 274 | }; 275 | 276 | struct mergeNode 277 | { 278 | long long operator()(long long left, long long right) 279 | { 280 | return mul(left, right); 281 | } 282 | }; 283 | 284 | struct edge 285 | { 286 | int a,b; 287 | long long cost; 288 | }; 289 | 290 | template class rmq 291 | { 292 | private: 293 | vector > RMQ; 294 | public: 295 | rmq() 296 | { 297 | } 298 | rmq(vector &arr) 299 | { 300 | //------------------------------------------------ 301 | int n=arr.size(); 302 | RMQ.resize(n); 303 | int len=5+ceil(log(arr.size())); 304 | for(int i=0;i > tree; // change this according to your problem. 344 | private: 345 | tree &T; 346 | 347 | vector istraversed; 348 | vector level; 349 | vector position; 350 | vector > rmqArray; 351 | rmq > RMQ; 352 | 353 | void dfs(int source) 354 | { 355 | if(!istraversed[source]) 356 | { 357 | istraversed[source]=true; 358 | position[source]=rmqArray.size(); 359 | rmqArray.push_back(make_pair(level[source],source)); 360 | for(tree::value_type::iterator i=T[source].begin();i!=T[source].end();i++) 361 | { 362 | if(!istraversed[*i]) // vertex point here 363 | { 364 | dfs(*i); 365 | rmqArray.push_back(make_pair(level[source],source)); 366 | } 367 | } 368 | } 369 | } 370 | 371 | void bfs(int start) 372 | { 373 | queue Q; 374 | level[start]=0; 375 | Q.push(start); 376 | 377 | while(!Q.empty()) 378 | { 379 | int current=Q.front(); 380 | Q.pop(); 381 | for(tree::value_type::iterator i=T[current].begin();i!=T[current].end();i++) 382 | { 383 | if(level[*i]==-1) 384 | { 385 | level[*i]=level[current]+1; 386 | Q.push(*i); 387 | } 388 | } 389 | } 390 | } 391 | 392 | 393 | public: 394 | LCA(tree &t,int start=0):T(t) 395 | { 396 | level.resize(t.size(),-1); 397 | bfs(start); 398 | 399 | position.resize(t.size()); 400 | istraversed.resize(t.size()); 401 | rmqArray.reserve(t.size()); 402 | dfs(start); 403 | 404 | RMQ=rmq >(rmqArray); 405 | } 406 | 407 | int query(int nodeA,int nodeB) 408 | { 409 | return RMQ.query(min(position[nodeA],position[nodeB]),max(position[nodeA],position[nodeB])).second; 410 | } 411 | }; 412 | 413 | 414 | 415 | int main(){ 416 | // freopen("testQTREE.txt","r",stdin); 417 | // freopen("outQtree1.txt","w",stdout); 418 | 419 | ios_base::sync_with_stdio(false); 420 | 421 | int n, q; 422 | cin>>n >> q; 423 | 424 | vector E(n-1); 425 | HLD::tree T(n); 426 | 427 | for(int i=0;i>E[i].a>>E[i].b>>E[i].cost; 431 | E[i].a--; 432 | E[i].b--; 433 | T[E[i].a].push_back(E[i].b); 434 | T[E[i].b].push_back(E[i].a); 435 | } 436 | 437 | HLD hld(T); 438 | 439 | vector > ST(hld.chainCount()) ; 440 | 441 | for(int i=0;ihld.nodeLevel[E[i].b]?E[i].a:E[i].b); 447 | ST[hld.chainNumber[target]].update(hld.chainPosition[target],E[i].cost); 448 | } 449 | 450 | LCA lca(T,0); 451 | 452 | while(q--) 453 | { 454 | int choice; 455 | cin>>choice; 456 | if(choice==1) 457 | { 458 | int a,b; 459 | long long k; 460 | cin>>a>>b>>k; 461 | if(a==b) 462 | { 463 | cout<>i>>value; 501 | i--; 502 | int target=(hld.nodeLevel[E[i].a]>hld.nodeLevel[E[i].b]?E[i].a:E[i].b); 503 | ST[hld.chainNumber[target]].update(hld.chainPosition[target],value); 504 | } 505 | } 506 | } -------------------------------------------------------------------------------- /src/heavy_light_decomposition_wieghted_vertices(hld).cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Heavy Light Decomposition (Perform point updates and aggregate query over paths between two nodes in tree in case vertices are weighted) 3 | * Usage: update O(lg(N)), path_query O(lg^2(N)), See below for more details. 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | //----------Modifiable------ 16 | #define MAX 50050 17 | //-------------------------- 18 | #define INVALID -1 19 | 20 | bool isvisited[MAX]; 21 | 22 | int st_size[MAX]; // subtree_size 23 | int p[MAX]; // parent of node 24 | int lvl[MAX]; // level of node 25 | 26 | vector > G; 27 | 28 | int calc_size(int u, int level) 29 | { 30 | isvisited[u] = 1; 31 | lvl[u] = level; 32 | 33 | st_size[u] = 1; 34 | for (int i = 0; i < G[u].size(); i++) { 35 | int v = G[u][i]; 36 | if (!isvisited[v]) { 37 | p[v] = u; 38 | st_size[u] += calc_size(v, level+1); 39 | } 40 | } 41 | return st_size[u]; 42 | } 43 | 44 | int node[MAX]; 45 | int chain_head[MAX], chain_link[MAX], chain[MAX]; 46 | 47 | //----------Modifiable------ 48 | int chain_id = 0, node_id = 1; // change this as per requiremnt bit donot support 0 base indexing 49 | //-------------------------- 50 | 51 | int decompose(int u) 52 | { 53 | isvisited[u] = 1; 54 | 55 | chain[u] = chain_id; 56 | node[u] = node_id++; 57 | if (chain_head[chain_id] == INVALID) { 58 | chain_head[chain_id] = u; 59 | chain_link[chain_id] = p[u]; 60 | } 61 | 62 | int special_child = INVALID, max_subtree_size = 0; 63 | for (int i = 0; i < G[u].size(); i++) { 64 | int v = G[u][i]; 65 | if (!isvisited[v] && max_subtree_size < st_size[v]) { 66 | special_child = v; 67 | max_subtree_size = st_size[v]; 68 | } 69 | } 70 | if (special_child != INVALID) decompose(special_child); 71 | for (int i = 0; i < G[u].size(); i++) { 72 | int v = G[u][i]; 73 | if (!isvisited[v] && v != special_child) { 74 | chain_id++; 75 | decompose(v); 76 | } 77 | } 78 | } 79 | 80 | void hld_decompose(int root, int v) 81 | { 82 | chain_id = 0, node_id = 1; // change this as per requiremnt bit donot support 0 base indexing 83 | memset(isvisited, 0, sizeof(isvisited)); 84 | calc_size(root, 0); 85 | memset(isvisited, 0, sizeof(isvisited)); 86 | for (int i = 0; i < v; i++) { 87 | chain_head[i] = INVALID; 88 | chain_link[i] = INVALID; 89 | } 90 | decompose(root); 91 | } 92 | 93 | int lca(int v1, int v2) 94 | { 95 | int x = v1, y = v2; 96 | while (chain[x] != chain[y]){ 97 | if (lvl[chain_head[chain[x]]] >= lvl[chain_head[chain[y]]]) 98 | x = chain_link[chain[x]]; 99 | else 100 | y = chain_link[chain[y]]; 101 | } 102 | if (lvl[x] < lvl[y]) return x; 103 | else return y; 104 | } 105 | 106 | //---- BIT ----- 107 | long long _query(long long *bit, int indx){ 108 | long long sum = 0; 109 | while (indx) { 110 | sum += bit[indx]; 111 | indx -= indx & -indx; 112 | } 113 | return sum; 114 | } 115 | 116 | void update(long long *bit, int indx, long long val){ 117 | while (indx < MAX) { 118 | bit[indx] += val; 119 | indx += indx & -indx; 120 | } 121 | } 122 | 123 | long long query(long long *bit, int x, int y){ 124 | if (x > y) swap(x, y); 125 | return _query(bit, y) - _query(bit, x-1); 126 | } 127 | //-------------- 128 | 129 | 130 | //-----Modifiable--- 131 | long long path_query(long long *bit, int x, int y) // y is some ancestor of x in the actual tree 132 | { 133 | long long aggregate = 0; // Set it as per the problem statement 134 | while (chain[x] != chain[y]){ 135 | aggregate += query(bit, node[x], node[chain_head[chain[x]]]); // Set it as per the problem statement 136 | x = chain_link[chain[x]]; 137 | } 138 | aggregate += query(bit, node[x], node[y]); 139 | return aggregate; 140 | } 141 | 142 | void node_update(long long *bit, int x, long long y) // pass the actual id of the nodes not the hashed ids 143 | { 144 | update(bit, node[x], y); 145 | } 146 | //------------------ 147 | 148 | 149 | long long a[MAX], t[MAX], bit[MAX]; 150 | 151 | int main() 152 | { 153 | int tc; 154 | scanf("%d", &tc); 155 | for (int t = 1; t <= tc; t++) 156 | { 157 | printf("Case %d:\n", t); 158 | int v; 159 | scanf("%d", &v); 160 | G.clear(); 161 | G.resize(v); 162 | for (int i = 0; i < v; i++) { 163 | scanf("%lld", &a[i]); 164 | } 165 | memset(bit, 0, sizeof(bit)); 166 | tree.process(); 167 | for (int i = 1; i <= v-1; i++) { 168 | int a, b; 169 | scanf("%d%d", &a, &b); 170 | G[a].push_back(b); 171 | G[b].push_back(a); 172 | } 173 | 174 | hld_decompose(0, v); 175 | 176 | for (int i = 0; i < v; i++) { 177 | update(bit, node[i], a[i]); 178 | } 179 | 180 | int q; 181 | scanf("%d", &q); 182 | while (q--) { 183 | int ch; 184 | scanf("%d", &ch); 185 | int x; 186 | scanf("%d", &x); 187 | if (!ch) { 188 | int y; 189 | scanf("%d", &y); 190 | long long sum = 0; 191 | int lca_xy = lca(x, y); 192 | sum += path_query(bit, x, lca_xy); 193 | sum += path_query(bit, y, lca_xy); 194 | sum -= a[lca_xy]; 195 | printf("%lld\n", sum); 196 | } else { 197 | long long y; 198 | scanf("%lld", &y); 199 | node_update(bit, x, y - a[x]); 200 | a[x] = y; 201 | } 202 | } 203 | } 204 | } -------------------------------------------------------------------------------- /src/int2string_string2int.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Converts integer to string and vice versa 3 | * Usage: toString (Converts an integer to its string representation) 4 | * toValue (Converts a string to its interger representation) 5 | * Source: https://github.com/dragonslayerx 6 | */ 7 | 8 | template 9 | string toString(T x){ 10 | string s; 11 | while (x) { 12 | s.push_back(x % 10 + '0'); 13 | x /= 10; 14 | } 15 | reverse(s.begin(), s.end()); 16 | return s; 17 | } 18 | 19 | long long toInt(string &x){ 20 | long long sum = 0; 21 | for (int i = 0; i < x.size(); i++) { 22 | sum *= 10; 23 | sum += (x[i]-'0'); 24 | } 25 | return sum; 26 | } 27 | -------------------------------------------------------------------------------- /src/isConnected_using_bfs.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: BFS (Checks if graph is connected using BFS) 3 | * Usgae: isConnected O(V + E) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | int isConnected(vector > &G, int src){ 8 | bool isVisited[MAX] = {false}; 9 | queue Q; 10 | Q.push(src); 11 | while (Q.size()) { 12 | int u = Q.front(); 13 | Q.pop(); 14 | isVisited[u] = true; 15 | for (int v : G[u]) { 16 | if (!isVisited[v]) { 17 | Q.push(v); 18 | } 19 | } 20 | } 21 | for (int i = 0; i < G.size(); i++) { 22 | if (isVisited[i] == false) { 23 | return false; 24 | } 25 | } 26 | return true; 27 | } 28 | -------------------------------------------------------------------------------- /src/karatsuba_polynomial_multiplication.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Karatsuba Algorithm (Fast polynomial multiplication) 3 | * Usage: multiply O(N^1.583) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | #define MOD 99991 12 | 13 | //m should be a power of 2 14 | class Karatsuba { 15 | public: 16 | 17 | static void multiply(int *A, int *B, int *C, int lA, int rA, int lB, int rB){ 18 | int m = rA-lA+1; 19 | if (m == 1) { 20 | C[0] = ((long long)A[lA]*B[lB]) % MOD; 21 | return; 22 | } 23 | 24 | int z0[m], z1[m], z2[m]; 25 | 26 | int midA = (lA + rA) >> 1; 27 | int midB = (lB + rB) >> 1; 28 | 29 | multiply(A, B, z0, lA, midA, lB, midB); 30 | multiply(A, B, z1, midA+1, rA, midB+1, rB); 31 | 32 | int a[m], b[m]; 33 | int shift = m>>1; 34 | int mid = m>>1; 35 | for (int i = lA, j = 0; i <= midA; i++, j++) { 36 | a[j] = A[i] + A[i+shift]; 37 | if (a[j] >= MOD) a[j] -= MOD; 38 | } 39 | for (int i = lB, j = 0; i <= midB; i++, j++) { 40 | b[j] = B[i] + B[i+shift]; 41 | if (b[j] >= MOD) b[j] -= MOD; 42 | } 43 | multiply(a, b, z2, 0, mid-1, 0, mid-1); 44 | 45 | for (int i = 0; i <= m-2; i++) { 46 | C[i] = z0[i]; 47 | if (C[i] >= MOD) C[i] -= MOD; 48 | } 49 | C[m-1] = 0; 50 | 51 | shift = m; 52 | for (int i = 0; i <= m-2; i++) { 53 | C[i+shift] = z1[i]; 54 | if (C[i+shift] >= MOD) C[i+shift] -= MOD; 55 | } 56 | 57 | shift = m>>1; 58 | for (int i = 0; i <= m-2; i++) { 59 | C[i+shift] += (z2[i] + (MOD-z1[i]) + (MOD-z0[i])) % MOD; 60 | if (C[i+shift] >= MOD) { 61 | C[i+shift] -= MOD; 62 | } 63 | } 64 | } 65 | }; 66 | 67 | int main() 68 | { 69 | int A[] = {1, 1, 1, 1}; 70 | int B[] = {1, 1, 0, 0}; 71 | int C[7] = {}; 72 | Karatsuba::multiply(A, B, C, 0, 3, 0, 3); 73 | for (int i = 0; i < 7; i++) { 74 | cerr << C[i] << endl;; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/kruskal_min_spanning_tree.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Kruskal Algorithm (Minimum Spanning Tree). 3 | * Usage: See below O((V + E) lg(E)) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | class Disjoint_Set { 14 | private: 15 | vector P; 16 | vector rank; 17 | public: 18 | Disjoint_Set(int n){ 19 | P.resize(n); 20 | rank.resize(n); 21 | for (int i = 0; i < n; i++) { 22 | P[i] = i; 23 | } 24 | } 25 | 26 | void merge(int node_x, int node_y){ 27 | int rep_x = find(node_x); 28 | int rep_y = find(node_y); 29 | if (rank[rep_x] > rank[rep_y]) 30 | P[rep_y] = rep_x; 31 | else { 32 | P[rep_x] = rep_y; 33 | if (rank[rep_x] == rank[rep_y]) 34 | rank[rep_y]++; 35 | } 36 | } 37 | 38 | int find(int node){ 39 | int tmp = node; 40 | while (node != P[node]) { 41 | node = P[tmp]; 42 | tmp = node; 43 | } 44 | return node; 45 | } 46 | }; 47 | 48 | 49 | struct edge { 50 | int a, b; 51 | long long w; 52 | int index; 53 | }; 54 | 55 | bool compare(const edge &a, const edge &b){ 56 | return a.w < b.w; 57 | } 58 | 59 | #define MAX 505 60 | int main(){ 61 | ios::sync_with_stdio(false); 62 | int v, e; 63 | cin >> v >> e; 64 | vector E(e); 65 | for (int i = 0; i < e; i++) { 66 | cin >> E[i].a; 67 | cin >> E[i].b; 68 | E[i].a-- , E[i].b--; 69 | cin >> E[i].w; 70 | E[i].index = i; 71 | } 72 | int u; 73 | cin >> u; 74 | sort(E.begin(), E.end(), compare); 75 | Disjoint_Set D(v); 76 | int selected = 0; 77 | cout << v-1 << endl; 78 | for (int i = 0; i < E.size(); i++) { 79 | int w = E[i].w; 80 | int a = E[i].a; 81 | int b = E[i].b; 82 | if (D.find(a) != D.find(b)) { 83 | cout << E[i].index + 1 << endl; 84 | selected++; 85 | D.merge(a, b); 86 | } 87 | if (selected == v - 1) { 88 | break; 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/kth_ancestor_tree.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Level Ancestor (Finds the Kth level ancestor of a node in tree using sparse table) 3 | * Usage: assign, process O(N lg(N)), query O(lg(N)) 4 | * Note: The tree should in form of an array P where P[i] represents parent of i th node. 5 | * Source: https://github.com/dragonslayerx 6 | */ 7 | 8 | class levelAncestor 9 | { 10 | private: 11 | vector tree; 12 | vector > LA; 13 | 14 | public: 15 | levelAncestor(){} 16 | 17 | levelAncestor(size_t size){ 18 | assign(size); 19 | } 20 | 21 | template levelAncestor(const vector &T){ 22 | assign(T); 23 | } 24 | 25 | template void assign(const vector &T){ 26 | clear(); 27 | tree.resize(T.size()); 28 | for(size_t i=0;i>=1,lgn++); 34 | 35 | LA.resize(lgn,vector(tree.size())); 36 | 37 | for(size_t j=0;j>=1,k++) { 53 | if(level&1) { 54 | current=LA[k][current]; 55 | } 56 | } 57 | return current; 58 | } 59 | 60 | size_t size() const{ 61 | return tree.size(); 62 | } 63 | 64 | void clear(){ 65 | tree.clear(); 66 | } 67 | 68 | ~levelAncestor(){ 69 | clear(); 70 | } 71 | }; 72 | -------------------------------------------------------------------------------- /src/kth_shortest_path_between_nodes_graph.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Finds Kth shortest path from s to t. 3 | * Usage : getCost O((V + E) lg(V) * k) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | const int INF = 1e9; 7 | int getCost(vector< vector< pair > > &G, int s, int t, int k) { 8 | int n = G.size(); 9 | int dist[MAX], count[MAX]; 10 | for (int i = 0; i < n; i++) { 11 | dist[i] = INF; 12 | count[i] = 0; 13 | } 14 | priority_queue, vector >, greater > > Q; 15 | Q.push(make_pair(0, s)); 16 | while (!Q.empty() && (count[t] < k)) { 17 | pair node = Q.top(); 18 | int u = node.second; 19 | int w = node.first; 20 | Q.pop(); 21 | if ((dist[u] == INF) or (w > dist[u])) { // remove equal paths 22 | count[u]++; 23 | dist[u] = w; 24 | } 25 | if (count[u] <= k) { 26 | for (int i = 0; i < G[u].size(); i++) { 27 | int v = G[u][i].first; 28 | int w = G[u][i].second; 29 | Q.push(make_pair(dist[u] + w, v)); 30 | } 31 | } 32 | } 33 | return dist[t]; 34 | } 35 | -------------------------------------------------------------------------------- /src/linear_recurrence_matrix_exponentiation.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Matrix Exponentiation (Finds the Kth element of a linear recurrence using matrix exponentiation) 3 | * Usage: solve O(N^3 lg (K)) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | typedef long long ll; 12 | const int MOD = 1000000007; 13 | 14 | template 15 | void multiply(T A[N][N], T B[N][N]) { 16 | T C[N][N]={}; 17 | for (int i = 0; i < N; i++) { 18 | for (int j = 0; j < N; j++) { 19 | for (int k = 0; k < N ;k++) { 20 | C[i][j] += (A[i][k]*B[k][j]) % MOD; 21 | if (C[i][j] >= MOD) C[i][j] -= MOD; 22 | } 23 | } 24 | } 25 | for (int i = 0; i < N; i++) { 26 | for (int j = 0; j < N; j++) { 27 | A[i][j] = C[i][j]; 28 | } 29 | } 30 | } 31 | 32 | template 33 | void power(T A[N][N], T base[N][N], long long k) { 34 | if (k == 0) return; // assumes A is I initially 35 | else { 36 | power(A, base, k>>1); 37 | multiply(A, A); 38 | if (k & 1) { 39 | multiply(A, base); 40 | } 41 | } 42 | } 43 | 44 | template 45 | void solve(T transition[N][N], T cur[N], ll k, T next[N]) { 46 | T r[N][N]={}; 47 | for (int i = 0; i < N; i++) r[i][i]=1; // r is I 48 | 49 | power(r, transition, k); 50 | 51 | for (int i = 0; i < N; i++) { 52 | next[i]=0; 53 | for (int j = 0; j < N; j++) { 54 | next[i] += (r[i][j]*cur[j]) % MOD; 55 | if (next[i] >= MOD) next[i] -= MOD; 56 | } 57 | } 58 | } 59 | 60 | int main() { 61 | long long A[2][2] = {{1, 1}, {1, 0}}; 62 | long long cur[2] = {1, 0}, next[2]; 63 | int k; 64 | cin >> k; 65 | solve(A, cur, k, next); 66 | cout << next[0] << endl; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /src/linearize_tree_subtree_aggregate_query.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Tree linearization (Find the aggregate queries over nodes of a subtree) 3 | * Usage: dfs O(N) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | #define MAX 100500 8 | bool isvisited[MAX]; 9 | int pos[MAX], child[MAX]; 10 | int size = 0; 11 | 12 | vector > G; 13 | 14 | int dfs(int u){ 15 | isvisited[u] = 1; 16 | int count = 1; 17 | pos[u] = size++; 18 | for (vector::iterator i = G[u].begin(); i != G[u].end(); i++) { 19 | if (!isvisited[*i]) { 20 | count += dfs(*i); 21 | } 22 | } 23 | child[pos[u]] = count; 24 | return count; 25 | } 26 | -------------------------------------------------------------------------------- /src/longest_increasing_subsequence_lis_binary_search.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Longest Increasing Subsequence 3 | * Usage: LIS O(N lg(N)) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | int LIS(const vector &a){ 13 | vector lis; 14 | lis.push_back(a[0]); 15 | for (int i = 1; i < a.size(); i++) { 16 | vector::iterator pos = upper_bound(lis.begin(), lis.end(), a[i]); 17 | if (pos == lis.end()) { 18 | lis.push_back(a[i]); 19 | } else { 20 | int idx = pos - lis.begin(); 21 | lis[idx] = a[i]; 22 | } 23 | } 24 | return lis.size(); 25 | } 26 | 27 | int main() { 28 | int n; 29 | cin >> n; 30 | vector a(n); 31 | for (int i = 0; i < n; i++) { 32 | cin >> a[i]; 33 | } 34 | cout << LIS(a) << endl; 35 | } 36 | -------------------------------------------------------------------------------- /src/lowest_common_ancestor_lca.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: LCA (Finds the lowest common ancestor of two nodes in a tree) 3 | * Usage: LCA constructor O(Nlg(N)), query O(lg(N)) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | template class RMQ { 8 | vector a; 9 | vector > rmq; 10 | 11 | int size; 12 | int log2(int x){ 13 | int i = 0, n = 1; 14 | while (x >= n) { 15 | i++; n <<= 1; 16 | } 17 | i--; 18 | return i; 19 | } 20 | 21 | public: 22 | RMQ() {} 23 | 24 | RMQ(vector &a) : a(a) { 25 | size = log2(a.size()) + 1; 26 | rmq.resize(size, vector (a.size())); 27 | construct(a); 28 | } 29 | 30 | void construct(vector &array){ 31 | for (int i = 0; i < array.size(); i++) rmq[0][i] = i; 32 | for (int k = 1; k < size; k++) { 33 | for (int i = 0; i < a.size(); i++) { 34 | int length = 1 << (k - 1); 35 | if (i + length >= a.size() || a.at(rmq[k - 1][i]) < a.at(rmq[k - 1][i + length])){ 36 | rmq[k][i] = rmq[k - 1][i]; 37 | } else { 38 | rmq[k][i] = rmq[k - 1][i + length]; 39 | } 40 | } 41 | } 42 | } 43 | 44 | int query(int i, int j){ 45 | int range = j - i + 1; 46 | int logr = log2(range); 47 | if (a[rmq[logr][i]] < a[rmq[logr][j - (1 << logr) + 1]]) 48 | return rmq[logr][i]; 49 | else 50 | return rmq[logr][j - (1 << logr) + 1]; 51 | } 52 | }; 53 | 54 | class LCA { 55 | typedef vector > tree; 56 | vector E, H, L; 57 | RMQ R; 58 | tree T; 59 | vector isvisited; 60 | 61 | void euler_tour(int node, int level){ 62 | isvisited[node] = 1; 63 | E.push_back(node); 64 | L.push_back(level); 65 | for (vector::iterator i = T[node].begin(); i != T[node].end(); i++) { 66 | if (!isvisited[*i]) { 67 | euler_tour(*i, level + 1); 68 | E.push_back(node); 69 | L.push_back(level); 70 | } 71 | } 72 | } 73 | 74 | public: 75 | LCA(tree &T, int root): T(T){ 76 | isvisited.resize(T.size()); 77 | H.resize(T.size(), -1); 78 | euler_tour(root, 0); 79 | for (int i = 0; i < E.size(); i++) { 80 | if (H[E[i]] == -1) 81 | H[E[i]] = i; 82 | } 83 | R = RMQ(L); 84 | } 85 | 86 | int lca(int a, int b){ 87 | if (H[a] > H[b]) swap(a, b); 88 | int index = R.query(H[a], H[b]); 89 | return E[index]; 90 | } 91 | }; 92 | -------------------------------------------------------------------------------- /src/lucas_combinatorics.cpp: -------------------------------------------------------------------------------- 1 | long long Lucas_nCr(long long n, long long m){ 2 | long long m0 = m % MOD; 3 | long long m1 = m / MOD; 4 | long long n0 = n % MOD; 5 | long long n1 = n / MOD; 6 | 7 | long long answer = 1; 8 | if (n0 >= m0) { 9 | answer *= C(n0, m0); 10 | answer %= MOD; 11 | } else { 12 | answer = 0; 13 | } 14 | if (n1 >= m1) { 15 | answer *= C(n1, m1); 16 | answer %= MOD; 17 | } else { 18 | answer = 0; 19 | } 20 | 21 | return answer; 22 | } -------------------------------------------------------------------------------- /src/max_bipartite_matching_hopcroft_karp.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Desciption: Maximum bipartite matching: 3 | * Usage: max matching O(E sqrt(V)) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | class Max_Bipartite_Match { 8 | vector > &G; 9 | public: 10 | 11 | vector match, mark; 12 | int max_match, stamp; 13 | 14 | Max_Bipartite_Match(vector > &bipartite_graph, int v): G(bipartite_graph){ 15 | match.resize(v); 16 | mark.resize(v); 17 | for (int i = 0; i < v; i++) { 18 | match[i] = -1; 19 | mark[i] = -1; 20 | } 21 | stamp = 0; 22 | } 23 | 24 | bool augment_path(int vertex){ 25 | for (int i = 0; i < G[vertex].size(); i++) { 26 | int v = G[vertex][i]; 27 | if (mark[v] == stamp) 28 | continue; 29 | mark[v] = stamp; 30 | if (match[v] == -1 || augment_path(match[v])) { 31 | match[v] = vertex; 32 | return true; 33 | } 34 | } 35 | return false; 36 | } 37 | 38 | int max_matching(){ 39 | max_match = 0; 40 | for (int i = 0; i < G.size(); i++) { 41 | stamp++; 42 | if (augment_path(i)) max_match++; 43 | } 44 | return max_match; 45 | } 46 | }; 47 | 48 | -------------------------------------------------------------------------------- /src/max_flow_network_dinic_algorithm.cpp: -------------------------------------------------------------------------------- 1 | 2 | #define NN 1505 3 | 4 | int cap[NN][NN]; 5 | vector > adj; 6 | 7 | int q[NN], prev[NN]; 8 | int dinic( int n, int s, int t ) 9 | { 10 | int flow = 0; 11 | while( true ) 12 | { 13 | // find an augmenting path 14 | memset( prev, -1, sizeof(prev) ); 15 | int qf = 0, qb = 0; 16 | prev[q[qb++] = s] = -2; 17 | while( qb > qf && prev[t] == -1 ) 18 | for( int u = q[qf++], i = 0, v; i < adj[u].size(); i++ ) 19 | if( prev[v = adj[u][i]] == -1 && cap[u][v] ) 20 | prev[q[qb++] = v] = u; 21 | 22 | // see if we're done 23 | if( prev[t] == -1 ) break; 24 | 25 | // try finding more paths 26 | for( int z = 0; z < n; z++ ) if( cap[z][t] && prev[z] != -1 ) 27 | { 28 | int bot = cap[z][t]; 29 | for( int v = z, u = prev[v]; u >= 0; v = u, u = prev[v] ) 30 | bot = min(bot, cap[u][v]); 31 | if( !bot ) continue; 32 | 33 | cap[z][t] -= bot; 34 | cap[t][z] += bot; 35 | for( int v = z, u = prev[v]; u >= 0; v = u, u = prev[v] ) 36 | { 37 | cap[u][v] -= bot; 38 | cap[v][u] += bot; 39 | } 40 | flow += bot; 41 | } 42 | } 43 | return flow; 44 | } 45 | -------------------------------------------------------------------------------- /src/merge_sort_count_inversion.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Merge sort (Find inversions in an array) 3 | * Usage: merge_sort O(N lg(N)). See below 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | #define MAX 100050 13 | 14 | int merge(int a[], int b[], int l, int r, int mid) 15 | { 16 | int lptr = l; 17 | int rptr = mid+1; 18 | int current_ptr = 0; 19 | int count = 0; 20 | for (int i = l; i <= r; i++) { 21 | if (lptr > mid) { 22 | b[current_ptr++] = a[rptr++]; 23 | count += (mid - lptr + 1); 24 | } else if (rptr > r) { 25 | b[current_ptr++] = a[lptr++]; 26 | } else { 27 | if (a[lptr] < a[rptr]) { 28 | b[current_ptr++] = a[lptr++]; 29 | } else { 30 | b[current_ptr++] = a[rptr++]; 31 | count += (mid - lptr + 1); 32 | } 33 | } 34 | } 35 | for (int i = l, j = 0; i <= r; i++, j++) { 36 | a[i] = b[j]; 37 | } 38 | return count; 39 | } 40 | 41 | int merge_sort(int a[], int b[], int l, int r) 42 | { 43 | if (l == r) { 44 | return 0; 45 | } 46 | int mid = (l + r)/2; 47 | int inversion_left = merge_sort(a, b, l, mid); 48 | int inversion_right = merge_sort(a, b, mid+1, r); 49 | int inversion_count = merge(a, b, l, r, mid); 50 | return inversion_left + inversion_right + inversion_count; 51 | } 52 | 53 | int main() 54 | { 55 | int a[MAX], b[MAX]; 56 | int n; 57 | cin >> n; 58 | for (int i = 0; i < n; i++) { 59 | cin >> a[i]; 60 | //a[i] = rand() % 32; 61 | } 62 | cout << merge_sort(a, b, 0, n-1) << endl ; 63 | cout << endl; 64 | } 65 | -------------------------------------------------------------------------------- /src/merge_sort_trees.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Merge sort tree 3 | * Usage: construct O(Nlg(N)), query O(lg(N)) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | #define MAX 30050 8 | 9 | vector > st; 10 | int a[MAX]; 11 | 12 | void merge(int n, int left, int right) { 13 | int lptr = 0, rptr = 0, cptr = 0;; 14 | while (lptr < st[left].size() || rptr < st[right].size()) { 15 | if (lptr == st[left].size()) 16 | st[n][cptr++] = st[right][rptr++]; 17 | else if (rptr == st[right].size()) 18 | st[n][cptr++] = st[left][lptr++]; 19 | else { 20 | if (st[left][lptr] < st[right][rptr]) 21 | st[n][cptr++] = st[left][lptr++]; 22 | else 23 | st[n][cptr++] = st[right][rptr++]; 24 | } 25 | } 26 | } 27 | 28 | void construct(int n, int ll, int rl) { 29 | if (ll == rl) { 30 | st[n].push_back(a[ll]); 31 | return; 32 | } 33 | construct(2*n+1, ll, (ll+rl)/2); 34 | construct(2*n+2, (ll+rl)/2+1, rl); 35 | st[n].resize(rl-ll+1); 36 | merge(n, 2*n+1, 2*n+2); 37 | } 38 | 39 | int query(int n, int ll, int rl, int ql, int qr, int k) { 40 | if (rl < ql || ll > qr) return 0; 41 | if (ll >= ql && rl <= qr) { 42 | // modify here 43 | int t = st[n].end() - upper_bound(st[n].begin(), st[n].end(), k); 44 | return t; 45 | } 46 | int left = query(2*n+1, ll, (ll+rl)/2, ql, qr, k); 47 | int right = query(2*n+2, (ll+rl)/2+1, rl, ql, qr, k); 48 | return left + right; 49 | } 50 | 51 | int main() { 52 | int n; 53 | scanf("%d", &n); 54 | for (int i = 0; i < n; i++) scanf("%d", &a[i]); 55 | 56 | st.resize(4*MAX); 57 | construct(0, 0, n-1); 58 | 59 | int q; 60 | scanf("%d", &q); 61 | while (q--) { 62 | int i, j, k; 63 | scanf("%d%d%d", &i, &j, &k); 64 | i--, j--; 65 | int answer = query(0, 0, n-1, i, j, k); 66 | printf("%d\n", answer); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/merge_sort_trees_order_stat_query.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Merge sort tree for order statistics and rank query in range. 3 | * Usage: insertST O(lg(N)), removeST O(lg(N)), queryST O(lg^2(N)), queryOrderST O(lg^2(N)) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | int queryOrderST(int n, int ll, int rl, int ql, int qr, int k) 8 | { 9 | if (ll == rl) return ll; 10 | int count = upper_bound(st[(n<<1)+1].begin(), st[(n<<1)+1].end(), qr) - 11 | lower_bound(st[(n<<1)+1].begin(), st[(n<<1)+1].end(), ql); 12 | int m = (ll + rl)>>1; 13 | if (count > k) { 14 | return queryOrderST((n<<1)+1, ll, m, ql, qr, k); 15 | } else { 16 | return queryOrderST((n<<1)+2, m+1, rl, ql, qr, k - count); 17 | } 18 | } 19 | 20 | int queryST(int n, int ll, int rl, int ql, int qr, int x) 21 | { 22 | int mid = (ll + rl)>>1; 23 | if (x == mid) { 24 | int count = upper_bound(st[(n<<1)+1].begin(), st[(n<<1)+1].end(), qr) - 25 | lower_bound(st[(n<<1)+1].begin(), st[(n<<1)+1].end(), ql); 26 | return count; 27 | } 28 | if (x < mid) { 29 | return queryST((n<<1)+1, ll, mid, ql, qr, x); 30 | } else { 31 | int count = upper_bound(st[(n<<1)+1].begin(), st[(n<<1)+1].end(), qr) - 32 | lower_bound(st[(n<<1)+1].begin(), st[(n<<1)+1].end(), ql); 33 | return count + queryST((n<<1)+2, mid+1, rl, ql, qr, x); 34 | } 35 | } 36 | 37 | void insertST(int n, int ll, int rl, int q, int k) 38 | { 39 | if (k >= ll && k <= rl) { 40 | st[n].push_back(q); 41 | if (ll != rl) { 42 | insertST((n<<1)+1, ll, ((ll+rl)>>1), q, k); 43 | insertST((n<<1)+2, ((ll+rl)>>1)+1, rl, q, k); 44 | } 45 | } 46 | } 47 | 48 | void removeST(int n, int ll, int rl, int q) 49 | { 50 | if (q >= ll && q <= rl) { 51 | st[n].pop_back(); 52 | if (ll != rl) { 53 | removeST((n<<1)+1, ll, ((ll+rl)>>1), q); 54 | removeST((n<<1)+2, ((ll+rl)>>1)+1, rl, q); 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /src/misc/online_median_heaps.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | int main() 8 | { 9 | int n; 10 | scanf("%d", &n); 11 | priority_queue firstHalf; 12 | priority_queue, greater > secondHalf; 13 | int elementsSoFar = 0; 14 | firstHalf.push(-1); 15 | secondHalf.push(INT_MAX); 16 | 17 | for (int i = 0; i < n; i++) { 18 | int k; 19 | scanf("%d", &k); 20 | ++elementsSoFar; 21 | 22 | if (k <= firstHalf.top()) { 23 | firstHalf.push(k); 24 | } else { 25 | secondHalf.push(k); 26 | } 27 | if (elementsSoFar & 1) { 28 | int median; 29 | if (firstHalf.size() > secondHalf.size()) { 30 | median = firstHalf.top(); 31 | } else { 32 | median = secondHalf.top(); 33 | } 34 | printf("%.1f\n", (float)median); 35 | } else { 36 | if (firstHalf.size() > secondHalf.size()) { 37 | int maxFirstHalf = firstHalf.top(); 38 | firstHalf.pop(); 39 | secondHalf.push(maxFirstHalf); 40 | } else if (firstHalf.size() < secondHalf.size()){ 41 | int minSecondHalf = secondHalf.top(); 42 | secondHalf.pop(); 43 | firstHalf.push(minSecondHalf); 44 | } 45 | int lowerMedian = firstHalf.top(); 46 | int upperMedian = secondHalf.top(); 47 | printf("%.1f\n", (float)(lowerMedian + upperMedian) / 2); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/misc/radix_sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | //Valid Indexes are from [0, n-1] and value are from [0, k-1] 6 | //Digits are taken from LSB 7 | template 8 | class RadixSort{ 9 | void stableCountingSort(T a[], int d, int n, int (*get)(T, int)){ 10 | int position[k] = {}; 11 | T b[k]; 12 | for (int i = 0; i < n; i++) { 13 | ++position[get(a[i], d)]; 14 | } 15 | for (int i = 1; i < k; i++) { 16 | position[i] += position[i-1]; 17 | } 18 | for (int i = n-1; i >= 0; i--) { 19 | b[position[get(a[i], d)]--] = a[i]; 20 | } 21 | for (int i = 0; i < n; i++) { 22 | a[i] = b[i+1]; 23 | } 24 | } 25 | public: 26 | void sort(T a[], int n, int (*get)(T, int)){ 27 | for (int i = 1; i <= digits; i++) { 28 | stableCountingSort(a, i, n, get); 29 | } 30 | }; 31 | }; 32 | -------------------------------------------------------------------------------- /src/mo_algorithm_offline_range_query.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Mo Algorithm (Support offline query processing) 3 | * Usage: See below (O(N sqrt(N))) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | using namespace std; 14 | 15 | typedef long long ll; 16 | 17 | const int MAX = 100005 18 | 19 | struct Query { 20 | int l, r; 21 | int idx; 22 | int answer; 23 | Query(int l, int r, int idx) { 24 | this->l = l; 25 | this->r = r; 26 | this->idx = idx; 27 | } 28 | }; 29 | 30 | int S; 31 | void initS(int n) { S = sqrt(n); } 32 | 33 | bool compare(Query a, Query b) { 34 | if (a.l/S != b.l/S) { 35 | return a.l/S < b.l/S; 36 | } else { 37 | return a.r > b.r; 38 | } 39 | } 40 | 41 | //--Data-Strcuture 42 | int Answer = 0; 43 | inline void insert(int v) { 44 | } 45 | 46 | inline void erase(int v) { 47 | } 48 | //------------- 49 | 50 | int answer[MAX]; 51 | 52 | int main() { 53 | int n, q; 54 | cin >> n >> q; 55 | initS(n); 56 | vector a(n); 57 | for (int i = 0; i < n; i++) { 58 | cin >> a[i]; 59 | if (a[i] > n) a[i] = n+1; 60 | } 61 | vector query; 62 | for (int i = 0; i < q; i++) { 63 | int l, r; 64 | cin >> l >> r; 65 | l--, r--; 66 | query.push_back(Query(l, r, i)); 67 | } 68 | sort(query.begin(), query.end(), compare); 69 | int left = 0, right = -1; 70 | for (int i = 0; i < query.size(); i++) { 71 | int l = query[i].l; 72 | int r = query[i].r; 73 | if (right < r) { 74 | while (right < r) { 75 | right++; insert(a[right]); 76 | } 77 | } else { 78 | while (right > r) { 79 | erase(a[right]); right--; 80 | } 81 | } 82 | if (left < l) { 83 | while (left < l) { 84 | erase(a[left]); left++; 85 | } 86 | } else { 87 | while (left > l) { 88 | left--; insert(a[left]); 89 | } 90 | } 91 | answer[query[i].idx] = Answer; 92 | } 93 | 94 | for (int i = 0; i < q; i++) { 95 | cout << answer[i] << endl; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/mobeius_function.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Mobeius Function. 3 | * Usage: initmobeius O(Nlg(N)) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | vector mobeius; 8 | vector no_prime_factors; 9 | #define INVALID INT_MAX 10 | void initmobeius(int n){ 11 | mobeius.resize(n + 1, INVALID); 12 | no_prime_factors.resize(n + 1); 13 | mobeius[1] = 0; 14 | mobeius[2] = 1, no_prime_factors[2] = 0; 15 | for (int i = 2; i <= n; i++) { 16 | if (mobeius[i]) { 17 | if (no_prime_factors[i] == 0) { 18 | mobeius[i] = 1; 19 | for (int j = 1; i * j <= n; j++) 20 | no_prime_factors[i * j] += 1; 21 | } 22 | else if (no_prime_factors[i] == 1) { 23 | mobeius[i] = 0; 24 | for (int j = 1; i * j <= n; j++) 25 | mobeius[i * j] = 0; 26 | } 27 | else if (no_prime_factors[i] & 1) 28 | mobeius[i] = 1; 29 | else 30 | mobeius[i] = -1; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/monotone_priority_queue.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Monotone Priority Queues (Supports sliding window queries) 3 | * Usage: pushmax, pushmin, O(N) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | deque maxq, minq; 8 | void pushmax(int element) { 9 | while (!maxq.empty() && element > maxq.back()) maxq.pop_back(); 10 | maxq.push_back(element); 11 | } 12 | 13 | 14 | void pushmin(int element) { 15 | while (!minq.empty() && element < minq.back()) minq.pop_back(); 16 | minq.push_back(element); 17 | } 18 | -------------------------------------------------------------------------------- /src/multiply_detect_overflow.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Multiply two 64-bit integers and checks if there is overflow. In later case INF is returned 3 | * Usage: mul O(1) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | const long long INF = 1000000000000000005LL; 8 | long long mul(long long a, long long b) { 9 | pair s, t, result; 10 | t.first = a / 1000000000; 11 | t.second = a % 1000000000; 12 | 13 | s.first = b / 1000000000; 14 | s.second = b % 1000000000; 15 | 16 | long long r1, r2, r3, r4; 17 | 18 | r1 = t.first * s.first; 19 | r2 = t.first * s.second; 20 | r3 = t.second * s.first; 21 | r4 = t.second * s.second; 22 | 23 | if (r1 > 1) return INF; 24 | else if (r1 && (r2 || r3 || r4)) return INF; 25 | else if ((r2 + r3) > 1000000000) return INF; 26 | else if ((r2 + r3)*1000000000 + r4 > 1000000000000000000LL) return INF; 27 | else return r1*1000000000000000000LL + (r2 + r3)*1000000000 + r4; 28 | } 29 | -------------------------------------------------------------------------------- /src/multiply_longlong_integers.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Multiply two 64 bit integers and returns result mod M, 3 | * Source: https://github.com/dragonslayerx 4 | */ 5 | 6 | long long int multiply(long long int val, long long int n,long long int mod){ 7 | long long int q=((double)val*(double)n/(double)mod); 8 | long long int res=val*n-mod*q; 9 | res=(res%mod+mod)%mod; 10 | return res; 11 | } -------------------------------------------------------------------------------- /src/non_bipartite_check.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Checks if a graph is non bipartite. Assigns color to each node in case it is. 3 | * Usage: dfs returns true if the graph in nonbipartite O(V + E) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | #define MAX 100005 8 | bool isVisited[MAX]; 9 | bool color[MAX]; 10 | 11 | long long countA, countB; 12 | 13 | bool isNonBipartite(int u, bool colorU){ 14 | color[u] = colorU; 15 | (color[u])? countA++: countB++; 16 | isVisited[u] = true; 17 | bool nonBipartite = false; 18 | for (int i = 0; i < G[u].size(); i++) { 19 | int v = G[u][i]; 20 | if (!isVisited[v]) { 21 | nonBipartite |= dfs(v, !colorU); 22 | } else { 23 | if (color[v] == color[u]) { 24 | return true; 25 | } 26 | } 27 | } 28 | return nonBipartite; 29 | } 30 | -------------------------------------------------------------------------------- /src/number_paths_length_k.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Calculate the no of paths of paths of length L from u to v 3 | * Usage: pow O(N^3 log L) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | #define MAX 150 14 | #define MOD 1000000007 15 | 16 | void multiply(long long A[][MAX], long long B[][MAX], int n){ 17 | long long C[MAX][MAX]; 18 | for(int i = 0; i < n; i++){ 19 | for (int j = 0; j < n; j++) { 20 | C[i][j] = 0; 21 | } 22 | } 23 | for (int i = 0; i < n; i++) { 24 | for (int j = 0; j < n; j++) { 25 | for (int k = 0; k < n; k++) { 26 | C[i][j] += (A[i][k] * B[k][j]) % MOD; 27 | C[i][j] %= MOD; 28 | } 29 | } 30 | } 31 | for (int i = 0; i < n; i++) { 32 | for (int j = 0; j < n; j++) { 33 | A[i][j] = C[i][j]; 34 | } 35 | } 36 | } 37 | 38 | void pow(long long A[][MAX], long long B[][MAX], int n, int m){ 39 | if (m == 1)return; 40 | pow(A, B, n, m/2); 41 | multiply(A, A, n); 42 | if (m & 1) multiply(A, B, n); 43 | } 44 | 45 | int main() 46 | { 47 | int t; 48 | scanf("%d", &t); 49 | while (t--) { 50 | int n, m; 51 | scanf("%d%d", &n, &m); 52 | long long d[MAX][MAX] = {}, W[MAX][MAX] = {}; 53 | for (int i = 0; i < m; i++) { 54 | int a, b; 55 | scanf("%d%d", &a, &b); 56 | W[a][b]++; W[b][a]++; 57 | } 58 | for (int i = 0; i < n; i++) { 59 | for (int j = 0; j < n; j++) { 60 | d[i][j]=W[i][j]; 61 | } 62 | } 63 | int q, L; 64 | scanf("%d%d", &q, &L); 65 | pow(d, W, n, L); 66 | while (q--) { 67 | int a, b; 68 | scanf("%d%d", &a, &b); 69 | printf("%lld\n", d[a][b]); 70 | } 71 | } 72 | } 73 | 74 | -------------------------------------------------------------------------------- /src/obselete/knuth_morris_pratt_string_matching.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: KMP algorithm (Find the longest suffix match) 3 | * Usage: KMP_matcher O(T + P). See below. 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | void Compute_Prefix_Function(string &P, vector &prefix){ 8 | int m = P.length(); 9 | int k = 0; 10 | prefix[1] = 0; 11 | for (int i = 2; i < m; i++) { 12 | while (k > 0 && P[k + 1] != P[i]) k = prefix[k]; 13 | if (P[k + 1] == P[i]) k = k + 1; 14 | prefix[i] = k; 15 | } 16 | } 17 | 18 | int match[100005]; 19 | 20 | int KMP_matcher(string T, string P){ 21 | int count = 0; 22 | int n = T.length(), m = P.length(); 23 | T = '#' + T, P = '#' + P; 24 | vector prefix(m + 1); 25 | Compute_Prefix_Function(P, prefix); 26 | #ifdef DEBUG 27 | for (int i = 1; i <= m; i++) 28 | cout << prefix[i] << " "; 29 | cout << endl; 30 | #endif 31 | int k = 0; 32 | for (int i = 1; i <= n; i++) { 33 | while (k > 0 && T[i] != P[k + 1]) k = prefix[k]; 34 | if (T[i] == P[k + 1]) k = k + 1; 35 | match[i] = k; 36 | if (k == m) { 37 | //Todo when a valid shift is found 38 | count++; 39 | } 40 | } 41 | return count; 42 | } 43 | 44 | int main(){ 45 | cout << KMP_matcher("aabaabcabaa", "aab") << endl; 46 | for (int i = 1; i <= 11; i++) { 47 | cout << match[i] << " "; 48 | } 49 | cout << endl; 50 | } 51 | -------------------------------------------------------------------------------- /src/obselete/suffix_array.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Suffix Array (Manber's Algorithm) 3 | * Usage: See https://www.codechef.com/viewsolution/9631939 for detailed usage. 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | const int MAX = 100005; 8 | const int MOD = 1000000000+7; 9 | const int INF = 1000000000; 10 | 11 | //Valid Indexes are from [0, n-1] and value are from [0, k-1] 12 | //Digits are numbered from LSD 13 | template 14 | class RadixSort 15 | { 16 | static void stableCountingSort(T a[], int d, int n, int (*get)(T, int)) 17 | { 18 | int position[k] = {}; 19 | T *b = new T[k]; 20 | for (int i = 0; i < n; i++) { 21 | ++position[get(a[i], d)]; 22 | } 23 | for (int i = 1; i < k; i++) { 24 | position[i] += position[i-1]; 25 | } 26 | for (int i = n-1; i >= 0; i--) { 27 | b[position[get(a[i], d)]--] = a[i]; 28 | } 29 | for (int i = 0; i < n; i++) { 30 | a[i] = b[i+1]; 31 | } 32 | delete(b); 33 | } 34 | public: 35 | static void sort(T a[], int n, int (*get)(T, int)) 36 | { 37 | for (int i = 1; i <= digits; i++) { 38 | stableCountingSort(a, i, n, get); 39 | } 40 | }; 41 | }; 42 | 43 | struct Pair { 44 | int first; 45 | int second; 46 | int index; 47 | Pair(){} 48 | Pair(int first, int second, int index): first(first), second(second), index(index) {} 49 | 50 | bool operator ==(const Pair& p) 51 | { 52 | return ((first == p.first) && (second == p.second))? true: false; 53 | } 54 | }; 55 | 56 | int get(Pair p, int d) 57 | { 58 | return (d == 1)? p.second: p.first; 59 | } 60 | 61 | 62 | //Output Arrays 63 | int P[25][100100]; 64 | int suffixArray[100100]; 65 | Pair orderedPair[100100]; 66 | 67 | class SuffixArray { 68 | static const int MAXSIZE = 100100; 69 | 70 | char s[MAXSIZE]; 71 | int n; 72 | int lgn; 73 | 74 | 75 | int calculateLgN(int n); 76 | 77 | public: 78 | SuffixArray() { 79 | initialize(); 80 | } 81 | 82 | SuffixArray(string s) 83 | { 84 | initialize(); 85 | setString(s); 86 | createSuffixArray(); 87 | } 88 | SuffixArray(char* s) 89 | { 90 | initialize(); 91 | setString(s); 92 | createSuffixArray(); 93 | } 94 | 95 | void initialize(); 96 | void setString(char *s); 97 | void setString(const string &s); 98 | void createSuffixArray(); 99 | inline int operator[] (int index) const; 100 | int getLCP(int a, int b) const; 101 | inline int getPosition(int index) const; 102 | }; 103 | 104 | void SuffixArray::initialize() 105 | { 106 | n = 0; 107 | } 108 | 109 | void SuffixArray::setString(char *inputString) 110 | { 111 | strcpy(s, inputString); 112 | n = strlen(s); 113 | } 114 | 115 | void SuffixArray::setString(const string &inputString) 116 | { 117 | int i = 0; 118 | for (; inputString[i]; i++) { 119 | s[i] = inputString[i]; 120 | } 121 | s[i] = '\0'; 122 | n = i; 123 | } 124 | 125 | int SuffixArray::calculateLgN(int n) 126 | { 127 | int i = 0; 128 | int l = 1; 129 | while (l <= n) { 130 | l <<= 1; 131 | i++; 132 | } 133 | i--; 134 | return i; 135 | } 136 | 137 | void SuffixArray::createSuffixArray() 138 | { 139 | //Assign Rank to every Character 140 | { 141 | bool isPresent[128] = {false}; 142 | int rankCharacter[128]; 143 | for (int i = 0; i < n; i++) { 144 | isPresent[s[i]] = true; 145 | } 146 | int currentRank = 1; 147 | for (int i = 0; i < 128; i++) { 148 | if (isPresent[i]) { 149 | rankCharacter[i] = currentRank++; 150 | } 151 | } 152 | for (int i = 0; i < n; i++) { 153 | P[0][i] = rankCharacter[s[i]]; 154 | } 155 | } 156 | lgn = calculateLgN(n); 157 | int length = 1; 158 | lgn++; 159 | for (int k = 1; k <= lgn; k++) { 160 | for (int i = 0; i < n; i++) { 161 | if (i + length < n) 162 | orderedPair[i] = Pair(P[k-1][i], P[k-1][i+length], i); 163 | else 164 | orderedPair[i] = Pair(P[k-1][i], 0, i); 165 | } 166 | 167 | RadixSort R; 168 | R.sort(orderedPair, n, get); 169 | 170 | int rank = 1; 171 | for (int i = 0; i < n; i++) { 172 | if (i > 0 && !(orderedPair[i] == orderedPair[i-1])) { 173 | ++rank; 174 | } 175 | P[k][orderedPair[i].index] = rank; 176 | } 177 | length <<= 1; 178 | } 179 | 180 | for (int i = 0; i < n; i++) { 181 | suffixArray[P[lgn][i]-1] = i; 182 | } 183 | }; 184 | 185 | inline int SuffixArray::operator [](int index) const 186 | { 187 | return suffixArray[index]; 188 | } 189 | 190 | inline int SuffixArray::getPosition(int index) const 191 | { 192 | return P[lgn][index]; 193 | } 194 | 195 | int SuffixArray::getLCP(int a, int b) const 196 | { 197 | int lps = 0; 198 | int k = lgn; 199 | int length = 1 << k; 200 | for (int k = lgn; k >= 0; k--) { 201 | if (P[k][a] == P[k][b]) { 202 | lps += length; 203 | a += length; 204 | b += length; 205 | } 206 | if (a >= n || b >= n) break; 207 | length >>= 1; 208 | } 209 | return lps; 210 | } -------------------------------------------------------------------------------- /src/orderstat_rank_query_augmented_bst.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Augmented tree for order statistics, rank query 3 | * Usage: See below O(lg(N)) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | #include 8 | #include //required 9 | #include //required 10 | using namespace __gnu_pbds; //required 11 | using namespace std; 12 | template using ordered_set = tree, rb_tree_tag, tree_order_statistics_node_update>; 13 | 14 | ordered_set s; 15 | /* or: 16 | typedef tree, rb_tree_tag, tree_order_statistics_node_update> ordered_set; 17 | ordered_set s; 18 | This works in C++98 but the above version only works in C++11 19 | */ 20 | int main(){ 21 | // It has C++ `set` functions: 22 | for(auto i: {1,3,5,8}) 23 | s.insert(i); 24 | s.erase(8); 25 | s.erase(s.find(8)); 26 | cout << * s.begin() << endl; 27 | if(s.begin() == s.end() or s.empty()) 28 | cout << "empty" << endl; 29 | s.lower_bound(3); 30 | s.upper_bound(1); 31 | cout << s.size() << endl; 32 | // special `tree` functions: 33 | cout << s.order_of_key(3) << endl; // the number of elements in s less than 3 (in this case, 0-based index of element 3) 34 | cout << *s.find_by_order(1) << endl; // 1-st elemt in s (in sorted order, 0-based) 35 | } 36 | -------------------------------------------------------------------------------- /src/palindrome_longest_subsequence.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Find longest length palindromic subsequence in s[i..j] 3 | * Usage: See below O(V^2) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | void process(const string &s, int last[][30]) { 13 | int n = s.size(); 14 | for (int j = 0; j < 26; j++) { 15 | if (j==s[0]-'a') { 16 | last[0][j] = 0; 17 | } else { 18 | last[0][j] = -1; 19 | } 20 | } 21 | for (int i = 1; i < n; i++) { 22 | for (int j = 0; j < 26; j++) { 23 | last[i][j] = last[i-1][j]; 24 | } 25 | last[i][s[i]-'a'] = i; 26 | } 27 | 28 | } 29 | 30 | int last[1005][30]; 31 | int dp[1005][1005]; 32 | 33 | int main() { 34 | string s; 35 | cin >> s; 36 | int len = s.size(); 37 | 38 | process(s, last); 39 | 40 | memset(dp, 0, sizeof(dp)); 41 | for (int i = 0; i < len; i++) dp[i][i] = 1; 42 | for (int i = len-1; i >= 0; i--) { 43 | for (int j = i+1; j < len; j++) { 44 | dp[i][j] = 1; 45 | dp[i][j] = max(dp[i][j], dp[i+1][j]); 46 | if (last[j][s[i]-'a'] > i) { 47 | dp[i][j] = max(dp[i][j], 2 + dp[i+1][last[j][s[i]-'a']-1]); 48 | } 49 | } 50 | } 51 | 52 | cout << dp[0][len-1] << endl; 53 | } 54 | -------------------------------------------------------------------------------- /src/path_nearly_complete_binary_tree.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Constructs path between two nodes in a full binary tree. 3 | * Usage: constructPath O(lg(N)) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | vector constructPath(ll u, ll v) { 8 | vector pathA, pathB; 9 | while (u >= 1) { 10 | pathA.push_back(u); 11 | u >>= 1; 12 | } 13 | while (v >= 1) { 14 | pathB.push_back(v); 15 | v >>= 1; 16 | } 17 | reverse(pathA.begin(), pathA.end()); 18 | reverse(pathB.begin(), pathB.end()); 19 | vector path; 20 | int i = 0; 21 | for (; i+1 < pathA.size() && i+1 < pathB.size(); i++) if (pathA[i+1] != pathB[i+1]) break; 22 | for (int j = pathA.size()-1; j >= i; j--) { 23 | path.push_back(pathA[j]); 24 | } 25 | for (int j = i+1; j < pathB.size(); j++) { 26 | path.push_back(pathB[j]); 27 | } 28 | return path; 29 | } -------------------------------------------------------------------------------- /src/power_binary_exponentiation.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Calculates n^m (Binary exponentiation) 3 | * Usage: power O(lg(M)) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | #define MOD 1000000007 8 | long long power(long long n, long long m) 9 | { 10 | if (m == 0) return 1; 11 | long long x = power(n, m / 2); 12 | if (!(m & 1)) return (x * x) % MOD; 13 | else return (((x * x) % MOD) * n) % MOD; 14 | } 15 | 16 | -------------------------------------------------------------------------------- /src/primality_check_fermat.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Fermats Primality Testing 3 | * Usage: fermat 4 | * Note: increating the no of iterations in fermat function improves accuracy (See Carmichael numbers). Usually I keep it 50. 5 | * Source: https://github.com/dragonslayerx 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | long long mul(long long a,long long b,long long MOD){ 14 | long long a_high = a/1000000000; 15 | long long a_low = a%1000000000; 16 | 17 | long long b_high = b/1000000000; 18 | long long b_low = b%1000000000; 19 | 20 | long long result = (a_high*b_high)%MOD; 21 | for(int i=0;i<9;i++){ 22 | result=(result*10)%MOD; 23 | } 24 | result=(result+a_high*b_low+a_low*b_high)%MOD; 25 | for(int i=0;i<9;i++){ 26 | result=(result*10)%MOD; 27 | } 28 | result=(result+a_low*b_low)%MOD; 29 | return result; 30 | } 31 | 32 | long long p(long long a,long long b,long long MOD){ 33 | if(b==0) return 1; 34 | long long x=p(a,b/2,MOD); 35 | if((b&1)==0) { 36 | return mul(x,x,MOD); 37 | } else { 38 | return mul(mul(x,x,MOD),a,MOD); 39 | } 40 | } 41 | 42 | bool fermat(long long num,int iterations){ 43 | if(num==1) { 44 | return false; 45 | } else if(num==2) { 46 | return true; 47 | } else { 48 | for(int i=0;i> x; 59 | cout << fermat(x, 50) << endl; 60 | } 61 | 62 | -------------------------------------------------------------------------------- /src/prime_factor_count.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: No of prime and distinct prime divisors. 3 | * Eg. 12 is 2*2*3. It has 3 prime factors but 2 distinct prime factors. 4 | * Usage: sieve O(Nlog(N)) 5 | * Source: https://github.com/dragonslayerx 6 | */ 7 | 8 | long long noPrimeDivisors[5000100]; 9 | long long noDistinctPrimeDivisors[5000100]; 10 | bool isPrime[5000100]; 11 | 12 | void sieve(int n){ 13 | for (int i = 1; i <= n; i++) { 14 | isPrime[i] = true; 15 | } 16 | isPrime[0] = isPrime[1] = false; 17 | for (int i = 2; i <= n; i++) { 18 | if (isPrime[i] || (noDistinctPrimeDivisors[i] == 1)) { 19 | for (int j = i; j <= n; j+=i) { 20 | ++noPrimeDivisors[j]; 21 | if (isPrime[i]) { 22 | ++noDistinctPrimeDivisors[j]; 23 | } 24 | if (j > i) { 25 | isPrime[j] = false; 26 | } 27 | } 28 | } 29 | } 30 | return; 31 | } 32 | -------------------------------------------------------------------------------- /src/prime_sieve.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Sieve of Eratosthenes 3 | * Usage: sieve O(Nlg(N)) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | vector isprime; 8 | vector primes; 9 | void sieve(int n) { 10 | isprime.resize(n + 1); 11 | for (int i = 0; i <= n; i++) { 12 | isprime[i] = true; 13 | } 14 | isprime[1] = false; isprime[2] = true; 15 | for (int i = 2; i <= n; i++) { 16 | if (isprime[i]) { 17 | for (int j = 2*i; j < n; j+=i) { 18 | isprime[j] = false; 19 | } 20 | } 21 | } 22 | for (int i = 2; i < n; i++) { 23 | if (isprime[i]) { 24 | primes.push_back(i); 25 | } 26 | } 27 | return; 28 | } 29 | -------------------------------------------------------------------------------- /src/quick_select_order_stat_linear.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Quick Select (Find Kth order statistics) 3 | * Usage: quick_select O(N) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | using namespace std; 13 | 14 | int randomised_partition(vector &A, int p, int q){ 15 | int random = (rand() % (q-p+1)) + p; 16 | swap(A[q], A[random]); 17 | int ptr = p; 18 | for (int i = p; i <= q; i++) { 19 | if (A[i] <= A[q]) { 20 | swap(A[i], A[ptr++]); 21 | } 22 | } 23 | return ptr; 24 | } 25 | 26 | int quick_select(vector &A, int p, int q, int k){ 27 | if (p == q) return A[p]; 28 | int pivot = randomised_partition(A, p, q); 29 | if (pivot == k) 30 | return A[pivot]; 31 | else if (k < pivot) { 32 | return quick_select(A, p, pivot - 1, k); 33 | } else { 34 | return quick_select(A, pivot + 1, q, k); 35 | } 36 | } 37 | 38 | int main(){ 39 | srand(time(NULL)); 40 | int t; 41 | cin >> t; 42 | while (t--) { 43 | int n; 44 | scanf("%d", &n); 45 | vector A(n); 46 | for (int i = 0; i < n; i++) scanf("%d", &A[i]); 47 | int q; 48 | cin >> q; 49 | while (q--) { 50 | int k; 51 | cin >> k; 52 | cout << quick_select(A, 0, n - 1, k) << endl; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/rabin_karp.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Rabin-Karp Hashing 3 | * Usage: findSubstring O(N) 4 | * Note: Its not useful as adversary can generate cases like (T="aaaaaaaaaaa", P="aaa"). 5 | * Source: https://github.com/dragonslayerx 6 | */ 7 | 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | 13 | long long pow(long long a, long long b, long long MOD){ 14 | if (b == 0) return 1; 15 | long long p = pow(a, b/2, MOD); 16 | p = (p * p) % MOD; 17 | if (b & 1) { 18 | return (p * a) % MOD; 19 | } else { 20 | return p % MOD; 21 | } 22 | } 23 | 24 | typedef long long int64; 25 | int findSubtring(string T, string P, int d, int MOD){ 26 | int n =T.size(), m = P.size(); 27 | int64 p = 0, t = 0; 28 | int64 h = pow(d, m - 1, MOD); 29 | for (int i = 0; i < m; i++) { 30 | p *= d, p += (P[i] - 'a'), p %= MOD; 31 | t *= d, t += (T[i] - 'a'), t %= MOD; 32 | } 33 | for (int i = 0; i < n - m + 1; i++){ 34 | //cerr << t << " " << p << endl; 35 | if (p == t) { 36 | if (T.substr(i, m) == P) { 37 | return i; 38 | } 39 | } 40 | if (i < n - m) { 41 | t = (((d * (t + MOD - ((T[i] - 'a') * h) % MOD) % MOD) % MOD) + (T[i + m] - 'a')) % MOD; 42 | } 43 | } 44 | return -1; 45 | } 46 | 47 | 48 | int main(){ 49 | cout << findSubtring("swapnil", "n", 26, 1000000007) << endl; 50 | } 51 | -------------------------------------------------------------------------------- /src/range_minimum_query_sparse_table.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Range Min Query using Sparse Table 3 | * Usage: construct O(NlgN), query O(lg(N)) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | const int MAX = 100005; 11 | const int size = 25; 12 | 13 | int rmq[size][MAX]; 14 | 15 | void construct(int a[], int n){ 16 | for (int j = 0; j < n; j++) rmq[0][j] = a[j]; 17 | for (int i = 1; i < size; i++) { 18 | int length = 1<<(i-1); 19 | for (int j = 0; j < n; j++) { 20 | if (j+length > n) rmq[i][j] = max(rmq[i-1][j], 0); 21 | else rmq[i][j] = max(rmq[i-1][j], rmq[i-1][j+length]); 22 | } 23 | } 24 | } 25 | 26 | /** 27 | * Usage: query O(lg(N)) 28 | */ 29 | 30 | int query(int l, int r){ 31 | int length = r-l+1, p = 0; 32 | while ((1 << p) <= length) p++; 33 | p--; 34 | return max(rmq[p][l], rmq[p][r-(1<> n; 40 | int a[MAX]; 41 | for (int i = 0; i < n; i++) cin >> a[i]; 42 | construct(a, n); 43 | int q; 44 | cin >> q; 45 | while (q--) { 46 | int l, r; 47 | cin >> l >> r; 48 | l--, r--; 49 | cout << query(l, r) << endl; 50 | } 51 | } 52 | 53 | /** 54 | * Usage: preprocess O(N), query O(1) 55 | * Note: Call preprocess function before using query function. 56 | 57 | int frameSize[MAX]; 58 | int preprocess(){ 59 | for(int i=0, pow2=1; pow2 < MAX; pow2*=2, i++) 60 | frameSize[pow2]=i; 61 | for(int i=3;i st[4*MAX]; 8 | vector maxUpto[4*MAX]; 9 | 10 | void merge(int currentX, int leftX, int rightX) { 11 | vector ¤t = st[currentX]; 12 | vector &left = st[leftX], &right = st[rightX]; 13 | 14 | int l = 0, r = 0, cur = 0; 15 | while ((l < left.size()) or (r < right.size())) { 16 | if (l == left.size()) current[cur++]=right[r++]; 17 | else if (r == right.size()) current[cur++]=left[l++]; 18 | else { 19 | if (left[l] <= right[r]) { 20 | current[cur++] = left[l++]; 21 | } else { 22 | current[cur++] = right[r++]; 23 | } 24 | } 25 | } 26 | 27 | int sz = maxUpto[currentX].size(); 28 | maxUpto[currentX][sz-1] = current[sz-1].second; 29 | for (int i = sz-2; i >= 0; i--) { 30 | maxUpto[currentX][i]=max(maxUpto[currentX][i+1], current[i].second); 31 | } 32 | 33 | } 34 | 35 | void construct(vector &a, int n, int ll, int rl) { 36 | if (ll==rl) { 37 | st[n].push_back(make_pair(a[ll], ll)); 38 | maxUpto[n].push_back(ll); 39 | } else { 40 | int mid = (ll+rl)/2; 41 | construct(a, 2*n+1, ll, mid); 42 | construct(a, 2*n+2, mid+1, rl); 43 | st[n].resize(rl-ll+1); 44 | maxUpto[n].resize(rl-ll+1); 45 | merge(n, 2*n+1, 2*n+2); 46 | } 47 | } 48 | 49 | //returns max index element > d in [ll..rl]. return -1 if none exists 50 | int query(int n, int ll, int rl, int ql, int qr, int d) { 51 | if (ll >= ql && rl <= qr) { 52 | vector::iterator it = upper_bound(st[n].begin(), st[n].end(), make_pair(d, INF)); 53 | if (it == st[n].begin()) { 54 | return rl; 55 | } else if (it == st[n].end()) { 56 | return -1; 57 | } else { 58 | int p = it-st[n].begin(); 59 | return maxUpto[n][p]; 60 | } 61 | } else { 62 | int mid = (ll+rl)/2; 63 | if (qr <= mid) return query(2*n+1, ll, mid, ql, qr, d); 64 | else if (ql > mid) return query(2*n+2, mid+1, rl, ql, qr, d); 65 | else { 66 | int left = query(2*n+1, ll, mid, ql, qr, d); 67 | int right = query(2*n+2, mid+1, rl, ql, qr, d); 68 | return max(left, right); 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /src/segment_tree_2D.cpp: -------------------------------------------------------------------------------- 1 | e.i/** 2 | * Description: Segment Tree 2D (Support point updates and associative operations like sum, max on a 2-D integer matrix) 3 | * Usage: construct O(NM), 4 | * query O( lg(N) lg(M) ), 5 | * update O( lg(N) lg(M) ) 6 | * Source: https://github.com/dragonslayerx 7 | */ 8 | class SegTree2D { 9 | vector > segtree; 10 | size_t n, m; 11 | 12 | bool OUT(int l, int r, int ql, int qr){ 13 | return (qr < l || ql > r); 14 | } 15 | 16 | bool IN(int l, int r, int ql, int qr){ 17 | return (ql >= l && qr <= r); 18 | } 19 | 20 | long long build_y(int node_x, int lx, int rx, int node_y, int ly, int ry, vector > &array){ 21 | if (ly == ry) { 22 | if (lx == rx) { 23 | segtree[node_x][node_y] = array[lx][ly]; 24 | } else { 25 | segtree[node_x][node_y] = operation(segtree[node_x * 2 + 1][node_y], segtree[node_x * 2 + 2][node_y]); 26 | } 27 | return segtree[node_x][node_y]; 28 | } 29 | int my = (ly + ry)/2; 30 | long long left = build_y(node_x, lx, rx, node_y * 2 + 1, ly, my, array); 31 | long long right = build_y(node_x, lx, rx, node_y * 2 + 2, my + 1, ry, array); 32 | segtree[node_x][node_y] = operation(left, right); 33 | return segtree[node_x][node_y]; 34 | } 35 | 36 | long long build_x(int node_x, int lx, int rx, vector > &array){ 37 | if (lx != rx) {// demarcs that branching is still possible 38 | int mx = (lx + rx)/2; 39 | build_x(node_x * 2 + 1, lx, mx, array); 40 | build_x(node_x * 2 + 2, mx + 1, rx, array); 41 | } 42 | build_y(node_x, lx, rx, 0, 0, m - 1, array); 43 | } 44 | 45 | 46 | long long query_y(int node_x, int node_y, int ly, int ry, int qly, int qry){ 47 | if (OUT(qly, qry, ly, ry)) { 48 | return def; 49 | } else if (IN(qly, qry, ly, ry)) { 50 | return segtree[node_x][node_y]; 51 | } 52 | int my = (ly + ry)/2; 53 | long long left = query_y(node_x, node_y * 2 + 1, ly, my, qly, qry); 54 | long long right = query_y(node_x, node_y * 2 + 2, my + 1, ry, qly, qry); 55 | return operation(left, right); 56 | } 57 | 58 | long long query_x(int node_x, int lx, int rx, int qlx, int qrx, int qly, int qry){ 59 | if (OUT(qlx, qrx, lx, rx)) { 60 | return def; 61 | } else if (IN(qlx, qrx, lx, rx)) { 62 | return query_y(node_x, 0, 0, m - 1, qly, qry); 63 | } 64 | int mx = (lx + rx)/2; 65 | long long left = query_x(node_x * 2 + 1, lx, mx, qlx, qrx, qly, qry); 66 | long long right = query_x(node_x * 2 + 2, mx + 1, rx, qlx, qrx, qly, qry); 67 | return operation(left, right); 68 | } 69 | 70 | long long update_y(int node_x, int lx, int rx, int node_y, int ly, int ry, int uy, int update_value){ 71 | if (uy > ry || uy < ly) { 72 | return segtree[node_x][node_y]; 73 | } 74 | if (ly == ry && ly == uy) { 75 | if (lx == rx) { 76 | segtree[node_x][node_y] = update_value; 77 | } else { 78 | segtree[node_x][node_y] = operation(segtree[node_x * 2 + 1][node_y], segtree[node_x * 2 + 2][node_y]); 79 | } 80 | return segtree[node_x][node_y]; 81 | } 82 | int my = (ly + ry)/2; 83 | long long left = update_y(node_x, lx, rx, node_y * 2 + 1, ly, my, uy, update_value); 84 | long long right = update_y(node_x, lx, rx, node_y * 2 + 2, my + 1, ry, uy, update_value); 85 | segtree[node_x][node_y] = operation(left, right); 86 | return segtree[node_x][node_y]; 87 | } 88 | 89 | void update_x(int node_x, int lx, int rx, int ux, int uy, long long update_value){ 90 | if (ux > rx || ux < lx) { 91 | return; 92 | } if (lx == rx && lx == ux) { 93 | update_y(node_x, lx, rx, 0, 0, m - 1, uy, update_value); 94 | return; 95 | } 96 | int mx = (lx + rx)/2; 97 | update_x(node_x * 2 + 1, lx, mx, ux, uy, update_value); 98 | update_x(node_x * 2 + 2, mx + 1, rx, ux, uy, update_value); 99 | 100 | update_y(node_x, lx, rx, 0, 0, m - 1, uy, update_value); 101 | } 102 | 103 | 104 | public: 105 | SegTree2D(int n, int m, long long def): def(def), n(n), m(m) { 106 | segtree.resize(4*n, vector(4*m)); 107 | } 108 | 109 | SegTree2D(vector > &array, int n, int m, long long def): def(def), n(n), m(m) { 110 | segtree.resize(4*n, vector(4*m)); 111 | construct(array); 112 | } 113 | 114 | void construct(vector > &array){ 115 | build_x(0, 0, n - 1, array); 116 | } 117 | 118 | long long query(int qlx, int qrx, int qly, int qry){ 119 | return query_x(0, 0, n - 1, qlx, qrx, qly, qry); 120 | } 121 | 122 | void update(int ux, int uy, long long update_value){ 123 | update_x(0, 0, n - 1, ux, uy, update_value); 124 | } 125 | 126 | #ifdef DEBUG 127 | void print(){ 128 | for (int i = 0; i < 4*n; i++) { 129 | for (int j = 0; j < 4*m; j++) 130 | printf("(%d, %d)", segtree[i][j].maxx, segtree[i][j].count); 131 | cout << endl; 132 | } 133 | } 134 | #endif 135 | 136 | private: 137 | long long operation(long long left, long long right){ 138 | return max(left, right); 139 | } 140 | }; 141 | 142 | int main() 143 | { 144 | int tc; 145 | scanf("%d", &tc); 146 | for (int t=1; t<=tc; t++) { 147 | printf("Case %d:\n", t); 148 | int n, q; 149 | scanf("%d%d", &n, &q); 150 | vector > array(n, vector (n)); 151 | for (int i = 0; i < n; i++) { 152 | for (int j = 0; j < n; j++) { 153 | scanf("%d", &array[i][j]); 154 | } 155 | } 156 | SegTree2D S(array, n, n, 0); 157 | while (q--) { 158 | int x, y, s; 159 | scanf("%d%d%d", &x, &y, &s); 160 | x--, y--; 161 | //cout << x << " " << y << " " << x+s-1 << " " << y+s-1 << endl; 162 | printf("%d\n", S.query(x, x+s-1, y, y+s-1)); 163 | } 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /src/segment_tree_custom_merge_function.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Segment Tree with custom merge function. 3 | * Usage: construct O(N), query O(lg(N)), update O(lg(N)) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | #define MAX 50100 12 | #define INF -1000000000 13 | 14 | struct node { 15 | int sum; 16 | int maxs, prefix, suffix; 17 | node(){ 18 | sum = prefix = suffix = 0; 19 | maxs = INF; 20 | } 21 | 22 | node(int sum, int maxs, int prefix, int suffix) { 23 | setNode(sum, maxs, prefix, suffix); 24 | } 25 | 26 | void setNode(int sum, int maxs, int prefix, int suffix){ 27 | this->sum =sum; 28 | this->maxs=maxs; 29 | this->prefix=prefix; 30 | this->suffix=suffix; 31 | } 32 | }; 33 | 34 | int a[MAX]; 35 | node st[4*MAX]; 36 | 37 | node merge(node left, node right){ 38 | node t; 39 | t.prefix = max(left.prefix, left.sum+right.prefix); 40 | t.suffix = max(right.suffix, right.sum+left.suffix); 41 | t.sum = left.sum+right.sum; 42 | t.maxs = left.maxs; 43 | t.maxs = max(t.maxs, right.maxs); 44 | t.maxs = max(t.maxs, left.suffix+right.prefix); 45 | return t; 46 | } 47 | 48 | node construct(int n, int ll, int rl){ 49 | if (ll == rl) { 50 | st[n].setNode(a[ll], a[ll], a[ll], a[ll]); 51 | } else { 52 | node left = construct(2*n+1, ll, (ll+rl)/2); 53 | node right = construct(2*n+2, (ll+rl)/2+1, rl); 54 | st[n] = merge(left, right); 55 | } 56 | return st[n]; 57 | } 58 | 59 | node query(int n, int ll, int rl, int x, int y){ 60 | int mid = (ll+rl)/2; 61 | if (x==ll && y==rl) return st[n]; 62 | else if (y <= mid) return query(2*n+1, ll, mid, x, y); 63 | else if (x > mid) return query(2*n+2, mid+1, rl, x, y); 64 | else { 65 | node left = query(2*n+1, ll, (ll+rl)/2, x, mid); 66 | node right = query(2*n+2, (ll+rl)/2+1, rl, mid+1, y); 67 | return merge(left, right); 68 | } 69 | } 70 | 71 | node update(int n, int ll, int rl, int p, int val){ 72 | if (p < ll || p > rl) return st[n]; 73 | if (p == ll && p == rl) { 74 | st[n].setNode(val, val, val, val); 75 | return st[n]; 76 | } else { 77 | int mid = (ll+rl)/2; 78 | node left = update(2*n+1, ll, (ll+rl)/2, p, val); 79 | node right = update(2*n+2, (ll+rl)/2+1, rl, p, val); 80 | st[n] = merge(left, right); 81 | } 82 | return st[n]; 83 | } 84 | 85 | int main() 86 | { 87 | int n; 88 | scanf("%d", &n); 89 | for (int i = 0; i < n; i++) scanf("%d", a+i); 90 | construct(0, 0, n-1); 91 | int q; 92 | scanf("%d", &q); 93 | while (q--) { 94 | int x, y; 95 | scanf("%d%d", &x, &y); 96 | x--, y--; 97 | printf("%d\n", query(0, 0, n-1, x, y).maxs); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/segment_tree_dynamic_reverse_subarray_using_treap.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Dynamic Segment tree (Support for inbetween insertion and array reversal) 3 | * Usage: See below. insert O(lg(N)), reverse O(lg(N)), get O(lg(N)) 4 | * Note: Override augment function appropriately for supporting distinct aggregate operation. 5 | * Source: https://github.com/dragonslayerx 6 | */ 7 | 8 | const int MAX = 100005; 9 | const int MOD = 1000000000+7; 10 | const int INF = 1000000000; 11 | 12 | struct node { 13 | int val, cnt[15]; 14 | int size, pr; 15 | bool rev; 16 | node *l, *r; 17 | node(int val, int pr) { 18 | this->val = val; 19 | this->pr = pr; 20 | this->l = this->r = NULL; 21 | this->rev = false; 22 | this->size = 1; 23 | memset(cnt, 0, sizeof(cnt)); 24 | this->cnt[val]++; 25 | } 26 | 27 | friend ostream& operator <<(ostream &o, node &x) { 28 | o << "{ x= " << &x << ", val=" << x.val << ", size=" << x.size << ", rev=" << x.rev << ", pr=" << x.pr; 29 | o << "l = " << x.l << " " << ", r = " << x.r << " "; 30 | o << " ["; 31 | for (int i = 0; i < 15; i++) { 32 | o << x.cnt[i] << " "; 33 | } 34 | o << "] }"; 35 | } 36 | }; 37 | 38 | 39 | class Treap { 40 | node *root; 41 | 42 | int getSize(node *p) { 43 | if (p == NULL) return 0; 44 | else return p->size; 45 | } 46 | 47 | int getCnt(node *p, int i) { 48 | if (p == NULL) return 0; 49 | else return p->cnt[i]; 50 | } 51 | 52 | void augment(node *p) { 53 | if (p==NULL) return; 54 | else { 55 | if (p->rev) { 56 | if (p->l) p->l->rev ^= 1; 57 | if (p->r) p->r->rev ^= 1; 58 | swap(p->l, p->r); 59 | p->rev=false; 60 | } 61 | p->size = getSize(p->l)+getSize(p->r)+1; 62 | // Change here for support for a different augment function 63 | for (int i = 0; i < 15; i++) p->cnt[i] = getCnt(p->l, i)+getCnt(p->r, i); 64 | p->cnt[p->val]++; 65 | // 66 | } 67 | } 68 | 69 | node* rightRotate(node* x){ 70 | node *y = x->l; 71 | node *B = y->r; 72 | 73 | x->l = B; 74 | y->r = x; 75 | 76 | augment(x); augment(y); 77 | return y; 78 | } 79 | 80 | node* leftRotate(node* x){ 81 | node *y = x->r; 82 | node *B = y->l; 83 | 84 | x->r = B; 85 | y->l = x; 86 | 87 | augment(x); augment(y); 88 | return y; 89 | } 90 | 91 | node* insert(node *p, int pos, int x, int pr) { 92 | if (p==NULL) { 93 | return new node(x, pr); 94 | } else { 95 | augment(p); 96 | int sz = getSize(p->l); 97 | if (pos <= sz) { 98 | p->l = insert(p->l, pos, x, pr); 99 | augment(p); 100 | node* l = p->l; 101 | if (l->pr < p->pr) { 102 | return rightRotate(p); 103 | } 104 | } else { 105 | p->r = insert(p->r, pos-sz-1, x, pr); 106 | augment(p); 107 | node* r = p->r; 108 | if (r->pr < p->pr) { 109 | return leftRotate(p); 110 | } 111 | } 112 | return p; 113 | } 114 | } 115 | 116 | node* merge(node *lt, node *rt) { 117 | if (lt==NULL) return rt; 118 | else if (rt==NULL) return lt; 119 | else { 120 | if (lt->pr < rt->pr) { 121 | augment(lt); 122 | lt->r = merge(lt->r, rt); 123 | augment(lt); 124 | return lt; 125 | } else { 126 | augment(rt); 127 | rt->l = merge(lt, rt->l); 128 | augment(rt); 129 | return rt; 130 | } 131 | } 132 | } 133 | 134 | pair split(node* p, int pos) { 135 | node* tmpRt = insert(p, pos, 0, -1); 136 | return make_pair(tmpRt->l, tmpRt->r); 137 | } 138 | 139 | void inorder(node *p, ostream &o) { 140 | if (p==NULL) return; 141 | else { 142 | inorder(p->l, o); 143 | o << *p << endl; 144 | inorder(p->r, o); 145 | } 146 | } 147 | 148 | public: 149 | Treap(){ 150 | srand(time(NULL)); 151 | root=NULL; 152 | } 153 | 154 | void insert(int pos, int x) { 155 | root = insert(root, pos, x, rand()); 156 | } 157 | 158 | void reverse(int l, int r) { 159 | pair p = split(root, l); 160 | pair q = split(p.second, r-l+1); 161 | (q.first)->rev ^= 1; 162 | root = merge(merge(p.first, q.first), q.second); 163 | } 164 | 165 | void get(int l, int r, int cnt[]) { 166 | pair p = split(root, l); 167 | pair q = split(p.second, r-l+1); 168 | for (int i = 0; i < 15; i++) { 169 | cnt[i] = (q.first)->cnt[i]; 170 | } 171 | root = merge(merge(p.first, q.first), q.second); 172 | } 173 | 174 | void inorder(ostream &o) { 175 | inorder(root, o); 176 | } 177 | 178 | friend std::ostream& operator<<(ostream &o, Treap D) { 179 | D.inorder(o); 180 | return o; 181 | } 182 | 183 | }; 184 | -------------------------------------------------------------------------------- /src/segment_tree_dynamic_using_treaps.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Dynamic segment tree (Perform associative operations on dynamic array. Support insertion, deletion of elements at any index, point updates) 3 | * Usage: insert O(lg(N)), erase O(lg(N)), update O(lg(N)), query O(lg(N)) 4 | * Source: https://github.com/dragonslayerx 5 | * Note: Override augment function for supporting other associative operations 6 | */ 7 | 8 | template 9 | struct node { 10 | Tv val, mval; 11 | int size, pr; 12 | node *l, *r; 13 | node(Tv val, int pr) { 14 | this->val = this->mval = val; 15 | this->size = 1; 16 | this->pr = pr; 17 | this->l = this->r = NULL; 18 | } 19 | }; 20 | 21 | template 22 | ostream& operator <<(ostream &o, node &x) { 23 | o << "{val=" << x.val << ", mval=" << x.mval << ", size=" << x.size << ", pr=" << x.pr << "}"; 24 | return o; 25 | } 26 | 27 | template 28 | class DST { 29 | node *root; 30 | 31 | int getSize(node *p) { 32 | if (p == NULL) return 0; 33 | else return p->size; 34 | } 35 | 36 | Tv getVal(node *p) { 37 | if (p==NULL) return 0; 38 | else return p->mval; 39 | } 40 | 41 | void augment(node *p) { 42 | if (p==NULL) return; 43 | else { 44 | p->size = getSize(p->l) + getSize(p->r) + 1; 45 | // Change here 46 | p->mval = p->val + getVal(p->l) + getVal(p->r); 47 | } 48 | } 49 | 50 | node* rightRotate(node* x){ 51 | node *y = x->l; 52 | node *B = y->r; 53 | 54 | x->l = B; 55 | y->r = x; 56 | 57 | augment(x); augment(y); 58 | return y; 59 | } 60 | 61 | node* leftRotate(node* x){ 62 | node *y = x->r; 63 | node *B = y->l; 64 | 65 | x->r = B; 66 | y->l = x; 67 | 68 | augment(x); augment(y); 69 | return y; 70 | } 71 | 72 | node* insert(node *p, int pos, Tv x, int pr) { 73 | if (p==NULL) { 74 | return new node(x, pr); 75 | } else { 76 | int sz = getSize(p->l); 77 | if (pos <= sz) { 78 | p->l = insert(p->l, pos, x, pr); 79 | augment(p); 80 | node *l = p->l; 81 | if (l->pr < p->pr) { 82 | return rightRotate(p); 83 | } 84 | } else { 85 | p->r = insert(p->r, pos-sz-1, x, pr); 86 | augment(p); 87 | node *r = p->r; 88 | if (r->pr < p->pr) { 89 | return leftRotate(p); 90 | } 91 | } 92 | return p; 93 | } 94 | } 95 | 96 | void update(node *p, int pos, Tv x) { 97 | int sz = getSize(p->l); 98 | if (pos == sz) { 99 | p->val += x; 100 | } else if (pos < sz) { 101 | update(p->l, pos, x); 102 | } else { 103 | update(p->r, pos-sz-1, x); 104 | } 105 | augment(p); 106 | } 107 | 108 | 109 | node* merge(node *lt, node *rt) { 110 | if (lt==NULL) return rt; 111 | else if (rt==NULL) return lt; 112 | else { 113 | if (lt->pr < rt->pr) { 114 | lt->r = merge(lt->r, rt); 115 | augment(lt); 116 | return lt; 117 | } else { 118 | rt->l = merge(lt, rt->l); 119 | augment(rt); 120 | return rt; 121 | } 122 | } 123 | } 124 | 125 | pair*, node*> split(node *p, int pos) { 126 | node *tmpRt = insert(p, pos, 0, -1); 127 | return make_pair(tmpRt->l, tmpRt->r); 128 | } 129 | 130 | void inorder(node *p, ostream &o) { 131 | if (p==NULL) return; 132 | else { 133 | inorder(p->l, o); 134 | o << *p << endl; 135 | inorder(p->r, o); 136 | } 137 | } 138 | 139 | public: 140 | DST() {srand(time(NULL)); this->root = NULL;} 141 | 142 | void insert(int pos, Tv x) { 143 | root = insert(root, pos, x, rand()%100000); 144 | } 145 | 146 | void update(int pos, Tv x) { 147 | update(root, pos, x); 148 | } 149 | 150 | void erase(int pos) { 151 | pair*, node*> p = split(root, pos); 152 | pair*, node*> q = split(p.second, 1); 153 | root = merge(p.first, q.second); 154 | } 155 | 156 | Tv query(int l, int r) { 157 | pair*, node* > p = split(root, l); 158 | pair*, node* > q = split(p.second, r-l+1); 159 | Tv v = q.first->mval; 160 | root = merge(merge(p.first, q.first), q.second); 161 | return v; 162 | } 163 | 164 | void inorder(ostream &o) { 165 | inorder(root, o); 166 | } 167 | 168 | friend std::ostream& operator<<(ostream &o, DST D) { 169 | D.inorder(o); 170 | return o; 171 | } 172 | }; 173 | -------------------------------------------------------------------------------- /src/segment_tree_persistent.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Persistent Segment trees (Version Query) 3 | * Usage: See below update O(lg(N)), query O(lg(N)), construct O(Nlg(N)) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | struct Node { 8 | long long value; 9 | Node *left, *right; 10 | Node() { 11 | left=right=NULL; 12 | } 13 | }; 14 | 15 | const int MAX = 100005; // # of updates 16 | Node *root[MAX]; 17 | class PersistentST { 18 | 19 | const int n; //size of array 20 | int version; // current version 21 | int size; 22 | 23 | Node* createNewNode() { 24 | return new Node; 25 | } 26 | 27 | long long mergeFunction(Node *left, Node *right) { 28 | return left->value + right->value; 29 | } 30 | 31 | 32 | Node* construct(long long val[], int l, int r) { 33 | Node *x = createNewNode();; 34 | if (l == r) { 35 | x->value = (val==NULL)?0:val[l]; // NULL in case to be initialized with 0 initially 36 | return x; 37 | } else { 38 | int mid = (l+r)/2; 39 | x->left = construct(val, l, mid); 40 | x->right = construct(val, mid+1, r); 41 | x->value = mergeFunction(x->left, x->right); 42 | return x; 43 | } 44 | } 45 | 46 | Node* update(int l, int r, Node *prevVersionPtr, const int pos, const long long updatedVal) { 47 | Node *x = createNewNode(); 48 | if (l == r) { 49 | x->value = prevVersionPtr->value + updatedVal; 50 | } else { 51 | int mid = (l+r)/2; 52 | if (pos <= mid) { 53 | x->left = update(l, mid, prevVersionPtr->left, pos, updatedVal); 54 | x->right = prevVersionPtr->right; 55 | } else { 56 | x->right = update(mid+1, r, prevVersionPtr->right, pos, updatedVal); 57 | x->left = prevVersionPtr->left; 58 | } 59 | x->value = mergeFunction(x->left, x->right); 60 | } 61 | return x; 62 | } 63 | 64 | long long query(Node *x, int l, int r, const int ql, const int qr) { 65 | if (r < ql || l > qr) { 66 | return 0; 67 | } else if (l >= ql && r <= qr) { 68 | return x->value; 69 | } else { 70 | int mid = (l+r)/2; 71 | long long left = query(x->left, l, mid, ql, qr); 72 | long long right = query(x->right, mid+1, r, ql, qr); 73 | return left+right; 74 | } 75 | } 76 | 77 | public: 78 | 79 | PersistentST(int n): n(n) { 80 | version = 0; 81 | size = 0; 82 | } 83 | 84 | void construct(long long val[]) { 85 | root[0]=construct(val, 0, n-1); 86 | } 87 | 88 | void update(int p, long long x) { 89 | root[version+1]=update(0, n-1, root[version], p, x); 90 | version++; 91 | } 92 | 93 | long long query(int queryVersion, int l, int r) { 94 | return query(root[queryVersion], 0, n-1, l, r); 95 | } 96 | 97 | Node *getVersion(int ver) { 98 | return root[ver]; 99 | } 100 | }; 101 | 102 | int main() { 103 | long long a[5] = {1, 2, 3, 4, 5}; 104 | PersistentST S(5); 105 | S.construct(a); 106 | cout << S.query(0, 1, 2) << endl; 107 | S.update(1, 5); 108 | cout << S.query(1, 1, 2) << endl; 109 | } 110 | -------------------------------------------------------------------------------- /src/segment_tree_persistent_order_stat.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Persistent Segment trees (Order Statistics) 3 | * Usage: See below 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | using namespace std; 13 | 14 | struct Node { 15 | long long value; 16 | Node *left, *right; 17 | Node() { 18 | left=right=NULL; 19 | } 20 | }; 21 | 22 | const int MAX = 100005; // # of updates 23 | Node *root[MAX]; 24 | class PersistentST { 25 | 26 | const int n; //size of array 27 | int version; // current version 28 | int size; 29 | 30 | Node* createNewNode() { 31 | return new Node; 32 | } 33 | 34 | long long mergeFunction(Node *left, Node *right) { 35 | return left->value + right->value; 36 | } 37 | 38 | 39 | Node* construct(long long val[], int l, int r) { 40 | Node *x = createNewNode();; 41 | if (l == r) { 42 | x->value = (val==NULL)?0:val[l]; // NULL in case to be initialized with 0 initially 43 | return x; 44 | } else { 45 | int mid = (l+r)/2; 46 | x->left = construct(val, l, mid); 47 | x->right = construct(val, mid+1, r); 48 | x->value = mergeFunction(x->left, x->right); 49 | return x; 50 | } 51 | } 52 | 53 | Node* update(int l, int r, Node *prevVersionPtr, const int pos, const long long updatedVal) { 54 | Node *x = createNewNode(); 55 | if (l == r) { 56 | x->value = prevVersionPtr->value + updatedVal; 57 | } else { 58 | int mid = (l+r)/2; 59 | if (pos <= mid) { 60 | x->left = update(l, mid, prevVersionPtr->left, pos, updatedVal); 61 | x->right = prevVersionPtr->right; 62 | } else { 63 | x->right = update(mid+1, r, prevVersionPtr->right, pos, updatedVal); 64 | x->left = prevVersionPtr->left; 65 | } 66 | x->value = mergeFunction(x->left, x->right); 67 | } 68 | return x; 69 | } 70 | 71 | long long query(Node *x, int l, int r, const int ql, const int qr) { 72 | if (r < ql || l > qr) { 73 | return 0; 74 | } else if (l >= ql && r <= qr) { 75 | return x->value; 76 | } else { 77 | int mid = (l+r)/2; 78 | long long left = query(x->left, l, mid, ql, qr); 79 | long long right = query(x->right, mid+1, r, ql, qr); 80 | return left+right; 81 | } 82 | } 83 | 84 | public: 85 | 86 | PersistentST(int n): n(n) { 87 | version = 0; 88 | size = 0; 89 | } 90 | 91 | void construct(long long val[]) { 92 | root[0]=construct(val, 0, n-1); 93 | } 94 | 95 | void update(int p, long long x) { 96 | root[version+1]=update(0, n-1, root[version], p, x); 97 | version++; 98 | } 99 | 100 | long long query(int queryVersion, int l, int r) { 101 | return query(root[queryVersion], 0, n-1, l, r); 102 | } 103 | 104 | Node *getVersion(int ver) { 105 | return root[ver]; 106 | } 107 | }; 108 | 109 | class OrderStat { 110 | public: 111 | const int n; 112 | PersistentST S; 113 | 114 | OrderStat(long long a[], int n) : n(n), S(n) { 115 | S.construct(NULL); 116 | // Map all elements of a from 0..n-1 first 117 | for (int i = 0; i < n; i++) { 118 | S.update(a[i], +1); 119 | } 120 | /*for (int i = 0; i <= n; i++) { 121 | for (int j = 0; j < n; j++) { 122 | cout << S.query(i, j, j) << " "; 123 | } 124 | cout << endl; 125 | }*/ 126 | } 127 | 128 | int getOrderStat(int ql, int qr, int k) { 129 | assert(k <= qr-ql+1); 130 | int l = 0, r = n-1; 131 | Node *pL = S.getVersion(ql), *pR = S.getVersion(qr+1); 132 | while (l < r) { 133 | int mid = (l+r)/2; 134 | int count = (pR->left->value - pL->left->value); 135 | if (count >= k) { 136 | pL=pL->left, pR=pR->left; 137 | r = mid; 138 | } else { 139 | k-=count; 140 | pL=pL->right, pR=pR->right; 141 | l = mid+1; 142 | } 143 | } 144 | return l; 145 | } 146 | }; 147 | 148 | int main() { 149 | long long a[5] = {1, 1, 3, 2, 4}; 150 | OrderStat O(a, 5); 151 | cout << O.getOrderStat(0, 4, 5) << endl;; 152 | } 153 | -------------------------------------------------------------------------------- /src/segment_tree_range_query_point_update.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Segment Tree Range query Point update. 3 | * Usage: construct O(N), update O(lg(N)), query O(lg(N)) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | #define MAX 100005 14 | 15 | long long a[MAX]; 16 | 17 | int st[4*MAX]; 18 | 19 | int construct (int node, int ll, int rl){ 20 | if (ll == rl) st[node] = a[ll]; 21 | else { 22 | int left = construct(2*node+1, ll, (ll+rl)/2); 23 | int right = construct(2*node+2, (ll+rl)/2 + 1, rl); 24 | st[node] = left + right; 25 | } 26 | return st[node]; 27 | } 28 | 29 | int query(int node, int ll, int rl, int ql, int qr){ 30 | if (ll >= ql && rl <= qr) return st[node]; 31 | else if (rl < ql || ll > qr) return 0; 32 | int left = query(2*node+1, ll, (ll+rl)/2, ql, qr); 33 | int right = query(2*node+2, (ll+rl)/2 + 1, rl, ql, qr); 34 | return left + right; 35 | } 36 | 37 | int update(int node, int ll, int rl, int q, int val){ 38 | if (rl < q || ll > q) return st[node]; 39 | if (q == ll && q == rl) st[node] = val; 40 | else { 41 | int left = update(2*node+1, ll, (ll+rl)/2, q, val); 42 | int right = update(2*node+2, (ll+rl)/2 + 1, rl, q, val); 43 | st[node] = left + right; 44 | } 45 | return st[node]; 46 | } 47 | 48 | 49 | int main() 50 | { 51 | int tc; 52 | scanf("%d", &tc); 53 | for (int t=1; t<=tc; t++ ) { 54 | printf("Case %d:\n", t); 55 | memset(a, 0, sizeof(a)); 56 | int n, q; 57 | scanf("%d%d", &n, &q); 58 | for (int i = 0; i < n; i++) 59 | scanf("%lld", &a[i]); 60 | construct(0, 0, n-1); 61 | while (q--) { 62 | int x, y; 63 | scanf("%d%d", &x, &y); 64 | x--, y--; 65 | printf("%d\n", query(0, 0, n-1, x, y)); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/segment_tree_range_query_range_update_lazy_propogation.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Segment Tree Range query Range update. 3 | * Usage: construct O(N), update O(lg(N)), query O(lg(N)) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | using namespace std; 14 | 15 | #define MAX 100100 16 | 17 | struct node { 18 | long long val, lazy; 19 | bool flag; 20 | node() 21 | { 22 | val = lazy = 0; 23 | flag = false; 24 | } 25 | }; 26 | 27 | node st[4*MAX]; 28 | 29 | long long query(int n, int ll, int rl, int ql, int qr) 30 | { 31 | if (st[n].flag) { 32 | st[n].val += (rl-ll+1)*st[n].lazy; 33 | if (ll != rl) { 34 | st[(n<<1)+1].flag = true; 35 | st[(n<<1)+1].lazy += st[n].lazy; 36 | st[(n<<1)+2].flag = true; 37 | st[(n<<1)+2].lazy += st[n].lazy; 38 | } 39 | st[n].flag = false; 40 | st[n].lazy = 0; 41 | } 42 | 43 | if (qr < ll || ql > rl) return 0; 44 | if (ll >= ql && rl <= qr) return st[n].val; 45 | else { 46 | long long left = query((n<<1)+1, ll, ((ll+rl)>>1), ql, qr); 47 | long long right = query((n<<1)+2, ((ll+rl)>>1) + 1, rl, ql, qr); 48 | return left + right; 49 | } 50 | } 51 | 52 | node update(int n, int ll, int rl, int ql, int qr, long long val) 53 | { 54 | //cout << n << " " << ll << " " << rl << " " << ql << " " << qr << endl; 55 | if (st[n].flag) { 56 | st[n].val += (rl-ll+1)*st[n].lazy; 57 | if (ll != rl) { 58 | st[(n<<1)+1].flag = true; 59 | st[(n<<1)+1].lazy += st[n].lazy; 60 | st[(n<<1)+2].flag = true; 61 | st[(n<<1)+2].lazy += st[n].lazy; 62 | } 63 | st[n].flag = false; 64 | st[n].lazy = 0; 65 | } 66 | 67 | if (qr < ll || ql > rl) return st[n]; 68 | if (ll >= ql && rl <= qr) { 69 | st[n].val += (rl-ll+1)*val; 70 | if (ll != rl) { 71 | st[(n<<1)+1].flag = true; 72 | st[(n<<1)+1].lazy += val; 73 | st[(n<<1)+2].flag = true; 74 | st[(n<<1)+2].lazy += val; 75 | } 76 | } else { 77 | node left = update((n<<1)+1, ll, ((ll+rl)>>1), ql, qr, val); 78 | node right = update((n<<1)+2, ((ll+rl)>>1) + 1, rl, ql, qr, val); 79 | st[n].val = left.val + right.val; 80 | } 81 | return st[n]; 82 | } 83 | 84 | int main() 85 | { 86 | int tc; 87 | scanf("%d", &tc); 88 | for (int t = 1; t <= tc; t++) { 89 | memset(st, 0, sizeof(st)); 90 | printf("Case %d:\n", t); 91 | int n, q; 92 | scanf("%d%d", &n, &q); 93 | while (q--) { 94 | int ch; 95 | scanf("%d", &ch); 96 | int x, y; 97 | scanf("%d%d", &x, &y); 98 | if (ch) 99 | printf("%lld\n", query(0, 0, n-1, x, y)); 100 | else { 101 | long long val; 102 | scanf("%lld", &val); 103 | update(0, 0, n-1, x, y, val); 104 | } 105 | /*for (int i = 0; i < 4*n; i++) { 106 | cout << "(" << st[i].mod0 << " " << st[i].mod1 << " " << st[i].mod2 << " " << st[i].flag << " " << st[i].lazy << "), "; 107 | }*/ 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/segment_trees_interative_fast.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Fast iterative segment tree. 3 | * Usgae: build O(N), query O(lg(N)), modify O(lg(N)) 4 | * Note: The code is taken from http://codeforces.com/blog/entry/18051 5 | * Source: https://github.com/dragonslayerx 6 | */ 7 | 8 | int n,m,q; 9 | int arr[600][600]; 10 | int a,b,t[50000]; 11 | 12 | void build(){ 13 | for(int i = n - 1; i > 0 ; --i) t[i] = max(t[i<<1], t[i<<1|1]); 14 | } 15 | 16 | void modify(int p, int v){ 17 | for(t[p += n] = v; p > 1 ; p>>=1) t[p>>1] = max(t[p], t[p^1]); 18 | } 19 | 20 | int query(int l, int r){ 21 | int ans = 0; 22 | for(l += n, r+=n; l < r; l >>= 1, r >>= 1) 23 | ans = max(ans, max( ((l&1) ? t[l++] : 0), ((r&1) ? t[--r] : 0))); 24 | return ans; 25 | } 26 | -------------------------------------------------------------------------------- /src/segmented_sieve_large_primes.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Get primes in range [ll, ul]. 3 | * Usage: getPrimes. O(NlgN) where N = ul-ll+1 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | void getPrimes(int ll, int ul, set &largePrimes) { 8 | vector isprm; 9 | isprm.resize(ul - ll + 1); 10 | for(int i = 0; i < ul - ll + 1; i++) { 11 | isprm[i] = 1; 12 | } 13 | for (int i = 2; i*i <= ul; i++) { 14 | if (isprime[i]) { 15 | int j; 16 | j = ll / i; 17 | for(; i * j <= ul; j++) { 18 | if (i * j >= ll && j > 1) { 19 | isprm[i * j - ll] = 0; 20 | } 21 | } 22 | } 23 | } 24 | for (int i = ll; i <= ul; i++) { 25 | if (isprm[i - ll] && i > 1) { 26 | largePrimes.insert(i); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/string_hashing.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: String Hashing 3 | * Usage: initalize O(N), getHash O(n), getSubHash O(1), getRevSubHash O(1) 4 | * Note: In case double hashing is required http://codeforces.com/contest/710/submission/20094958 5 | * Source: https://github.com/dragonslayerx 6 | */ 7 | 8 | long long power(long long n, long long m, long long MOD){ 9 | if (m == 0) return 1; 10 | long long x = power(n, m/2, MOD); 11 | if (!(m & 1)) return (x * x) % MOD; 12 | else return (((x * x) % MOD) * n) % MOD; 13 | } 14 | 15 | class StringHash { 16 | const static int MAX = 300005; 17 | 18 | ll b = 100000009; 19 | ll m = 1000000007; 20 | 21 | ll B[MAX], inverseB[MAX]; 22 | 23 | void initialize() { 24 | B[0]=1; 25 | for (int i = 1; i < MAX; i++) { 26 | B[i]=(B[i-1]*b)%m; 27 | } 28 | inverseB[MAX-1]=power(B[MAX-1], m-2, m); 29 | for (int i = MAX-2; i >= 0; i--) { 30 | inverseB[i]=(inverseB[i+1]*b)%m; 31 | } 32 | } 33 | 34 | public: 35 | StringHash() { 36 | initialize(); 37 | } 38 | 39 | ll getHash(char *s) { 40 | long long h = 0; 41 | for (int i = 0; s[i]; i++) { 42 | h = (h + (s[i] * B[i])) % m; 43 | } 44 | return h; 45 | } 46 | 47 | int length=0; 48 | ll h[MAX], revh[MAX]; 49 | ll construct(char *s) { 50 | length = strlen(s); 51 | h[0]=0, revh[length+1]=0; 52 | for (int i = 0, j = 1; s[i]; i++, j++) { 53 | h[j] = (h[j-1] + (s[i] * B[i]) % m) % m ; 54 | } 55 | for (int i = length-1, j = length, k = 0; i >= 0; i--, j--, k++) { 56 | revh[j] = (revh[j+1] + ((s[i] * B[k]) % m)) % m; 57 | } 58 | return h[length]; 59 | } 60 | 61 | ll getSubHash(int i, int j) { 62 | i++, j++; 63 | return ((h[j] + (m-h[i-1])) * inverseB[i-1]) % m; 64 | } 65 | 66 | ll getRevHash(int i, int j) { 67 | i++, j++; 68 | return ((revh[i] + (m-revh[j+1])) * inverseB[length-j]) % m; 69 | } 70 | }; 71 | -------------------------------------------------------------------------------- /src/string_hashing_dynamic_segment_trees.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Dynamic String Hashing (Supports updating string characters) 3 | * Usage: See below, update O(lg(N)), getHash O(lg(N)) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | long long power(long long n, long long m, long long MOD) 8 | { 9 | if (m == 0) return 1; 10 | long long x = power(n, m / 2, MOD); 11 | if (!(m & 1)) return (x * x) % MOD; 12 | else return (((x * x) % MOD) * n) % MOD; 13 | } 14 | 15 | const long long B = 100000007; 16 | const long long M = 1000000009; 17 | const long long invB = power(B-1, M-2, M); //inverse of B-1 18 | 19 | long long pB[MAX]; 20 | void pInit() { 21 | pB[0] = 1; 22 | for (int i = 1; i < MAX; i++) { 23 | pB[i] = (pB[i-1] * B) % M; 24 | } 25 | } 26 | 27 | struct node { 28 | long long val; 29 | bool flag; 30 | long long lazy; 31 | node() { 32 | flag = false; 33 | val = lazy = 0; 34 | } 35 | } st[4*MAX]; 36 | 37 | long long update(int n, int l, int r, int ql, int qr, int c) { 38 | if (st[n].flag) { 39 | st[n].val = (((st[n].lazy * (pB[r-l+1]+M-1) % M) % M) * invB) % M; 40 | if (l != r) { 41 | st[2*n+1].flag = true; 42 | st[2*n+1].lazy = st[n].lazy; 43 | st[2*n+2].flag = true; 44 | st[2*n+2].lazy = st[n].lazy; 45 | } 46 | st[n].flag = false; 47 | st[n].lazy = 0; 48 | } 49 | 50 | if (qr < l or ql > r) { 51 | return st[n].val; 52 | } else if (l >= ql and r <= qr) { 53 | st[n].val = (((c * (pB[r-l+1]+M-1) % M) % M) * invB) % M; 54 | if (l != r) { 55 | st[2*n+1].flag = true; 56 | st[2*n+1].lazy = c; 57 | st[2*n+2].flag = true; 58 | st[2*n+2].lazy = c; 59 | } 60 | return st[n].val; 61 | } else { 62 | int mid = (l + r)/2; 63 | long long leftHash = update(2*n+1, l, mid, ql, qr, c); 64 | long long rightHash = update(2*n+2, mid+1, r, ql, qr, c); 65 | st[n].val = ((leftHash * pB[r - mid]) % M + rightHash) % M; 66 | return st[n].val; 67 | } 68 | } 69 | 70 | long long getHash(int n, int l, int r, int ql, int qr) { 71 | if (st[n].flag) { 72 | st[n].val = (((st[n].lazy * (pB[r-l+1]+M-1) % M) % M) * invB) % M; 73 | if (l != r) { 74 | st[2*n+1].flag = true; 75 | st[2*n+1].lazy = st[n].lazy; 76 | st[2*n+2].flag = true; 77 | st[2*n+2].lazy = st[n].lazy; 78 | } 79 | st[n].flag = false; 80 | st[n].lazy = 0; 81 | } 82 | if (qr < l or ql > r) { 83 | return 0; 84 | } else if (l >= ql && r <= qr) { 85 | return (st[n].val * pB[qr - r]) % M; 86 | } else { 87 | int mid = (l + r)/2; 88 | long long leftHash = getHash(2*n+1, l, mid, ql, qr); 89 | long long rightHash = getHash(2*n+2, mid+1, r, ql, qr); 90 | long long h = (leftHash + rightHash) % M; 91 | return h; 92 | } 93 | } 94 | 95 | int main(){ 96 | pInit(); 97 | int n, m, k; 98 | scanf("%d%d%d", &n, &m, &k); 99 | char s[MAX]; 100 | scanf("%s", s); 101 | for (int i = 0; i < n; i++) { 102 | update(0, 0, n-1, i, i, s[i] - '0'); 103 | } 104 | for (int i = 0; i < m+k; i++) { 105 | int choice; 106 | scanf("%d", &choice); 107 | if (choice == 1){ 108 | int l, r, c; 109 | scanf("%d%d%d", &l, &r, &c); 110 | l--, r--; 111 | update(0, 0, n-1, l, r, c); 112 | } else if (choice == 2) { 113 | int l, r, c; 114 | scanf("%d%d%d", &l, &r, &c); 115 | l--, r--; 116 | if (r-c < l) { 117 | printf("YES\n"); 118 | } else { 119 | long long h1 = getHash(0, 0, n-1, l, r-c); 120 | long long h2 = getHash(0, 0, n-1, l+c, r); 121 | if (h1 == h2) { 122 | printf("YES\n"); 123 | } else { 124 | printf("NO\n"); 125 | } 126 | } 127 | } 128 | } 129 | } 130 | 131 | -------------------------------------------------------------------------------- /src/strongly_connected_components_kosaraju.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Strictly Connected Component decomposition 3 | * Usage: See below. O(V+E) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | using namespace std; 13 | 14 | typedef vector > graph; 15 | class SCC { 16 | static const int MAX = 100005; 17 | 18 | void transpose(vector > &G, vector > >) 19 | { 20 | GT.resize(G.size()); 21 | for (int i = 0; i < G.size(); i++) { 22 | for (int j = 0; j < G[i].size(); j++) { 23 | int v = G[i][j]; 24 | GT[v].push_back(i); 25 | } 26 | } 27 | } 28 | 29 | public: 30 | //This fucntion can be used for toposort 31 | void decomposeSCC(graph &G, int u, bool isVisited[], vector &sortedList) 32 | { 33 | isVisited[u] = true; 34 | for (int i = 0; i < G[u].size(); i++) { 35 | int v = G[u][i]; 36 | if (isVisited[v] == false) { 37 | decomposeSCC(G, v, isVisited, sortedList); 38 | } 39 | } 40 | sortedList.push_back(u); 41 | } 42 | 43 | vector > decompose(graph &G) 44 | { 45 | vector > SCCList; 46 | bool isVisited[MAX] = {false}; 47 | vector sortedList; 48 | for (int i = 0; i < G.size(); i++) { 49 | if (!isVisited[i]) { 50 | decomposeSCC(G, i, isVisited, sortedList); 51 | } 52 | } 53 | reverse(sortedList.begin(), sortedList.end()); 54 | vector > GT; 55 | transpose(G, GT); 56 | memset(isVisited, 0, sizeof(isVisited)); 57 | for (int i = 0; i < sortedList.size(); i++) { 58 | int source = sortedList[i]; 59 | if (!isVisited[source]) { 60 | vector scc; 61 | decomposeSCC(GT, source, isVisited, scc); 62 | SCCList.push_back(scc); 63 | } 64 | } 65 | return SCCList; 66 | } 67 | }; 68 | 69 | int main() 70 | { 71 | SCC S; 72 | vector > G; 73 | int n, m; 74 | cin >> n >> m; 75 | G.resize(n); 76 | for (int i = 0; i < m; i++) { 77 | int a, b; 78 | cin >> a >> b; 79 | a--, b--; 80 | G[a].push_back(b); 81 | } 82 | vector > SCCList = S.decompose(G); 83 | for (int i = 0; i < SCCList.size(); i++) { 84 | for (int j = 0; j < SCCList[i].size(); j++) { 85 | cout << SCCList[i][j] << " "; 86 | } 87 | cout << endl; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/subtree size and level.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Get size of subtree and level for a node in a rooted tree 3 | * Usage: calcSize O(V) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | ll stSize[200005]; 8 | int lvl[200005]; 9 | int calcSize(vector > &T, int u, int parent, int level){ 10 | stSize[u] = 1; 11 | lvl[u]=level; 12 | for (int i = 0; i < T[u].size(); i++) { 13 | int v = T[u][i]; 14 | if (v != parent) { 15 | stSize[u] += calcSize(T, v, u, level+1); 16 | } 17 | } 18 | return stSize[u]; 19 | } -------------------------------------------------------------------------------- /src/ternary_search.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Ternary search 3 | * Usage: getMax O(lg(N)) 4 | * Note: The function f should be strictly increasing and then strictly decreasing. 5 | * See http://codeforces.com/blog/entry/11497 for more help. 6 | * Source: https://github.com/dragonslayerx 7 | */ 8 | 9 | ll f(int mid) { 10 | 11 | } 12 | 13 | ll getMax(int ll, int rr) { 14 | int lo = ll, hi = rr; 15 | while(lo < hi) { 16 | int mid = (lo + hi) >> 1; 17 | if(f(mid) > f(mid+1)) { 18 | hi = mid; 19 | } else { 20 | lo = mid+1; 21 | } 22 | } 23 | return lo+1; 24 | } 25 | -------------------------------------------------------------------------------- /src/topological_sort_kosaraju.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Topological sorting 3 | * Usage: See below O(V + E) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | const int MAX = 10050; 8 | 9 | bool isvisited[MAX]; 10 | vector s; 11 | vector > g; 12 | 13 | void dfs(int u) 14 | { 15 | isvisited[u] = 1; 16 | for (int i = 0; i < g[u].size(); i++) { 17 | int v = g[u][i]; 18 | if (!isvisited[v]) { 19 | dfs(v); 20 | } 21 | } 22 | s.push_back(u); 23 | } 24 | 25 | int main() 26 | { 27 | int n, m; 28 | cin >> n >> m; 29 | g.resize(n); 30 | for (int i = 0; i < m; i++) { 31 | int a, b; 32 | cin >> a >> b; 33 | a--, b--; 34 | g[a].push_back(b); 35 | } 36 | for (int i = 0; i < n; i++) { 37 | if (!isvisited[i]) dfs(i); 38 | } 39 | reverse(s.begin(), s.end()); 40 | for (int i = 0; i < s.size(); i++) { 41 | cout << s[i]+1 << " "; 42 | } 43 | cout << endl; 44 | } 45 | -------------------------------------------------------------------------------- /src/tree_dfs_preorder_postorder_isInSubtree.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Preorder and Postorder stamps (Finds the preorder and postorder stamps for vertices of tree. Useful for checking if vertex is in subtree) 3 | * Usage: preprocess O(V) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | const int MAX = 100005; 11 | 12 | vector< vector > T; 13 | 14 | int prestamp[MAX], poststamp[MAX]; 15 | int counter = 0; 16 | void preprocess(int u, int p) { 17 | prestamp[u] = counter++; 18 | for (int v : T[u]) { 19 | if (v != p) { 20 | preprocess(v, u); 21 | } 22 | } 23 | poststamp[u] = counter++; 24 | } 25 | 26 | bool isInSubtree(int u, int v) { 27 | return ((prestamp[u] <= prestamp[v]) && (poststamp[u] >= poststamp[v])); 28 | } 29 | 30 | int main() { 31 | int n; 32 | cin >> n; 33 | T.resize(n); 34 | for (int i = 0; i < n-1; i++) { 35 | int a, b; 36 | cin >> a >> b; 37 | a--, b--; 38 | T[a].push_back(b); 39 | T[b].push_back(a); 40 | } 41 | int root; 42 | cin >> root; 43 | preprocess(root, root); 44 | int q; 45 | cin >> q; 46 | while (q--) { 47 | int u, v; 48 | cin >> u >> v; 49 | u--, v--; 50 | // Check if v is in subtree of u 51 | cout << isInSubtree(u, v) << endl; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/tree_diameter.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Find the diameter of the tree. 3 | * Usage: getDiameter O(V + E) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | typedef vector< vector > > tree; 14 | void dfs(tree &g, int u, int parent, int d, int dt[]){ 15 | dt[u] = d; 16 | for (int i = 0; i < g[u].size(); i++) { 17 | int v = g[u][i].first; 18 | if (v != parent) { 19 | dfs(g, v, u, d + g[u][i].second, dt); 20 | } 21 | } 22 | } 23 | 24 | const int MAX = 100005; 25 | int getDiameter(tree &g) { 26 | int dt[MAX] = {}; 27 | dfs(g, 0, 0, 0, dt); 28 | int max_dist = 0, max_pos = 0; 29 | int n = g.size(); 30 | for (int i = 0; i < n; i++) { 31 | if (max_dist < dt[i]) { 32 | max_dist = dt[i]; 33 | max_pos = i; 34 | } 35 | } 36 | memset(dt, 0, sizeof(dt)); 37 | dfs(g, max_pos, max_pos, 0, dt); 38 | max_dist = 0; 39 | for (int i = 0; i < n; i++) max_dist = max(max_dist, dt[i]); 40 | return max_dist; 41 | } 42 | 43 | int main() { 44 | int n, m; 45 | cin >> n >> m; 46 | tree T; 47 | for (int i = 0; i < m; i++) { 48 | int a, b; 49 | cin >> a >> b; 50 | a--, b--; 51 | int w; 52 | cin >> w; 53 | T[a].push_back({b, w}); 54 | T[b].push_back({a, w}); 55 | } 56 | cout << getDiameter(T) << endl; 57 | } 58 | -------------------------------------------------------------------------------- /src/trees_path_query_sparse_tables.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | typedef vector< vector > Tree; 8 | 9 | template 10 | class SparseTable { 11 | private: 12 | int counter; 13 | 14 | int n, root; 15 | Tree &T; 16 | vector &w; 17 | 18 | vector parent, level; 19 | vector prestamp, poststamp; 20 | vector > ancestor, aggregate; 21 | 22 | static const int INVALID = -1; 23 | 24 | bool isInSubtree(int u, int v) { 25 | return ((prestamp[u] <= prestamp[v]) && (poststamp[u] >= poststamp[v])); 26 | } 27 | 28 | void processTree() { 29 | //perform a DFS 30 | performDfs(root, INVALID, 0); 31 | //Get Ancestors 32 | processAncestors(); 33 | //Get Aggregate 34 | processAggregate(); 35 | } 36 | 37 | void performDfs(int u, int p, int l) { 38 | prestamp[u] = counter++; 39 | parent[u] = p; 40 | level[u] = l; 41 | for (int v : T[u]) { 42 | if (v != p) { 43 | performDfs(v, u, l+1); 44 | } 45 | } 46 | poststamp[u] = counter++; 47 | 48 | } 49 | 50 | void processAncestors() { 51 | for (int j = 0; j < n; j++) { 52 | ancestor[0][j] = parent[j]; 53 | } 54 | for (int i = 1; i < ancestor.size(); i++) { 55 | for (int j = 0; j < n; j++) { 56 | if (ancestor[i-1][j] != INVALID) { 57 | ancestor[i][j] = ancestor[i-1][ancestor[i-1][j]]; 58 | } else { 59 | ancestor[i][j] = INVALID; 60 | } 61 | } 62 | } 63 | } 64 | 65 | void processAggregate() { 66 | for (int j = 0; j < n; j++) { 67 | aggregate[0][j] = w[j]; 68 | } 69 | for (int i = 1; i < aggregate.size(); i++) { 70 | for (int j = 0; j < n; j++) { 71 | if (ancestor[i-1][j] != INVALID) { 72 | aggregate[i][j] = mergeFunction(aggregate[i-1][j], aggregate[i-1][ancestor[i-1][j]]); 73 | } else { 74 | aggregate[i][j] = INVALID; 75 | } 76 | } 77 | } 78 | } 79 | 80 | int getLog(int n){ 81 | int i=0; 82 | while (n) { 83 | i++, n>>=1; 84 | } 85 | return i; 86 | } 87 | 88 | public: 89 | MF mergeFunction; 90 | 91 | SparseTable(Tree &T, vector &w, const int root) : T(T), w(w) { 92 | this->counter = 0; 93 | this->root = root; 94 | this->n = T.size(); 95 | 96 | parent.resize(n); 97 | level.resize(n); 98 | prestamp.resize(n); poststamp.resize(n); 99 | 100 | int size = getLog(n)+5; 101 | ancestor.resize(size, vector(n)); 102 | aggregate.resize(size, vector(n)); 103 | 104 | processTree(); 105 | } 106 | 107 | int getLCA(int u, int v) { 108 | if (isInSubtree(u, v)) return u; 109 | if (isInSubtree(v, u)) return v; 110 | int size = ancestor.size(); 111 | for (int i = size-1; i >= 0; --i) { 112 | if (ancestor[i][u] == INVALID) continue; 113 | if (!isInSubtree(ancestor[i][u], v)) { 114 | u = ancestor[i][u]; 115 | } 116 | } 117 | return ancestor[0][u]; 118 | } 119 | 120 | valueType query(int x, int y) { 121 | if (level[x] <= level[y]) { 122 | swap(x, y); 123 | } 124 | //y should be an ancestor of x 125 | int currentNode = x, dif = level[x]-level[y]+1; 126 | int i = 0; 127 | valueType v = 0; 128 | while (dif) { 129 | if (dif & 1) { 130 | v = mergeFunction(v, aggregate[i][currentNode]); 131 | currentNode = ancestor[i][currentNode]; 132 | } 133 | i++, dif>>=1; 134 | } 135 | return v; 136 | } 137 | 138 | }; 139 | 140 | template 141 | class MF { 142 | public: 143 | valueType operator()(valueType left, valueType right) { 144 | return left+right; 145 | } 146 | }; 147 | 148 | int main() { 149 | int n; 150 | cin >> n; 151 | vector< vector > T(n); 152 | for (int i = 0; i < n-1; i++) { 153 | int a, b; 154 | cin >> a >> b; 155 | a--, b--; 156 | T[a].push_back(b); 157 | T[b].push_back(a); 158 | } 159 | vector w(n); 160 | for (int i = 0; i < n; i++) { 161 | cin >> w[i]; 162 | } 163 | SparseTable< int, MF > S(T, w, 0); 164 | int q; 165 | cin >> q; 166 | while (q--) { 167 | int u, v; 168 | cin >> u >> v; 169 | u--, v--; 170 | int lcaUV = S.getLCA(u, v); 171 | int sumU = S.query(u, lcaUV); 172 | int sumV = S.query(v, lcaUV); 173 | cout << lcaUV << " " << sumU << " " << sumV << endl; 174 | cout << sumU + sumV - w[lcaUV] << endl; 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /src/trie_insertion_deleteion.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Description: Trie 3 | * Usage: insert O( | S | ), erase O( | S | ) 4 | * Source: https://github.com/dragonslayerx 5 | */ 6 | 7 | struct node { 8 | node *p[26]; 9 | int count; 10 | node() { 11 | count=0; 12 | memset(p, 0, sizeof(p)); 13 | } 14 | } 15 | 16 | class trie { 17 | node *root; 18 | public: 19 | 20 | trie(){ 21 | root = new node() 22 | } 23 | 24 | void insert(char *s){ 25 | node *x = root; 26 | int length = strlen(s); 27 | for (int i = 0; i < length; i++) { 28 | if (x->p[s[i] - 'a'] == NULL) { 29 | x->p[s[i] - 'a'] = new node() 30 | } 31 | x = x->p[s[i] - 'a']; 32 | } 33 | x->count++; 34 | } 35 | 36 | void erase(char *s){ 37 | node *x = root; 38 | int length = strlen(s); 39 | for (int i = 0; i < length; i++) { 40 | x = x->p[s[i] - 'a']; 41 | } 42 | x->count--; 43 | } 44 | 45 | }; 46 | -------------------------------------------------------------------------------- /src/untested-codes/aho_corasick.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | const int SENTINEL = -1; 10 | struct Node { 11 | int count; 12 | int link[26]; 13 | int suffixLink; 14 | int fall; 15 | Node() { 16 | count=0; 17 | for (int i = 0; i < 26; i++) { 18 | link[i]=SENTINEL; 19 | } 20 | suffixLink=fall=SENTINEL; 21 | } 22 | }; 23 | 24 | const int MAX_SIZE = 5000005; 25 | Node trie[MAX_SIZE]; 26 | 27 | class AhoCorasick { 28 | int size; 29 | int root; 30 | 31 | int createNode() { 32 | return size++; 33 | } 34 | 35 | public: 36 | AhoCorasick() { 37 | size=0; 38 | root = createNode(); 39 | } 40 | 41 | void construct(char *patterns[], int m) { 42 | for (int k = 0; k < m; k++) { 43 | insert(patterns[k]); 44 | } 45 | } 46 | 47 | void insert(char *pattern) { 48 | int current = 0; 49 | for (int i = 0; pattern[i]; i++) { 50 | char c = pattern[i]-'a'; 51 | if (trie[current].link[c] == SENTINEL) { 52 | trie[current].link[c] = createNode(); 53 | } 54 | current = trie[current].link[c]; 55 | } 56 | trie[current].count++; 57 | } 58 | 59 | void erase(char *pattern) { 60 | int current = 0; 61 | for (int i = 0; pattern[i]; i++) { 62 | char c = pattern[i]-'a'; 63 | current = trie[current].link[c]; 64 | } 65 | trie[current].count--; 66 | } 67 | 68 | void createSuffixLinks(int node, int parent, int i) { 69 | int current = trie[parent].suffixLink; 70 | while (current && (trie[current].link[i] == SENTINEL)) current = trie[current].suffixLink; 71 | if (current) { 72 | trie[node].suffixLink = trie[current].link[i]; 73 | } else { 74 | if (!parent) trie[node].suffixLink = 0; 75 | else if (trie[current].link[i] == SENTINEL) { 76 | trie[node].suffixLink = 0; 77 | } else { 78 | trie[node].suffixLink = trie[current].link[i]; 79 | } 80 | } 81 | for (int k = 0; k < 26; k++) { 82 | if (trie[node].link[k] != SENTINEL) { 83 | createSuffixLinks(trie[node].link[k], node, k); 84 | } 85 | } 86 | } 87 | 88 | int getFall(int node) { 89 | if (node == 0) return 0; 90 | else if (trie[node].fall != SENTINEL) return trie[node].fall; 91 | else if (trie[trie[node].suffixLink].count) { 92 | return (trie[node].fall = trie[node].suffixLink); 93 | } else { 94 | trie[node].fall = getFall(trie[node].suffixLink); 95 | } 96 | } 97 | 98 | void createFall() { 99 | for (int i = 0; i < size; i++) { 100 | getFall(i); 101 | } 102 | } 103 | }; 104 | 105 | long long getCount(char *p) { 106 | int current = 0; 107 | long long count = 0; 108 | for (int i = 0; p[i]; i++) { 109 | int current = trie[current].link[p[i]-'a']; 110 | count += trie[current].count; 111 | } 112 | return count; 113 | } 114 | 115 | int main() { 116 | int m, q; 117 | scanf("%d%d", &m, &q); 118 | AhoCorasick A; 119 | for (int i = 1; i <= m; i++) { 120 | char s[10005]; 121 | scanf("%s", s); 122 | A.insert(s); 123 | } 124 | A.createSuffixLinks(0, 0, '#'); 125 | } 126 | -------------------------------------------------------------------------------- /src/untested-codes/suffix_array.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | using namespace std; 14 | 15 | //---------------------- 16 | // inputs 17 | string s; 18 | int n; 19 | 20 | const int MAX = 1000005; 21 | const int INF = 1000000000+5; 22 | 23 | int lgn=0; 24 | int sa[25][MAX]; 25 | int rankSuf[MAX]; 26 | void constructSA() { 27 | map rank; 28 | for (int i=0; isecond=ctr++; 31 | int p2=1; 32 | while (p2<=n) {p2<<=1; lgn++;} 33 | for (int i=0; i,int>> rank; 36 | for (int j=0; j, int> r = {{sa[i-1][j], ((j+l0 && (rank[j].first!=rank[j-1].first)) ctr++; 43 | sa[i][rank[j].second]=ctr; 44 | } 45 | } 46 | for (int i=0; i=0; i--, len>>=1) { 52 | if (sa[i][p]==sa[i][q]) { 53 | l+=len; p+=len, q+=len; 54 | } 55 | if (p>=n || q>=n) break; 56 | } 57 | return l; 58 | } 59 | 60 | int lcp[25][MAX]; 61 | void processlcp() { 62 | int N=n-1; 63 | for (int i=0; i