├── .gitignore ├── Coursera G72HSXLPV9A8.pdf ├── LICENSE ├── README.md ├── advanced-algorithms-and-complexity ├── Coursera C6ZKJE4RJRY9.pdf ├── week-1 │ ├── airline_crews.cpp │ ├── evacuation.cpp │ └── stock_charts.py ├── week-2 │ ├── ad_allocation.cpp │ ├── diet.cpp │ └── energy_values.cpp ├── week-3 │ ├── budget_allocation.cpp │ ├── cleaning_apartment.cpp │ └── gsm_network.cpp ├── week-4 │ ├── 2sat.cpp │ ├── max_weight_independent_set.cpp │ └── tsp.cpp └── week-5 │ └── heavy_hitters.cpp ├── algorithmic-toolbox ├── Coursera WLDWN5BQS34C.pdf ├── week-1 │ ├── aplusb.cpp │ └── maximum_pairwise_product.cpp ├── week-2 │ ├── fibonacci.cpp │ ├── fibonacci_last_digit.cpp │ ├── fibonacci_partial_sum.cpp │ ├── fibonacci_sum.cpp │ ├── fibonacci_sum_of_squares.cpp │ ├── gcd.cpp │ ├── huge_fibonacci.cpp │ └── lcm.cpp ├── week-3 │ ├── car_fueling.cpp │ ├── change.cpp │ ├── converging_segments.cpp │ ├── different_summands.cpp │ ├── dot_product.cpp │ ├── fractional_knapsack.cpp │ └── largest_number.cpp ├── week-4 │ ├── binary_search.cpp │ ├── closest.py │ ├── inversions.cpp │ ├── majority_element.cpp │ ├── points_and_segments.cpp │ └── sorting.cpp ├── week-5 │ ├── change_dp.cpp │ ├── edit_distance.cpp │ ├── lcs2.cpp │ ├── lcs3.cpp │ └── primitive_calculator.cpp └── week-6 │ ├── knapsack.cpp │ ├── parentheses.py │ └── partition3.cpp ├── algorithms-on-graphs ├── Coursera D4EZTNZ5ATXM.pdf ├── week-1 │ ├── connected_components.cpp │ └── reachabillity.cpp ├── week-2 │ ├── acyclicity.cpp │ ├── strongly_connected.cpp │ └── toposort.cpp ├── week-3 │ ├── bfs.cpp │ └── bipartite.cpp ├── week-4 │ ├── dijkstra.cpp │ ├── negative_cycle.cpp │ └── shortest_paths.py ├── week-5 │ ├── clustering.cpp │ └── connecting_points.cpp └── week-6 │ ├── dist_preprocess_large.cpp │ ├── dist_preprocess_small.cpp │ ├── dist_with_coords.cpp │ └── friend_suggestion.cpp ├── algorithms-on-strings ├── Coursera U84TMFDLT6BM.pdf ├── week-1 │ ├── non_shared_substring.py │ ├── suffix_tree.py │ ├── trie.cpp │ ├── trie_matching.cpp │ └── trie_matching_extended.cpp ├── week-2 │ ├── bwmatching.cpp │ ├── bwt.cpp │ ├── bwtinverse.cpp │ └── suffix_array.cpp └── week-4 │ ├── kmp.cpp │ ├── suffix_array_long.cpp │ ├── suffix_array_matching.py │ └── suffix_tree_from_array.py ├── assembling-genomes ├── Coursera 5QGPB9XKACS7.pdf ├── week-1 │ ├── phiX174_error_free_overlap.cpp │ └── phiX174_error_prone_overlap.cpp ├── week-2 │ ├── eulerian_cycle.cpp │ ├── phiX174_kmer.cpp │ ├── puzzle.cpp │ └── universal_string.cpp └── week-3 │ ├── bubble_detection.py │ ├── circulation.cpp │ ├── optimal_kmer_size.cpp │ └── tip_removal.py └── data-structures ├── Coursera BMUSAKGNSU4P.pdf ├── week-1 ├── brackets_in_code.cpp ├── max_sliding_window.cpp ├── network_simulation.cpp ├── stack_with_max.cpp └── tree_height.cpp ├── week-3 ├── make_heap.cpp ├── merging_tables.py └── parallel_processing.cpp ├── week-4 ├── common_substring.py ├── hash_chain.py ├── hash_substring.cpp ├── hash_substring.py ├── matching_with_mismatches.py ├── phone_book.cpp └── substr.py └── week-6 ├── is_bst.cpp ├── is_bst_hard.cpp ├── rope.cpp ├── rope.py ├── set_range_sum.py └── tree_orders.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app -------------------------------------------------------------------------------- /Coursera G72HSXLPV9A8.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virtyaluk/coursera-data-structures-algorithms/9743587e0520ead50d1838fa228877be0282cff1/Coursera G72HSXLPV9A8.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [Data Structures and Algorithms Specialization](https://www.coursera.org/specializations/data-structures-algorithms) by University of California San Diego and National Research University Higher School of Economics - [Certificate](https://www.coursera.org/account/accomplishments/specialization/G72HSXLPV9A8) 2 | 3 | - Course 1 - [Algorithmic Toolbox](https://www.coursera.org/learn/algorithmic-toolbox?specialization=data-structures-algorithms) - [Certificate](https://www.coursera.org/account/accomplishments/certificate/WLDWN5BQS34C) 4 | - Course 2 - [Data Structures](https://www.coursera.org/learn/data-structures?specialization=data-structures-algorithms) - [Certificate](https://www.coursera.org/account/accomplishments/certificate/BMUSAKGNSU4P) 5 | - Course 3 - [Algorithms on Graphs](https://www.coursera.org/learn/algorithms-on-graphs?specialization=data-structures-algorithms) - [Certificate](https://www.coursera.org/account/accomplishments/verify/D4EZTNZ5ATXM) 6 | - Course 4 - [Algorithms on Strings](https://www.coursera.org/learn/algorithms-on-strings?specialization=data-structures-algorithms) - [Certificate](https://www.coursera.org/account/accomplishments/verify/U84TMFDLT6BM) 7 | - Course 5 - [Advanced Algorithms and Complexity](https://www.coursera.org/learn/advanced-algorithms-and-complexity) - [Certificate](https://www.coursera.org/account/accomplishments/verify/C6ZKJE4RJRY9) 8 | - Course 6 - [Genome Assembly Programming Challenge](https://www.coursera.org/learn/assembling-genomes) - [Certificate](https://www.coursera.org/account/accomplishments/verify/5QGPB9XKACS7) 9 | 10 | ## :green_book: License 11 | 12 | Licensed under the [GPL-3.0 License](https://github.com/virtyaluk/coursera-data-structures-algorithms/blob/master/LICENSE). 13 | 14 | Copyright (c) 2020 - 2021 Bohdan Shtepan 15 | 16 | --- 17 | 18 | > [modern-dev.com](http://modern-dev.com)  ·  19 | > GitHub [@virtyaluk](https://github.com/virtyaluk)  ·  20 | > Twitter [@virtyaluk](https://twitter.com/virtyaluk) -------------------------------------------------------------------------------- /advanced-algorithms-and-complexity/Coursera C6ZKJE4RJRY9.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virtyaluk/coursera-data-structures-algorithms/9743587e0520ead50d1838fa228877be0282cff1/advanced-algorithms-and-complexity/Coursera C6ZKJE4RJRY9.pdf -------------------------------------------------------------------------------- /advanced-algorithms-and-complexity/week-1/airline_crews.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | vvll makeResidualGraph(vvll& graph, ll& n, ll& m) { 30 | vvll residual(n + m + 2, vll(n + m + 2)); 31 | 32 | for (ll i = 1; i < n + 1; i++) { 33 | residual[0][i] = 1; 34 | 35 | for (ll j = 0; j < m; j++) { 36 | residual[i][n + 1 + j] = graph[i - 1][j]; 37 | } 38 | } 39 | 40 | for (ll k = n + 1; k < n + m + 1; k++) { 41 | residual[k].back() = 1; 42 | } 43 | 44 | return residual; 45 | } 46 | 47 | bool hasPath(vvll& graph, vll& path) { 48 | ll V = graph.size(); 49 | vector visited(V); 50 | queue q; 51 | 52 | visited[0] = true; 53 | q.push(0); 54 | 55 | while (!q.empty()) { 56 | ll u = q.front(); 57 | q.pop(); 58 | 59 | if (u == V - 1) { 60 | return true; 61 | } 62 | 63 | for (ll i = 0; i < V; i++) { 64 | if (!visited[i] && graph[u][i] > 0) { 65 | q.push(i); 66 | visited[i] = true; 67 | path[i] = u; 68 | } 69 | } 70 | } 71 | 72 | return visited[V - 1]; 73 | } 74 | 75 | vll maxFlow(vvll& graph, ll& n) { 76 | ll V = graph.size(); 77 | vll path(V), matches(n, -1); 78 | 79 | iota(begin(path), end(path), 0); 80 | 81 | while (hasPath(graph, path)) { 82 | ll minFlow = INT_MAX, v = V - 1, u; 83 | 84 | while (v) { 85 | u = path[v]; 86 | minFlow = min(minFlow, graph[u][v]); 87 | v = u; 88 | } 89 | 90 | v = V - 1; 91 | 92 | while (v) { 93 | u = path[v]; 94 | graph[u][v] -= minFlow; 95 | graph[v][u] += minFlow; 96 | v = u; 97 | } 98 | } 99 | 100 | for (ll i = 0; i < V; i++) { 101 | if (graph[V - 1][i] == 1) { 102 | ll person = i - n, flight; 103 | 104 | for (ll j = 0; j < graph[i].size(); j++) { 105 | if (graph[i][j] == 1) { 106 | flight = j; 107 | break; 108 | } 109 | } 110 | 111 | matches[flight - 1] = person; 112 | } 113 | } 114 | 115 | return matches; 116 | } 117 | 118 | int main() { 119 | ios_base::sync_with_stdio(0); 120 | cin.tie(0); 121 | cout.tie(0); 122 | // freopen("input.txt", "r", stdin); 123 | // freopen("output.txt", "w", stdout); 124 | 125 | ll n, m; 126 | cin >> n >> m; 127 | 128 | vvll graph(n, vll(m)); 129 | 130 | for (ll i = 0; i < n; i++) { 131 | for (ll j = 0; j < m; j++) { 132 | cin >> graph[i][j]; 133 | } 134 | } 135 | 136 | vvll residual = makeResidualGraph(graph, n, m); 137 | vll matches = maxFlow(residual, n); 138 | 139 | copy(begin(matches), end(matches), ostream_iterator(cout, " ")); 140 | cout << endl; 141 | 142 | return 0; 143 | } 144 | -------------------------------------------------------------------------------- /advanced-algorithms-and-complexity/week-1/evacuation.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | bool hasPath(vvll& graph, ll& n, vll& path) { 30 | vector visited(n); 31 | queue q; 32 | 33 | visited[0] = true; 34 | q.push(0); 35 | 36 | while (!q.empty()) { 37 | ll tmp = q.front(); 38 | q.pop(); 39 | 40 | if (tmp == n - 1) { 41 | return true; 42 | } 43 | 44 | for (ll i = 0; i < n; i++) { 45 | if (!visited[i] && graph[tmp][i] > 0) { 46 | q.push(i); 47 | visited[i] = true; 48 | path[i] = tmp; 49 | } 50 | } 51 | } 52 | 53 | return visited[n - 1]; 54 | } 55 | 56 | ll maxFlow(vvll& graph, ll& n) { 57 | ll flow = 0; 58 | vll path(n); 59 | 60 | iota(begin(path), end(path), 0); 61 | 62 | while (hasPath(graph, n, path)) { 63 | ll minFlow = INT_MAX, v = n - 1, u; 64 | 65 | while (v) { 66 | u = path[v]; 67 | minFlow = min(minFlow, graph[u][v]); 68 | v = u; 69 | } 70 | 71 | v = n - 1; 72 | 73 | while (v) { 74 | u = path[v]; 75 | graph[u][v] -= minFlow; 76 | graph[v][u] += minFlow; 77 | v = u; 78 | } 79 | 80 | flow += minFlow; 81 | } 82 | 83 | return flow; 84 | } 85 | 86 | int main() { 87 | ios_base::sync_with_stdio(0); 88 | cin.tie(0); 89 | cout.tie(0); 90 | // freopen("input.txt", "r", stdin); 91 | // freopen("output.txt", "w", stdout); 92 | 93 | ll n, m, u, v, c; 94 | cin >> n >> m; 95 | 96 | vvll graph(n, vll(n)); 97 | 98 | for (ll i = 0; i < m; i++) { 99 | cin >> u >> v >> c; 100 | graph[u - 1][v - 1] += c; 101 | } 102 | 103 | cout << maxFlow(graph, n) << endl; 104 | 105 | return 0; 106 | } 107 | -------------------------------------------------------------------------------- /advanced-algorithms-and-complexity/week-1/stock_charts.py: -------------------------------------------------------------------------------- 1 | # python3 2 | 3 | 4 | from collections import deque 5 | 6 | 7 | def DAG(n, stock): 8 | adj = [[0] * n for _ in range(n)] 9 | for i in range(n): 10 | for j in range(i + 1, n): 11 | above = all([x < y for x, y in zip(stock[i], stock[j])]) 12 | below = all([x > y for x, y in zip(stock[i], stock[j])]) 13 | if above: 14 | adj[i][j] = 1 15 | elif below: 16 | adj[j][i] = 1 17 | return adj 18 | 19 | 20 | def MakeNetwork(n, adj): 21 | graph = [[0] * (2 * n + 2) for _ in range(2 * n + 2)] 22 | for i in range(1, n + 1): 23 | graph[0][i] = 1 24 | for j in range(n): 25 | graph[i][n + 1 + j] = adj[i - 1][j] 26 | for k in range(n + 1, 2 * n + 1): 27 | graph[k][-1] = 1 28 | return graph 29 | 30 | 31 | def HasPath(Gf, path): 32 | k = len(Gf) # network中一共k个结点 33 | visited = [False] * k 34 | queue = deque([0]) 35 | visited[0] = True 36 | while queue: 37 | u = queue.pop() 38 | if u == k - 1: 39 | return True 40 | for v in range(k): 41 | if not visited[v] and graph[u][v] > 0: 42 | queue.append(v) 43 | visited[v] = True 44 | path[v] = u 45 | return visited[-1] 46 | 47 | 48 | def MaxFlow(Gf): 49 | k = len(Gf) 50 | path = [-1] * k 51 | flow = 0 52 | while HasPath(Gf, path): 53 | min_flow = float('inf') 54 | v = k - 1 55 | while v > 0: 56 | u = path[v] 57 | min_flow = min(min_flow, graph[u][v]) 58 | v = u 59 | v = k - 1 60 | while v > 0: 61 | u = path[v] 62 | graph[u][v] -= min_flow 63 | graph[v][u] += min_flow 64 | v = u 65 | flow += min_flow 66 | return flow 67 | 68 | 69 | if __name__ == '__main__': 70 | n, m = map(int, input().split()) 71 | stock_data = [list(map(int, input().split())) for _ in range(n)] 72 | adj_matrix = DAG(n, stock_data) 73 | graph = MakeNetwork(n, adj_matrix) 74 | max_flow = MaxFlow(graph) 75 | min_charts = n - max_flow 76 | print(min_charts) -------------------------------------------------------------------------------- /advanced-algorithms-and-complexity/week-2/energy_values.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | struct Equation { 30 | vector> a; 31 | vector b; 32 | }; 33 | 34 | struct Position { 35 | short row, col; 36 | }; 37 | 38 | const Position selectPivotElement(Position& pivot, const vector>& a, const vector& usedRows) { 39 | while (usedRows[pivot.row] || a[pivot.row][pivot.col] == 0) { 40 | pivot.row++; 41 | } 42 | 43 | return pivot; 44 | } 45 | 46 | void swapLines(vector>& a, vector& b, vector& usedRows, Position& pivot) { 47 | swap(a[pivot.col], a[pivot.row]); 48 | swap(b[pivot.col], b[pivot.row]); 49 | swap(usedRows[pivot.col], usedRows[pivot.row]); 50 | pivot.row = pivot.col; 51 | } 52 | 53 | void processPivotElement(vector>& a, vector& b, vector& usedRows, const Position& pivot) { 54 | double scale = a[pivot.row][pivot.col]; 55 | 56 | if (scale != 1.0) { 57 | for (int i = 0; i < a.size(); i++) { 58 | a[pivot.row][i] /= scale; 59 | } 60 | 61 | b[pivot.row] /= scale; 62 | } 63 | 64 | for (int i = 0; i < a.size(); i++) { 65 | if (i != pivot.row) { 66 | double multiple = a[i][pivot.col]; 67 | 68 | for (int j = 0; j < a.size(); j++) { 69 | a[i][j] -= a[pivot.row][j] * multiple; 70 | } 71 | 72 | b[i] -= b[pivot.row] * multiple; 73 | } 74 | } 75 | 76 | usedRows[pivot.row] = true; 77 | } 78 | 79 | vector solveEquation(const Equation& eq) { 80 | vector> a = eq.a; 81 | vector b = eq.b; 82 | int size = a.size(); 83 | vector usedRows(size); 84 | 85 | for (short i = 0; i < size; i++) { 86 | Position pivot{0, i}; 87 | pivot = selectPivotElement(pivot, a, usedRows); 88 | 89 | swapLines(a, b, usedRows, pivot); 90 | processPivotElement(a, b, usedRows, pivot); 91 | } 92 | 93 | return b; 94 | } 95 | 96 | int main() { 97 | ios_base::sync_with_stdio(0); 98 | cin.tie(0); 99 | cout.tie(0); 100 | // freopen("input.txt", "r", stdin); 101 | // freopen("output.txt", "w", stdout); 102 | 103 | ll n; 104 | cin >> n; 105 | 106 | vector> a(n, vector(n)); 107 | vector b(n); 108 | 109 | for (int i = 0; i < n; i++) { 110 | for (int j = 0; j < n; j++) { 111 | cin >> a[i][j]; 112 | } 113 | 114 | cin >> b[i]; 115 | } 116 | 117 | Equation eq{move(a), move(b)}; 118 | const vector solution = solveEquation(eq); 119 | 120 | cout.precision(10); 121 | copy(begin(solution), end(solution), ostream_iterator(cout, " ")); 122 | cout << endl; 123 | 124 | return 0; 125 | } 126 | -------------------------------------------------------------------------------- /advanced-algorithms-and-complexity/week-3/budget_allocation.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | void solve(const vvi& a, const vi& b) { 30 | string clausesStream; 31 | int cnt = 0; 32 | bitset<3> combinations; 33 | 34 | for (int i = 0; i < a.size(); i++) { 35 | const vi& row = a[i]; 36 | int n = count_if(begin(row), row.cend(), [](const int& num) { 37 | return num != 0; 38 | }); 39 | 40 | for (int j = 0, s = pow(2, n); j < s; j++) { 41 | combinations = j; 42 | int sum = 0, comb = 0; 43 | 44 | for (const int& num: row) { 45 | if (num != 0 and combinations[comb++]) { 46 | sum += num; 47 | } 48 | } 49 | 50 | if (sum > b[i]) { 51 | bool isClause = false; 52 | 53 | for (int k = 0, comb = 0; k < row.size(); k++) { 54 | if (row[k] != 0) { 55 | clausesStream += combinations[comb] ? (to_string(-(k + 1)) + ' ') : (to_string(k + 1) + ' '); 56 | comb++; 57 | isClause = true; 58 | } 59 | } 60 | 61 | if (isClause) { 62 | clausesStream += "0 \n"; 63 | cnt++; 64 | } 65 | } 66 | } 67 | } 68 | 69 | if (cnt == 0) { 70 | cnt++; 71 | clausesStream += "1 -1 0\n"; 72 | } 73 | 74 | cout << cnt << " " << (a[0].size()) << endl; 75 | cout << clausesStream.c_str(); 76 | } 77 | 78 | int main() { 79 | ios_base::sync_with_stdio(0); 80 | cin.tie(0); 81 | cout.tie(0); 82 | // freopen("input.txt", "r", stdin); 83 | // freopen("output.txt", "w", stdout); 84 | 85 | ll n, m; 86 | cin >> n >> m; 87 | 88 | vvi a(n, vi(m)); 89 | vi b; 90 | 91 | for (int i = 0; i < n; i++) { 92 | for (int j = 0; j < m; j++) { 93 | cin >> a[i][j]; 94 | } 95 | } 96 | 97 | copy_n(istream_iterator(cin), n, back_inserter(b)); 98 | 99 | solve(a, b); 100 | 101 | return 0; 102 | } 103 | -------------------------------------------------------------------------------- /advanced-algorithms-and-complexity/week-3/cleaning_apartment.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | using std::cin; 16 | using std::vector; 17 | using std::ios; 18 | 19 | struct Hamiltonian_path_to_SAT { 20 | 21 | Hamiltonian_path_to_SAT(int n, int m) 22 | : clauses_num(0), vertices_num(n), matrix(n, vector(n, false)), data(n, vector(n)) { 23 | for (int i = 0, cnt = 0; i < vertices_num; ++i) { 24 | for (int j = 0; j < vertices_num; ++j) { 25 | data[i][j] = ++cnt; 26 | } 27 | } 28 | } 29 | 30 | void print_SAT_formula(const int max_clauses_num) noexcept { 31 | clauses_stream.reserve(max_clauses_num * 3); 32 | 33 | each_vertext_in_path(); 34 | each_vertext_in_path_only_once(); 35 | each_path_position_occupied(); 36 | verteces_occupy_diff_positions(); 37 | nonadjacent_vertices_nonadjacent_in_path(); 38 | 39 | printf("%d %d \n%s", clauses_num, vertices_num * vertices_num, clauses_stream.c_str()); 40 | } 41 | 42 | void each_vertext_in_path() noexcept { 43 | for (int i = 0; i < vertices_num; ++i, ++clauses_num) { 44 | for (int j = 0; j < vertices_num; ++j) { 45 | clauses_stream += std::to_string(data[i][j]) + " "; 46 | } 47 | clauses_stream += "0\n"; 48 | } 49 | } 50 | 51 | void each_vertext_in_path_only_once() noexcept { 52 | for (int i = 0; i < vertices_num; ++i) { 53 | for (int j = 0; j < vertices_num; ++j) { 54 | for (int k = i + 1; k < vertices_num; ++k, ++clauses_num) { 55 | clauses_stream += std::to_string(-data[i][j]) + " " + std::to_string(-data[k][j]) + " 0\n"; 56 | } 57 | } 58 | } 59 | } 60 | 61 | void each_path_position_occupied() noexcept { 62 | for (int i = 0; i < vertices_num; ++i, ++clauses_num) { 63 | for (int j = 0; j < vertices_num; ++j) { 64 | clauses_stream += std::to_string(data[j][i]) + " "; 65 | } 66 | clauses_stream += "0\n"; 67 | } 68 | } 69 | 70 | void verteces_occupy_diff_positions() noexcept { 71 | for (int i = 0; i < vertices_num; ++i) { 72 | for (int j = 0; j < vertices_num; ++j) { 73 | for (int k = j + 1; k < vertices_num; ++k, ++clauses_num) { 74 | clauses_stream += std::to_string(-data[i][j]) + " " + std::to_string(-data[i][k]) + " 0\n"; 75 | } 76 | } 77 | } 78 | } 79 | 80 | void nonadjacent_vertices_nonadjacent_in_path() noexcept { 81 | for (int i = 0; i < vertices_num; ++i) { 82 | for (int j = 0; j < vertices_num; ++j) { 83 | if (!matrix[i][j] && j != i) { 84 | for (int k = 0; k < vertices_num - 1; ++k, ++clauses_num) { 85 | clauses_stream += std::to_string(-data[i][k]) + " " + std::to_string(-data[j][k + 1]) + " 0\n"; 86 | } 87 | } 88 | } 89 | } 90 | } 91 | 92 | unsigned int clauses_num; 93 | const unsigned int vertices_num; 94 | vector> matrix; 95 | vector> data; 96 | std::string clauses_stream; 97 | }; 98 | 99 | int main() { 100 | ios::sync_with_stdio(false); 101 | 102 | int n, m; 103 | cin >> n >> m; 104 | 105 | Hamiltonian_path_to_SAT converter(n, m); 106 | 107 | for (int k = 0; k < m; ++k) { 108 | int i, j; 109 | cin >> i >> j; 110 | converter.matrix[i - 1][j - 1] = true; 111 | converter.matrix[j - 1][i - 1] = true; 112 | } 113 | 114 | converter.print_SAT_formula(120000); 115 | 116 | return 0; 117 | } 118 | -------------------------------------------------------------------------------- /advanced-algorithms-and-complexity/week-3/gsm_network.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | static constexpr auto K = 3; 30 | 31 | int main() { 32 | ios_base::sync_with_stdio(0); 33 | cin.tie(0); 34 | cout.tie(0); 35 | // freopen("input.txt", "r", stdin); 36 | // freopen("output.txt", "w", stdout); 37 | 38 | ll n, m, u, v; 39 | cin >> n >> m; 40 | 41 | vector> edges(m); 42 | 43 | for (ll i = 0; i < m; i++) { 44 | cin >> u >> v; 45 | edges[i] = {u, v}; 46 | } 47 | 48 | ll C = K * m + n, V = n * K; 49 | 50 | printf("%d %d\n", C, V); 51 | 52 | for (ll j = 0, cnt = 1; j < n; j++, cnt += K) { 53 | printf("%d %d %d 0\n", cnt, cnt + 1, cnt + 2); 54 | } 55 | 56 | for (const pair& e: edges) { 57 | ll from = e.first, to = e.second; 58 | 59 | printf("%d %d 0\n", -((from - 1) * K + 1), -((to - 1) * K + 1)); 60 | printf("%d %d 0\n", -((from - 1) * K + 2), -((to - 1) * K + 2)); 61 | printf("%d %d 0\n", -((from - 1) * K + 3), -((to - 1) * K + 3)); 62 | } 63 | 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /advanced-algorithms-and-complexity/week-4/2sat.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | struct solver_2SAT { 30 | struct util { 31 | util(): index{MIN}, lowlink{MIN}, id{-1}, on_stack{false} {} 32 | 33 | int index, lowlink, id; 34 | bool on_stack; 35 | vector edges; 36 | }; 37 | 38 | solver_2SAT(unordered_map adj_lst_graph, int num_of_vars): n{num_of_vars}, graph{move(adj_lst_graph)}, sol{vector(n, false)} {} 39 | 40 | void process_vertex(int v) { 41 | auto &utl = graph[v]; 42 | 43 | utl.lowlink = utl.index = t++; 44 | utl.on_stack = true; 45 | stk.push(v); 46 | 47 | for (auto w : utl.edges) { 48 | if (graph[w].index == MIN) { 49 | process_vertex(w); 50 | utl.lowlink = min(utl.lowlink, graph[w].lowlink); 51 | } else if (graph[w].on_stack) { 52 | utl.lowlink = min(utl.lowlink, graph[w].index); 53 | } 54 | } 55 | 56 | if (utl.lowlink == utl.index) { 57 | do { 58 | w = stk.top(); 59 | stk.pop(); 60 | 61 | if (id == graph[-w].id) { 62 | sat = false; 63 | return; 64 | } 65 | 66 | auto &w_utl = graph[w]; 67 | w_utl.on_stack = false; 68 | w_utl.id = id; 69 | 70 | sol[abs(w) - 1] = w < 0 ? true : false; 71 | 72 | } while (w != v); 73 | ++id; 74 | } 75 | } 76 | 77 | void solve() { 78 | for (int i = -n; i <= n; ++i) { 79 | if (graph[i].index == MIN && i != 0) { 80 | process_vertex(i); 81 | } 82 | } 83 | } 84 | 85 | void print_solution() const noexcept { 86 | if (!sat) { 87 | printf("%s\n", "UNSATISFIABLE\0"); 88 | return; 89 | } 90 | 91 | printf("%s\n", "SATISFIABLE\0"); 92 | for (unsigned int i = 0, s = sol.size(); i < s; ++i) { 93 | printf("%d ", (sol[i] ? i + 1 : -(i + 1))); 94 | } 95 | 96 | printf("\n"); 97 | } 98 | 99 | int t{0}, id{0}, w{0}, n{0}; 100 | 101 | unordered_map graph; 102 | vector sol; 103 | stack stk; 104 | 105 | bool sat{true}; 106 | 107 | static constexpr int MIN = numeric_limits::min(); 108 | }; 109 | 110 | int main() { 111 | ios_base::sync_with_stdio(0); 112 | cin.tie(0); 113 | cout.tie(0); 114 | // freopen("input.txt", "r", stdin); 115 | // freopen("output.txt", "w", stdout); 116 | 117 | int n, m; 118 | cin >> n >> m; 119 | 120 | unordered_map adj_lst_graph(n * 2); 121 | 122 | for (int i = 0, x, y; i < m; ++i) { 123 | cin >> x >> y; 124 | adj_lst_graph[-x].edges.emplace_back(y); 125 | adj_lst_graph[-y].edges.emplace_back(x); 126 | } 127 | 128 | solver_2SAT solver(move(adj_lst_graph), n); 129 | solver.solve(); 130 | solver.print_solution(); 131 | 132 | return 0; 133 | } -------------------------------------------------------------------------------- /advanced-algorithms-and-complexity/week-4/max_weight_independent_set.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | struct vertex { 30 | int weight; 31 | vi children; 32 | }; 33 | 34 | int computeMaxIndependentSet(const vector& g, const int v, vi& s, const int parent) { 35 | if (s[v] == - 1) { 36 | if (g[v].children.empty()) { 37 | s[v] = g[v].weight; 38 | } else { 39 | auto m1 = g[v].weight; 40 | 41 | for (auto u: g[v].children) { 42 | if (u == parent) { 43 | continue; 44 | } 45 | 46 | for (auto w: g[u].children) { 47 | if (w != v) { 48 | m1 += computeMaxIndependentSet(g, w, s, u); 49 | } 50 | } 51 | } 52 | 53 | auto m0 = 0; 54 | 55 | for (auto u: g[v].children) { 56 | if (u != parent) { 57 | m0 += computeMaxIndependentSet(g, u, s, v); 58 | } 59 | } 60 | 61 | s[v] = max(m1, m0); 62 | } 63 | } 64 | 65 | return s[v]; 66 | } 67 | 68 | int solve(const vector& g) noexcept { 69 | int size = g.size(); 70 | 71 | if (size == 0) { 72 | return 0; 73 | } 74 | 75 | vi s(size, -1); 76 | 77 | return computeMaxIndependentSet(g, 0, s, -1); 78 | } 79 | 80 | int main() { 81 | ios_base::sync_with_stdio(0); 82 | cin.tie(0); 83 | cout.tie(0); 84 | // freopen("input.txt", "r", stdin); 85 | // freopen("output.txt", "w", stdout); 86 | 87 | int n, u, v; 88 | cin >> n; 89 | 90 | vector g(n); 91 | 92 | for (int i = 0; i < n; i++) { 93 | cin >> g[i].weight; 94 | } 95 | 96 | for (int i = 1; i < n; i++) { 97 | cin >> u >> v; 98 | 99 | g[u - 1].children.emplace_back(v - 1); 100 | g[v - 1].children.emplace_back(u - 1); 101 | } 102 | 103 | cout << solve(g) << endl; 104 | 105 | return 0; 106 | } -------------------------------------------------------------------------------- /advanced-algorithms-and-complexity/week-4/tsp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | struct Node { 30 | int dist = INF, parent = 0; 31 | }; 32 | 33 | struct TSP { 34 | const int N; 35 | vvi dist; 36 | vector> C; 37 | 38 | TSP(vvi g): N(g.size()), C(vector>(1 << N, vector(N))), dist(move(g)) { 39 | for (int k = 1; k < N; k++) { 40 | C[1 << k][k] = Node{dist[0][k], 0}; 41 | } 42 | } 43 | 44 | pair optimalTour() noexcept { 45 | for (int s = 2; s < 1 << (N - 1); s++) { 46 | if (s & (s - 1)) { 47 | vi S = combinations(s); 48 | int bits = s * 2; 49 | 50 | for (auto k: S) { 51 | int prev = bits ^ (1 << k); 52 | Node minNode; 53 | 54 | for (auto m: S) { 55 | if (C[prev][m].dist + dist[m][k] < minNode.dist and k != m) { 56 | minNode = Node{C[prev][m].dist + dist[m][k], m}; 57 | } 58 | } 59 | 60 | C[bits][k] = minNode; 61 | } 62 | } 63 | } 64 | 65 | return backtrackOptimal(); 66 | } 67 | 68 | vi combinations(const int n) noexcept { 69 | vi combs; 70 | bitset<16> bset = n; 71 | 72 | for (auto k = 0u; k < bset.size(); k++) { 73 | if (bset[k]) { 74 | combs.emplace_back(k + 1); 75 | } 76 | } 77 | 78 | return combs; 79 | } 80 | 81 | pair backtrackOptimal() noexcept { 82 | Node minNode; 83 | int bits = (1 << N) - 2; 84 | 85 | for (int k = 1; k < N; k++) { 86 | if (minNode.dist > C[bits][k].dist + dist[k][0]) { 87 | minNode = Node{C[bits][k].dist + dist[k][0], k}; 88 | } 89 | } 90 | 91 | if (minNode.dist == INF) { 92 | return {-1, {}}; 93 | } 94 | 95 | pair optimalTour; 96 | 97 | optimalTour.second.reserve(N); 98 | optimalTour.first = minNode.dist; 99 | optimalTour.second.emplace_back(1); 100 | 101 | for (int i = 0; i < N - 1; i++) { 102 | optimalTour.second.emplace_back(minNode.parent + 1); 103 | minNode.parent = C[bits][minNode.parent].parent; 104 | bits = bits ^ (1 << (optimalTour.second.back() - 1)); 105 | } 106 | 107 | return optimalTour; 108 | } 109 | }; 110 | 111 | int main() { 112 | ios_base::sync_with_stdio(0); 113 | cin.tie(0); 114 | cout.tie(0); 115 | // freopen("input.txt", "r", stdin); 116 | // freopen("output.txt", "w", stdout); 117 | 118 | int n, m, u, v, w; 119 | cin >> n >> m; 120 | 121 | vvi g(n, vi(n, INF)); 122 | 123 | for (int i = 0; i < m; i++) { 124 | cin >> u >> v >> w; 125 | --u, --v; 126 | g[u][v] = g[v][u] = w; 127 | } 128 | 129 | TSP tsp(g); 130 | const pair tour = tsp.optimalTour(); 131 | 132 | printf("%d\n", tour.first); 133 | 134 | if (tour.first == -1) { 135 | return 0; 136 | } 137 | 138 | for (auto p: tour.second) { 139 | printf("%d ", p); 140 | } 141 | 142 | printf("\n"); 143 | 144 | return 0; 145 | } -------------------------------------------------------------------------------- /advanced-algorithms-and-complexity/week-5/heavy_hitters.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | struct HashFunction { 30 | long a, b, p, m; 31 | 32 | long operator()(long x) const noexcept { 33 | return ((a * x + b) % p) % m; 34 | } 35 | }; 36 | 37 | struct SignFunction { 38 | static default_random_engine gen; 39 | static uniform_int_distribution dist; 40 | 41 | HashFunction hf; 42 | 43 | SignFunction() noexcept: hf{ dist(gen), dist(gen), 10000019, 1000} {} 44 | 45 | int operator()(long x) const noexcept { 46 | return hf(x) > 500 ? 1 : -1; 47 | } 48 | }; 49 | 50 | default_random_engine SignFunction::gen = default_random_engine(); 51 | uniform_int_distribution SignFunction::dist = uniform_int_distribution(10, 100); 52 | 53 | struct Funcs { 54 | HashFunction hf; 55 | SignFunction sf; 56 | }; 57 | 58 | struct CountSketch { 59 | CountSketch(long n) noexcept: 60 | b{ (int)log(n) * 50}, t{ (int) log(n) + 1}, data{ vector>(t, vector(b)) }, ithData{ vector(data.size()) } { 61 | default_random_engine gen; 62 | uniform_int_distribution dist(3, 50); 63 | 64 | long p = 10e8 + 19; 65 | functions.reserve(data.size()); 66 | 67 | for (auto i = 0; i < t; i++) { 68 | functions.push_back(Funcs{ HashFunction{ dist(gen), dist(gen), p, b }, SignFunction() }); 69 | } 70 | } 71 | 72 | void update(long i, long frq = 1) noexcept { 73 | for (auto j = 0u; j < data.size(); j++) { 74 | data[j][functions[j].hf(i)] += (functions[j].sf(i) * frq); 75 | } 76 | } 77 | 78 | long estimate(long i) noexcept { 79 | for (auto j = 0u; j < data.size(); j++) { 80 | ithData[j] = data[j][functions[j].hf(i)] * functions[j].sf(i); 81 | } 82 | 83 | return median(); 84 | } 85 | 86 | private: 87 | const int b, t; 88 | vector functions; 89 | vector> data; 90 | vector ithData; 91 | 92 | long median() noexcept { 93 | nth_element(begin(ithData), begin(ithData) + ithData.size() / 2, end(ithData)); 94 | 95 | return *next(begin(ithData), ithData.size() / 2); 96 | } 97 | }; 98 | 99 | int main() { 100 | ios_base::sync_with_stdio(0); 101 | cin.tie(0); 102 | cout.tie(0); 103 | // freopen("input.txt", "r", stdin); 104 | // freopen("output.txt", "w", stdout); 105 | 106 | long n, t, id, val, q, query; 107 | cin >> n >> t; 108 | 109 | CountSketch countSketch(n); 110 | 111 | for (long i = 0; i < n; i++) { 112 | cin >> id >> val; 113 | countSketch.update(id, val); 114 | } 115 | 116 | for (long i = 0; i < n; i++) { 117 | cin >> id >> val; 118 | countSketch.update(id, -val); 119 | } 120 | 121 | cin >> q; 122 | 123 | for (long i = 0; i < q; i++) { 124 | cin >> query; 125 | printf("%c ", (countSketch.estimate(query) >= t) ? '1' : '0'); 126 | } 127 | 128 | printf("\n"); 129 | 130 | return 0; 131 | } -------------------------------------------------------------------------------- /algorithmic-toolbox/Coursera WLDWN5BQS34C.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virtyaluk/coursera-data-structures-algorithms/9743587e0520ead50d1838fa228877be0282cff1/algorithmic-toolbox/Coursera WLDWN5BQS34C.pdf -------------------------------------------------------------------------------- /algorithmic-toolbox/week-1/aplusb.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long 17 | typedef vector vi; 18 | typedef vector vf; 19 | typedef vector vd; 20 | 21 | const int MAX_N = 1e5 + 1; 22 | const int MOD = 1e9 + 7; 23 | const int INF = 1e9; 24 | const ll LINF = 1e18; 25 | 26 | int main() { 27 | ios_base::sync_with_stdio(0); 28 | cin.tie(0); 29 | cout.tie(0); 30 | // freopen("input.txt", "r", stdin); 31 | // freopen("output.txt", "w", stdout); 32 | 33 | int x, y; 34 | cin >> x >> y; 35 | 36 | cout << (x + y) << endl; 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /algorithmic-toolbox/week-1/maximum_pairwise_product.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long 17 | typedef vector vi; 18 | typedef vector vf; 19 | typedef vector vd; 20 | 21 | const int MAX_N = 1e5 + 1; 22 | const int MOD = 1e9 + 7; 23 | const int INF = 1e9; 24 | const ll LINF = 1e18; 25 | 26 | int main() { 27 | ios_base::sync_with_stdio(0); 28 | cin.tie(0); 29 | cout.tie(0); 30 | // freopen("input.txt", "r", stdin); 31 | // freopen("output.txt", "w", stdout); 32 | 33 | long long int n, a = 0, b = 0, x; 34 | cin >> n; 35 | 36 | while (n--) { 37 | cin >> x; 38 | 39 | if (x > a) { 40 | b = a; 41 | a = x; 42 | } else if (x > b) { 43 | b = x; 44 | } 45 | } 46 | 47 | cout << (a * b) << endl; 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /algorithmic-toolbox/week-2/fibonacci.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long 17 | #define lli long long int 18 | typedef vector vi; 19 | typedef vector vll; 20 | typedef vector vvi; 21 | typedef vector vvll; 22 | typedef vector vf; 23 | typedef vector vd; 24 | 25 | const int MAX_N = 1e5 + 1; 26 | const int MOD = 1e9 + 7; 27 | const int INF = 1e9; 28 | const ll LINF = 1e18; 29 | 30 | int main() { 31 | ios_base::sync_with_stdio(0); 32 | cin.tie(0); 33 | cout.tie(0); 34 | // freopen("input.txt", "r", stdin); 35 | // freopen("output.txt", "w", stdout); 36 | 37 | int n; 38 | cin >> n; 39 | 40 | vll dp(n + 1); 41 | dp[0] = 0; 42 | dp[1] = 1; 43 | 44 | for (int i = 2; i <= n; i++) { 45 | dp[i] = dp[i - 1] + dp[i - 2]; 46 | } 47 | 48 | cout << dp[n] << endl; 49 | 50 | return 0; 51 | } -------------------------------------------------------------------------------- /algorithmic-toolbox/week-2/fibonacci_last_digit.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long 17 | #define lli long long int 18 | typedef vector vi; 19 | typedef vector vll; 20 | typedef vector vvi; 21 | typedef vector vvll; 22 | typedef vector vf; 23 | typedef vector vd; 24 | 25 | const int MAX_N = 1e5 + 1; 26 | const int MOD = 1e9 + 7; 27 | const int INF = 1e9; 28 | const ll LINF = 1e18; 29 | 30 | int main() { 31 | ios_base::sync_with_stdio(0); 32 | cin.tie(0); 33 | cout.tie(0); 34 | // freopen("input.txt", "r", stdin); 35 | // freopen("output.txt", "w", stdout); 36 | 37 | int n; 38 | cin >> n; 39 | 40 | vll dp(n + 1); 41 | dp[0] = 0; 42 | dp[1] = 1; 43 | 44 | for (int i = 2; i <= n; i++) { 45 | dp[i] = (dp[i - 1] + dp[i - 2]) % 10; 46 | } 47 | 48 | cout << dp[n] << endl; 49 | 50 | return 0; 51 | } -------------------------------------------------------------------------------- /algorithmic-toolbox/week-2/fibonacci_partial_sum.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | ll getFibN(ll n) { 30 | ll f1 = 0, f2 = 1, f; 31 | 32 | for (int i = 0; i < n - 1; ++i) { 33 | f = (f1 + f2) % 10; 34 | f1 = f2; 35 | f2 = f; 36 | } 37 | return f - 1; 38 | } 39 | 40 | int main() { 41 | ios_base::sync_with_stdio(0); 42 | cin.tie(0); 43 | cout.tie(0); 44 | // freopen("input.txt", "r", stdin); 45 | // freopen("output.txt", "w", stdout); 46 | 47 | ll m, n; 48 | cin >> m >> n; 49 | 50 | n = (n + 2) % 60; 51 | m = (m + 1) % 60; 52 | 53 | ll a, b; 54 | 55 | if (n <= 1) { 56 | a = n - 1; 57 | } else { 58 | a = getFibN(n); 59 | } 60 | 61 | if (m <= 1) { 62 | b = m - 1; 63 | } else { 64 | b = getFibN(m); 65 | } 66 | 67 | if (a >= b) { 68 | cout << (a - b) << endl; 69 | } else { 70 | cout << (10 + a - b) << endl; 71 | } 72 | 73 | return 0; 74 | } -------------------------------------------------------------------------------- /algorithmic-toolbox/week-2/fibonacci_sum.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | ll getFibN(ll n) { 30 | if (n <= 1) { 31 | return n; 32 | } 33 | 34 | ll f1 = 0; 35 | ll f2 = 1; 36 | 37 | for (int i = 0; i < n - 1; ++i) { 38 | ll f = f1 % 10; 39 | f1 = f2 % 10; 40 | f2 = f + f2 % 10; 41 | } 42 | return f2 % 10; 43 | } 44 | 45 | int main() { 46 | ios_base::sync_with_stdio(0); 47 | cin.tie(0); 48 | cout.tie(0); 49 | // freopen("input.txt", "r", stdin); 50 | // freopen("output.txt", "w", stdout); 51 | 52 | ll n; 53 | cin >> n; 54 | 55 | n = (n + 2) % 60; 56 | ll newLast = getFibN(n); 57 | 58 | if (newLast == 0) { 59 | cout << 9 << endl; 60 | } else { 61 | cout << newLast - 1 << endl; 62 | } 63 | 64 | return 0; 65 | } -------------------------------------------------------------------------------- /algorithmic-toolbox/week-2/fibonacci_sum_of_squares.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | ll getFibN(ll n) { 30 | if (n <= 1) { 31 | return n; 32 | } 33 | 34 | ll f1 = 0; 35 | ll f2 = 1; 36 | 37 | for (int i = 0; i < n - 1; ++i) { 38 | ll f = f1 % 10; 39 | f1 = f2 % 10; 40 | f2 = f + f2 % 10; 41 | } 42 | return f2 % 10; 43 | } 44 | 45 | int main() { 46 | ios_base::sync_with_stdio(0); 47 | cin.tie(0); 48 | cout.tie(0); 49 | // freopen("input.txt", "r", stdin); 50 | // freopen("output.txt", "w", stdout); 51 | 52 | ll n; 53 | cin >> n; 54 | 55 | ll fn = getFibN(n % 60), fn1 = getFibN((n + 1) % 60); 56 | 57 | cout << (fn * fn1) % 10 << endl; 58 | 59 | return 0; 60 | } -------------------------------------------------------------------------------- /algorithmic-toolbox/week-2/gcd.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long 17 | #define lli long long int 18 | typedef vector vi; 19 | typedef vector vll; 20 | typedef vector vvi; 21 | typedef vector vvll; 22 | typedef vector vf; 23 | typedef vector vd; 24 | 25 | const int MAX_N = 1e5 + 1; 26 | const int MOD = 1e9 + 7; 27 | const int INF = 1e9; 28 | const ll LINF = 1e18; 29 | 30 | ll gcd(ll a, ll b) { 31 | if (b == 0) { 32 | return a; 33 | } 34 | 35 | return gcd(b, a % b); 36 | } 37 | 38 | int main() { 39 | ios_base::sync_with_stdio(0); 40 | cin.tie(0); 41 | cout.tie(0); 42 | // freopen("input.txt", "r", stdin); 43 | // freopen("output.txt", "w", stdout); 44 | 45 | int a, b; 46 | cin >> a >> b; 47 | 48 | cout << gcd(a, b) << endl; 49 | 50 | return 0; 51 | } -------------------------------------------------------------------------------- /algorithmic-toolbox/week-2/huge_fibonacci.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | ll pisano(ll m) { 30 | ll f1 = 0, f2 = 1, f = f1 + f2; 31 | 32 | for (int i = 0; i < m * m; i++) { 33 | f = (f1 + f2) % m; 34 | f1 = f2; 35 | f2 = f; 36 | 37 | if (f1 == 0 && f2 == 1) { 38 | return i + 1; 39 | } 40 | } 41 | 42 | return 0; 43 | } 44 | 45 | int main() { 46 | ios_base::sync_with_stdio(0); 47 | cin.tie(0); 48 | cout.tie(0); 49 | // freopen("input.txt", "r", stdin); 50 | // freopen("output.txt", "w", stdout); 51 | 52 | ll n, m; 53 | cin >> n >> m; 54 | 55 | n %= pisano(m); 56 | ll f1 = 0, f2 = 1, f = n; 57 | 58 | for (int i = 1; i < n; i++) { 59 | f = (f1 + f2) % m; 60 | f1 = f2; 61 | f2 = f; 62 | } 63 | 64 | cout << f % m << endl; 65 | 66 | return 0; 67 | } -------------------------------------------------------------------------------- /algorithmic-toolbox/week-2/lcm.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long 17 | #define lli long long int 18 | typedef vector vi; 19 | typedef vector vll; 20 | typedef vector vvi; 21 | typedef vector vvll; 22 | typedef vector vf; 23 | typedef vector vd; 24 | 25 | const int MAX_N = 1e5 + 1; 26 | const int MOD = 1e9 + 7; 27 | const int INF = 1e9; 28 | const ll LINF = 1e18; 29 | 30 | ll gcd(ll a, ll b) { 31 | if (b == 0) { 32 | return a; 33 | } 34 | 35 | return gcd(b, a % b); 36 | } 37 | 38 | ll lcm(ll a, ll b) { 39 | return abs(a) / gcd(a, b) * abs(b); 40 | } 41 | 42 | int main() { 43 | ios_base::sync_with_stdio(0); 44 | cin.tie(0); 45 | cout.tie(0); 46 | // freopen("input.txt", "r", stdin); 47 | // freopen("output.txt", "w", stdout); 48 | 49 | int a, b; 50 | cin >> a >> b; 51 | 52 | cout << lcm(a, b) << endl; 53 | 54 | return 0; 55 | } -------------------------------------------------------------------------------- /algorithmic-toolbox/week-3/car_fueling.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | int main() { 30 | ios_base::sync_with_stdio(0); 31 | cin.tie(0); 32 | cout.tie(0); 33 | // freopen("input.txt", "r", stdin); 34 | // freopen("output.txt", "w", stdout); 35 | 36 | ll d, m, n, ans = 0; 37 | cin >> d >> m >> n; 38 | 39 | vll stop(n + 2); 40 | stop[n + 1] = d; 41 | 42 | for (int i = 1; i <= n; i++) { 43 | cin >> stop[i]; 44 | } 45 | 46 | int curRefill = 0; 47 | 48 | while (curRefill <= n) { 49 | int lastRefill = curRefill; 50 | 51 | while (curRefill <= n && stop[curRefill + 1] - stop[lastRefill] <= m) { 52 | curRefill++; 53 | } 54 | 55 | if (curRefill == lastRefill) { 56 | ans = -1; 57 | break; 58 | } 59 | 60 | if (curRefill <= n) { 61 | ans++; 62 | } 63 | } 64 | 65 | cout << ans << endl; 66 | 67 | return 0; 68 | } -------------------------------------------------------------------------------- /algorithmic-toolbox/week-3/change.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | int main() { 30 | ios_base::sync_with_stdio(0); 31 | cin.tie(0); 32 | cout.tie(0); 33 | // freopen("input.txt", "r", stdin); 34 | // freopen("output.txt", "w", stdout); 35 | 36 | ll m, ans = 0; 37 | cin >> m; 38 | 39 | vector coins = {10, 5, 1}; 40 | 41 | for (int& coin: coins) { 42 | ans += m / coin; 43 | m %= coin; 44 | } 45 | 46 | cout << ans << endl; 47 | 48 | return 0; 49 | } -------------------------------------------------------------------------------- /algorithmic-toolbox/week-3/converging_segments.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | int main() { 30 | ios_base::sync_with_stdio(0); 31 | cin.tie(0); 32 | cout.tie(0); 33 | // freopen("input.txt", "r", stdin); 34 | // freopen("output.txt", "w", stdout); 35 | 36 | ll n; 37 | cin >> n; 38 | 39 | vector> segments; 40 | 41 | for (int i = 0; i < n; i++) { 42 | ll a, b; 43 | cin >> a >> b; 44 | 45 | segments.push_back({a, b}); 46 | } 47 | 48 | sort(segments.begin(), segments.end(), [](pair& lhs, pair& rhs) { 49 | return lhs.second < rhs.second; 50 | }); 51 | 52 | ll point = segments[0].second; 53 | vll ans = {point}; 54 | 55 | for (int i = 1; i < n; i++) { 56 | if (point < segments[i].first || point > segments[i].second) { 57 | point = segments[i].second; 58 | ans.push_back(point); 59 | } 60 | } 61 | 62 | cout << ans.size() << endl; 63 | copy(ans.begin(), ans.end(), ostream_iterator(cout, " ")); 64 | cout << endl; 65 | 66 | return 0; 67 | } -------------------------------------------------------------------------------- /algorithmic-toolbox/week-3/different_summands.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | int main() { 30 | ios_base::sync_with_stdio(0); 31 | cin.tie(0); 32 | cout.tie(0); 33 | // freopen("input.txt", "r", stdin); 34 | // freopen("output.txt", "w", stdout); 35 | 36 | ll n, k = 0; 37 | cin >> n; 38 | 39 | vll ans; 40 | 41 | for (int i = 1; i <= n; i++) { 42 | n -= i; 43 | 44 | if (n <= i) { 45 | ans.push_back(n + i); 46 | } else if (n == 0) { 47 | ans.push_back(i); 48 | break; 49 | } else { 50 | ans.push_back(i); 51 | } 52 | } 53 | 54 | cout << ans.size() << endl; 55 | copy(ans.begin(), ans.end(), ostream_iterator(cout, " ")); 56 | cout << endl; 57 | 58 | return 0; 59 | } -------------------------------------------------------------------------------- /algorithmic-toolbox/week-3/dot_product.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | int main() { 30 | ios_base::sync_with_stdio(0); 31 | cin.tie(0); 32 | cout.tie(0); 33 | // freopen("input.txt", "r", stdin); 34 | // freopen("output.txt", "w", stdout); 35 | 36 | ll n, ans = 0; 37 | cin >> n; 38 | 39 | vll a(n), b(n); 40 | 41 | for (int i = 0; i < n; i++) { 42 | cin >> a[i]; 43 | } 44 | 45 | for (int i = 0; i < n; i++) { 46 | cin >> b[i]; 47 | } 48 | 49 | sort(a.begin(), a.end()); 50 | sort(b.begin(), b.end()); 51 | 52 | for (int i = 0; i < n; i++) { 53 | ans += a[i] * b[i]; 54 | } 55 | 56 | cout << ans << endl; 57 | 58 | return 0; 59 | } -------------------------------------------------------------------------------- /algorithmic-toolbox/week-3/fractional_knapsack.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | int main() { 30 | ios_base::sync_with_stdio(0); 31 | cin.tie(0); 32 | cout.tie(0); 33 | // freopen("input.txt", "r", stdin); 34 | // freopen("output.txt", "w", stdout); 35 | 36 | ll n, W; 37 | cin >> n >> W; 38 | 39 | vector> vw; 40 | double ans; 41 | 42 | for (int i = 0; i < n; i++) { 43 | double v, w; 44 | cin >> v >> w; 45 | 46 | vw.push_back({v, w}); 47 | } 48 | 49 | sort(vw.begin(), vw.end(), [](pair& lhs, pair& rhs) { 50 | return lhs.first / lhs.second > rhs.first / rhs.second; 51 | }); 52 | 53 | for (pair& item: vw) { 54 | if (W == 0) { 55 | break; 56 | } 57 | 58 | double amount = min((double) W, item.second); 59 | 60 | ans += item.first / item.second * amount; 61 | W -= amount; 62 | } 63 | 64 | cout.precision(10); 65 | cout << ans << endl; 66 | 67 | return 0; 68 | } -------------------------------------------------------------------------------- /algorithmic-toolbox/week-3/largest_number.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | int main() { 30 | ios_base::sync_with_stdio(0); 31 | cin.tie(0); 32 | cout.tie(0); 33 | // freopen("input.txt", "r", stdin); 34 | // freopen("output.txt", "w", stdout); 35 | 36 | ll n; 37 | cin >> n; 38 | 39 | string ans; 40 | vector a; 41 | 42 | copy_n(istream_iterator(cin), n, back_inserter(a)); 43 | 44 | sort(a.begin(), a.end(), [](string& lhs, string& rhs) { 45 | return lhs + rhs > rhs + lhs; 46 | }); 47 | 48 | for (string& num: a) { 49 | cout << num; 50 | } 51 | 52 | cout << endl; 53 | 54 | return 0; 55 | } -------------------------------------------------------------------------------- /algorithmic-toolbox/week-4/binary_search.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | ll bs(vll& a, ll num) { 30 | int lo = 0, hi = a.size() - 1; 31 | 32 | while (lo <= hi) { 33 | int mid = lo + (hi - lo) / 2; 34 | 35 | if (a[mid] == num) { 36 | return mid; 37 | } else if (num < a[mid]) { 38 | hi = mid - 1; 39 | } else { 40 | lo = mid + 1; 41 | } 42 | } 43 | 44 | return -1; 45 | } 46 | 47 | int main() { 48 | ios_base::sync_with_stdio(0); 49 | cin.tie(0); 50 | cout.tie(0); 51 | // freopen("input.txt", "r", stdin); 52 | // freopen("output.txt", "w", stdout); 53 | 54 | ll n, k; 55 | cin >> n; 56 | 57 | vll a(n); 58 | 59 | for (int i = 0; i < n; i++) { 60 | cin >> a[i]; 61 | } 62 | 63 | cin >> k; 64 | 65 | vll b(k); 66 | 67 | for (int i = 0; i < k; i++) { 68 | cin >> b[i]; 69 | 70 | b[i] = bs(a, b[i]); 71 | } 72 | 73 | copy(b.begin(), b.end(), ostream_iterator(cout, " ")); 74 | cout << endl; 75 | 76 | return 0; 77 | } -------------------------------------------------------------------------------- /algorithmic-toolbox/week-4/closest.py: -------------------------------------------------------------------------------- 1 | # python3 2 | # https://medium.com/@andriylazorenko/closest-pair-of-points-in-python-79e2409fc0b2 3 | 4 | import math 5 | def dist(p1, p2): 6 | return math.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2) 7 | 8 | def closest_split_pair(p_x, p_y, delta, best_pair): 9 | ln_x = len(p_x) # store length - quicker 10 | mx_x = p_x[ln_x // 2][0] # select midpoint on x-sorted array 11 | 12 | # Create a subarray of points not further than delta from midpoint on x-sorted array 13 | s_y = [x for x in p_y if mx_x - delta <= x[0] <= mx_x + delta] 14 | 15 | best = delta # assign delta value to best 16 | ln_y = len(s_y) # store length of subarray for quickness 17 | for i in range(ln_y - 1): 18 | for j in range(i+1, min(i + 5, ln_y)): # We have to check only next 5 points; proof found in literature 19 | p, q = s_y[i], s_y[j] 20 | dst = dist(p, q) 21 | if dst < best: 22 | best_pair = p, q 23 | best = dst 24 | return best_pair[0], best_pair[1], best 25 | 26 | 27 | def brute(ax): 28 | mi = dist(ax[0], ax[1]) 29 | p1 = ax[0] 30 | p2 = ax[1] 31 | ln_ax = len(ax) 32 | if ln_ax == 2: 33 | return p1, p2, mi 34 | for i in range(ln_ax-1): 35 | for j in range(i + 1, ln_ax): 36 | if i != 0 and j != 1: 37 | d = dist(ax[i], ax[j]) 38 | if d < mi: # Update min_dist and points 39 | mi = d 40 | p1, p2 = ax[i], ax[j] 41 | return p1, p2, mi 42 | 43 | 44 | def closest_pair(ax, ay): 45 | ln_ax = len(ax) # It's quicker to assign variable 46 | if ln_ax <= 3: 47 | return brute(ax) # A call to bruteforce comparison 48 | mid = ln_ax // 2 # Division without remainder, need int 49 | Qx = ax[:mid] # Two-part split 50 | Rx = ax[mid:] 51 | 52 | midpoint = ax[mid][0] 53 | Qy = list() 54 | Ry = list() 55 | for x in ay: # split ay into 2 arrays using midpoint 56 | if x[0] < midpoint: 57 | Qy.append(x) 58 | else: 59 | Ry.append(x) 60 | # Call recursively both arrays after split 61 | (p1, q1, mi1) = closest_pair(Qx, Qy) 62 | (p2, q2, mi2) = closest_pair(Rx, Ry) 63 | 64 | # Determine smaller distance between points of 2 arrays 65 | if mi1 <= mi2: 66 | d = mi1 67 | mn = (p1, q1) 68 | else: 69 | d = mi2 70 | mn = (p2, q2) 71 | 72 | # Call function to account for points on the boundary 73 | (p3, q3, mi3) = closest_split_pair(ax, ay, d, mn) 74 | # Determine smallest distance for the array 75 | if d <= mi3: 76 | return mn[0], mn[1], d 77 | else: 78 | return p3, q3, mi3 79 | 80 | 81 | def solution(a): 82 | ax = sorted(a, key=lambda x: x[0]) # Presorting x-wise O(nlogn) 83 | ay = sorted(a, key=lambda x: (x[1], x[0])) # Presorting y-wise then x-wise O(nlogn) 84 | p1, p2, mi = closest_pair(ax, ay) # Recursive D&C function 85 | return mi 86 | 87 | 88 | # Input 89 | points = list() 90 | n = int(input()) 91 | for i in range(n): 92 | points.append([int(i) for i in input().split()]) 93 | 94 | print(solution(points)) 95 | -------------------------------------------------------------------------------- /algorithmic-toolbox/week-4/inversions.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | ll countMerge(vll& a, vll& b, ll lo, ll mid, ll hi) { 30 | ll ans = 0, i = lo, j = mid + 1, k = lo; 31 | 32 | while (i <= mid && j <= hi) { 33 | if (a[i] <= a[j]) { 34 | b[k++] = a[i++]; 35 | } else { 36 | b[k++] = a[j++]; 37 | ans += mid - i + 1; 38 | } 39 | } 40 | 41 | while (i <= mid) { 42 | b[k++] = a[i++]; 43 | } 44 | 45 | for (int i = lo; i <= hi; i++) { 46 | a[i] = b[i]; 47 | } 48 | 49 | return ans; 50 | } 51 | 52 | ll countMergeAndSort(vll& a, vll& b, ll lo, ll hi) { 53 | ll ans = 0; 54 | 55 | if (lo < hi) { 56 | ll mid = lo + (hi - lo) / 2; 57 | 58 | ans += countMergeAndSort(a, b, lo, mid); 59 | ans += countMergeAndSort(a, b, mid + 1, hi); 60 | ans += countMerge(a, b, lo, mid, hi); 61 | } 62 | 63 | return ans; 64 | } 65 | 66 | int main() { 67 | ios_base::sync_with_stdio(0); 68 | cin.tie(0); 69 | cout.tie(0); 70 | // freopen("input.txt", "r", stdin); 71 | // freopen("output.txt", "w", stdout); 72 | 73 | ll n; 74 | cin >> n; 75 | 76 | vll a, b; 77 | 78 | copy_n(istream_iterator(cin), n, back_inserter(a)); 79 | b = a; 80 | 81 | cout << countMergeAndSort(a, b, 0, n - 1) << endl; 82 | 83 | return 0; 84 | } -------------------------------------------------------------------------------- /algorithmic-toolbox/week-4/majority_element.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | int main() { 30 | ios_base::sync_with_stdio(0); 31 | cin.tie(0); 32 | cout.tie(0); 33 | // freopen("input.txt", "r", stdin); 34 | // freopen("output.txt", "w", stdout); 35 | 36 | ll n; 37 | cin >> n; 38 | 39 | unordered_map m; 40 | 41 | bool ans = false; 42 | 43 | for (int i = 0; i < n; i++) { 44 | ll num; 45 | cin >> num; 46 | 47 | m[num]++; 48 | 49 | if (m[num] > n/2) { 50 | ans = true; 51 | } 52 | } 53 | 54 | cout << int(ans) << endl; 55 | 56 | return 0; 57 | } -------------------------------------------------------------------------------- /algorithmic-toolbox/week-4/points_and_segments.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | int main() { 30 | ios_base::sync_with_stdio(0); 31 | cin.tie(0); 32 | cout.tie(0); 33 | // freopen("input.txt", "r", stdin); 34 | // freopen("output.txt", "w", stdout); 35 | 36 | ll s, p; 37 | cin >> s >> p; 38 | 39 | vector> segments; 40 | vll points(p), ans; 41 | 42 | for (int i = 0; i < s; i++) { 43 | ll a, b; 44 | cin >> a >> b; 45 | segments.push_back({a, 'l'}); 46 | segments.push_back({b, 'r'}); 47 | } 48 | 49 | for (int i = 0; i < p; i++) { 50 | cin >> points[i]; 51 | segments.push_back({points[i], 'p'}); 52 | } 53 | 54 | sort(segments.begin(), segments.end(), [](pair& lhs, pair& rhs) { 55 | if (lhs.first != rhs.first) { 56 | return lhs.first < rhs.first; 57 | } else { 58 | return lhs.second < rhs.second; 59 | } 60 | }); 61 | 62 | int count = 0; 63 | unordered_map m; 64 | 65 | for (pair seg: segments) { 66 | if (seg.second == 'l') { 67 | count++; 68 | } else if (seg.second == 'r') { 69 | count--; 70 | } else { 71 | m[seg.first] = count; 72 | } 73 | } 74 | 75 | for (int p: points) { 76 | ans.push_back(m[p]); 77 | } 78 | 79 | copy(ans.begin(), ans.end(), ostream_iterator(cout, " ")); 80 | cout << endl; 81 | 82 | return 0; 83 | } -------------------------------------------------------------------------------- /algorithmic-toolbox/week-4/sorting.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | int partition2(vector &a, int l, int r) { 30 | int x = a[l]; 31 | int j = l; 32 | for (int i = l + 1; i <= r; i++) { 33 | if (a[i] <= x) { 34 | j++; 35 | swap(a[i], a[j]); 36 | } 37 | } 38 | swap(a[l], a[j]); 39 | return j; 40 | } 41 | 42 | pair partition3(vector& a, int l, int r) { 43 | int x = a[l], lo = l, hi = r, i = l; 44 | 45 | while (i <= hi) { 46 | if (a[i] < x) { 47 | swap(a[i++], a[lo++]); 48 | } else if (a[i] > x) { 49 | swap(a[i], a[hi--]); 50 | } else { 51 | i++; 52 | } 53 | } 54 | 55 | return {lo, hi}; 56 | } 57 | 58 | void randomized_quick_sort(vector &a, int l, int r) { 59 | if (l >= r) { 60 | return; 61 | } 62 | 63 | int k = l + rand() % (r - l + 1); 64 | swap(a[l], a[k]); 65 | // int m = partition2(a, l, r); 66 | // 67 | // randomized_quick_sort(a, l, m - 1); 68 | // randomized_quick_sort(a, m + 1, r); 69 | 70 | pair bounds = partition3(a, l, r); 71 | randomized_quick_sort(a, l, bounds.first - 1); 72 | randomized_quick_sort(a, bounds.second + 1, r); 73 | } 74 | 75 | int main() { 76 | int n; 77 | std::cin >> n; 78 | vector a(n); 79 | for (size_t i = 0; i < a.size(); ++i) { 80 | std::cin >> a[i]; 81 | } 82 | randomized_quick_sort(a, 0, a.size() - 1); 83 | for (size_t i = 0; i < a.size(); ++i) { 84 | std::cout << a[i] << ' '; 85 | } 86 | cout << endl; 87 | } 88 | -------------------------------------------------------------------------------- /algorithmic-toolbox/week-5/change_dp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | int main() { 30 | ios_base::sync_with_stdio(0); 31 | cin.tie(0); 32 | cout.tie(0); 33 | // freopen("input.txt", "r", stdin); 34 | // freopen("output.txt", "w", stdout); 35 | 36 | ll n; 37 | cin >> n; 38 | 39 | unordered_set coins = {1, 3, 4}; 40 | vll dp(n + 1, INT_MAX); 41 | dp[0] = 0; 42 | dp[1] = 1; 43 | 44 | for (int i = 2; i <= n; i++) { 45 | for (const int coin: coins) { 46 | if (i >= coin) { 47 | dp[i] = min(dp[i], dp[i - coin] + 1); 48 | } 49 | } 50 | } 51 | 52 | cout << dp[n] << endl; 53 | 54 | return 0; 55 | } -------------------------------------------------------------------------------- /algorithmic-toolbox/week-5/edit_distance.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | int main() { 30 | ios_base::sync_with_stdio(0); 31 | cin.tie(0); 32 | cout.tie(0); 33 | // freopen("input.txt", "r", stdin); 34 | // freopen("output.txt", "w", stdout); 35 | 36 | string str1, str2; 37 | cin >> str1 >> str2; 38 | 39 | ll m = str1.size() + 1, n = str2.size() + 1; 40 | vvll dp(m, vll(n)); 41 | 42 | for (int i = 0; i < m; i++) { 43 | dp[i][0] = i; 44 | } 45 | 46 | for (int j = 0; j < n; j++) { 47 | dp[0][j] = j; 48 | } 49 | 50 | for (int i = 1; i < m; i++) { 51 | for (int j = 1; j < n; j++) { 52 | int diff = str1[i - 1] == str2[j - 1] ? 0 : 1; 53 | 54 | dp[i][j] = min({dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1] + diff}); 55 | } 56 | } 57 | 58 | cout << dp[m - 1][n - 1] << endl; 59 | 60 | return 0; 61 | } -------------------------------------------------------------------------------- /algorithmic-toolbox/week-5/lcs2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | int main() { 30 | ios_base::sync_with_stdio(0); 31 | cin.tie(0); 32 | cout.tie(0); 33 | // freopen("input.txt", "r", stdin); 34 | // freopen("output.txt", "w", stdout); 35 | 36 | ll n, m; 37 | vll a, b; 38 | 39 | cin >> n; 40 | copy_n(istream_iterator(cin), n, back_inserter(a)); 41 | cin >> m; 42 | copy_n(istream_iterator(cin), m, back_inserter(b)); 43 | 44 | vvll dp(n + 1, vll(m + 1)); 45 | 46 | for (int i = 1; i <= n; i++) { 47 | for (int j = 1; j <= m; j++) { 48 | int dif = a[i - 1] == b[j - 1] ? 1 : 0; 49 | dp[i][j] = max({dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1] + dif}); 50 | } 51 | } 52 | 53 | cout << dp[n][m] << endl; 54 | 55 | return 0; 56 | } -------------------------------------------------------------------------------- /algorithmic-toolbox/week-5/lcs3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | int main() { 30 | ios_base::sync_with_stdio(0); 31 | cin.tie(0); 32 | cout.tie(0); 33 | // freopen("input.txt", "r", stdin); 34 | // freopen("output.txt", "w", stdout); 35 | 36 | ll n, m, l; 37 | vll a, b, c; 38 | 39 | cin >> n; 40 | copy_n(istream_iterator(cin), n, back_inserter(a)); 41 | cin >> m; 42 | copy_n(istream_iterator(cin), m, back_inserter(b)); 43 | cin >> l; 44 | copy_n(istream_iterator(cin), l, back_inserter(c)); 45 | 46 | vector dp(n + 1, vvll(m + 1, vll(l + 1))); 47 | 48 | for (int i = 1; i <= n; i++) { 49 | for (int j = 1; j <= m; j++) { 50 | for (int k = 1; k <= l; k++) { 51 | if (a[i - 1] == b[j - 1] && b[j - 1] == c[k - 1]) { 52 | dp[i][j][k] = dp[i - 1][j - 1][k - 1] + 1; 53 | } else { 54 | dp[i][j][k] = max({dp[i - 1][j][k], dp[i][j - 1][k], dp[i][j][k - 1]}); 55 | } 56 | } 57 | } 58 | } 59 | 60 | cout << dp[n][m][l] << endl; 61 | 62 | return 0; 63 | } -------------------------------------------------------------------------------- /algorithmic-toolbox/week-5/primitive_calculator.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | int main() { 30 | ios_base::sync_with_stdio(0); 31 | cin.tie(0); 32 | cout.tie(0); 33 | // freopen("input.txt", "r", stdin); 34 | // freopen("output.txt", "w", stdout); 35 | 36 | ll n; 37 | cin >> n; 38 | 39 | vll dp(pow(10, 6) + 1, INT_MAX); 40 | dp[0] = 0; 41 | dp[1] = 0; 42 | dp[2] = 1; 43 | dp[3] = 1; 44 | 45 | for (int i = 4; i <= n; i++) { 46 | ll cur = INT_MAX; 47 | cur = min(cur, dp[i - 1] + 1); 48 | 49 | if (i % 2 == 0) { 50 | cur = min(cur, dp[i / 2] + 1); 51 | } 52 | 53 | if (i % 3 == 0) { 54 | cur = min(cur, dp[i / 3] + 1); 55 | } 56 | 57 | dp[i] = cur; 58 | } 59 | 60 | cout << dp[n] << endl; 61 | 62 | ll j = n; 63 | vll ans; 64 | 65 | while (j >= 0 && j != 1) { 66 | ans.push_back(j); 67 | 68 | ll nextJ = j; 69 | 70 | if (dp[j - 1] < dp[j]) { 71 | nextJ = j - 1; 72 | } 73 | 74 | if (j % 2 == 0 && dp[j / 2] < dp[j]) { 75 | nextJ = j / 2; 76 | } 77 | 78 | if (j % 3 == 0 && dp[j / 3] < dp[j]) { 79 | nextJ = j / 3; 80 | } 81 | 82 | j = nextJ; 83 | } 84 | 85 | ans.push_back(1); 86 | 87 | copy(ans.rbegin(), ans.rend(), ostream_iterator(cout, " ")); 88 | cout << endl; 89 | 90 | return 0; 91 | } -------------------------------------------------------------------------------- /algorithmic-toolbox/week-6/knapsack.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | int main() { 30 | ios_base::sync_with_stdio(0); 31 | cin.tie(0); 32 | cout.tie(0); 33 | // freopen("input.txt", "r", stdin); 34 | // freopen("output.txt", "w", stdout); 35 | 36 | ll W, n; 37 | cin >> W >> n; 38 | 39 | vll w; 40 | copy_n(istream_iterator(cin), n, back_inserter(w)); 41 | 42 | vvll dp(n + 1, vll(W + 1)); 43 | 44 | for (int i = 1; i <= n; i++) { 45 | for (int j = 1; j <= W; j++) { 46 | dp[i][j] = dp[i - 1][j]; 47 | 48 | if (w[i - 1] <= j) { 49 | dp[i][j] = max(dp[i][j], dp[i - 1][j - w[i - 1]] + w[i - 1]); 50 | } 51 | } 52 | } 53 | 54 | cout << dp[n][W] << endl; 55 | 56 | return 0; 57 | } -------------------------------------------------------------------------------- /algorithmic-toolbox/week-6/parentheses.py: -------------------------------------------------------------------------------- 1 | # Uses python3 2 | import sys 3 | 4 | def evalt(a, b, op): 5 | if op == '+': 6 | return a + b 7 | elif op == '-': 8 | return a - b 9 | elif op == '*': 10 | return a * b 11 | else: 12 | assert False 13 | 14 | def get_maximum_value(dataset): 15 | for i in range(len(digits)): 16 | dp_max[i][i] = digits[i] 17 | dp_min[i][i] = digits[i] 18 | 19 | for s in range(0, len(digits)): 20 | for i in range(0, len(digits) - s - 1): 21 | j = i + s + 1 22 | min_value, max_value = min_max_value(i, j) 23 | dp_max[i][j] = max_value 24 | dp_min[i][j] = min_value 25 | 26 | def min_max_value(i, j): 27 | min_value = sys.maxsize 28 | max_value = -sys.maxsize 29 | for k in range(i, j): 30 | a = evalt(dp_max[i][k], dp_max[k+1][j], ops[k]) 31 | b = evalt(dp_max[i][k], dp_min[k+1][j], ops[k]) 32 | c = evalt(dp_min[i][k], dp_max[k+1][j], ops[k]) 33 | d = evalt(dp_min[i][k], dp_min[k+1][j], ops[k]) 34 | min_value = min(min_value, a, b, c, d) 35 | max_value = max(max_value, a, b, c, d) 36 | return min_value, max_value 37 | 38 | 39 | if __name__ == "__main__": 40 | dataset = input() 41 | digits = list(map(int, dataset[0::2])) 42 | ops = list(dataset[1::2]) 43 | dp_min = [[0 for x in range(len(digits))] for y in range(len(digits))] 44 | dp_max = [[0 for x in range(len(digits))] for y in range(len(digits))] 45 | get_maximum_value(dataset) 46 | print(dp_max[0][len(digits) - 1]) 47 | -------------------------------------------------------------------------------- /algorithmic-toolbox/week-6/partition3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | ll partition3(vll& v) { 30 | ll sum = accumulate(v.begin(), v.end(), 0), n = v.size(); 31 | 32 | if (sum % 3 != 0 || n < 3) { 33 | return 0; 34 | } 35 | 36 | vvll dp(sum + 1, vll(n + 1)); 37 | 38 | for (int i = 0; i <= sum; i++) { 39 | int c = 0; 40 | 41 | for (int j = 0; j <= n; j++) { 42 | if (i == 0) { 43 | dp[i][j] = 1; 44 | } else if (j == 0 && i != 0) { 45 | dp[i][j] = 0; 46 | } else if (v[j - 1] <= i) { 47 | dp[i][j] = (dp[i][j - 1] || dp[i - v[j - 1]][j - 1]); 48 | } else { 49 | dp[i][j] = dp[i][j - 1]; 50 | } 51 | 52 | if (dp[i][j] == 1) { 53 | c++; 54 | } 55 | } 56 | 57 | if (i == sum / 3 && c > 1) { 58 | return 1; 59 | } else if (i == sum / 3) { 60 | return 0; 61 | } 62 | } 63 | 64 | return 0; 65 | } 66 | 67 | int main() { 68 | ios_base::sync_with_stdio(0); 69 | cin.tie(0); 70 | cout.tie(0); 71 | // freopen("input.txt", "r", stdin); 72 | // freopen("output.txt", "w", stdout); 73 | 74 | ll n; 75 | cin >> n; 76 | 77 | vll v; 78 | copy_n(istream_iterator(cin), n, back_inserter(v)); 79 | 80 | cout << partition3(v) << endl; 81 | 82 | return 0; 83 | } -------------------------------------------------------------------------------- /algorithms-on-graphs/Coursera D4EZTNZ5ATXM.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virtyaluk/coursera-data-structures-algorithms/9743587e0520ead50d1838fa228877be0282cff1/algorithms-on-graphs/Coursera D4EZTNZ5ATXM.pdf -------------------------------------------------------------------------------- /algorithms-on-graphs/week-1/connected_components.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | int main() { 30 | ios_base::sync_with_stdio(0); 31 | cin.tie(0); 32 | cout.tie(0); 33 | // freopen("input.txt", "r", stdin); 34 | // freopen("output.txt", "w", stdout); 35 | 36 | ll n, m, u, v; 37 | cin >> n >> m; 38 | 39 | vvll g(n + 1, vll()); 40 | 41 | for (int i = 0; i < m; i++) { 42 | cin >> u >> v; 43 | g[u].push_back(v); 44 | g[v].push_back(u); 45 | } 46 | 47 | vll visited(n + 1, 0); 48 | ll ans = 0; 49 | 50 | for (ll i = 1; i <= n; i++) { 51 | if (visited[i] == 0) { 52 | ans++; 53 | queue q; 54 | q.push(i); 55 | 56 | while (!q.empty()) { 57 | ll node = q.front(); 58 | q.pop(); 59 | 60 | visited[node] = ans; 61 | 62 | for (ll& next: g[node]) { 63 | if (visited[next] == 0) { 64 | q.push(next); 65 | } 66 | } 67 | } 68 | } 69 | } 70 | 71 | cout << ans << endl; 72 | 73 | return 0; 74 | } -------------------------------------------------------------------------------- /algorithms-on-graphs/week-1/reachabillity.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | int main() { 30 | ios_base::sync_with_stdio(0); 31 | cin.tie(0); 32 | cout.tie(0); 33 | // freopen("input.txt", "r", stdin); 34 | // freopen("output.txt", "w", stdout); 35 | 36 | ll n, m, u, v, s, e; 37 | cin >> n >> m; 38 | 39 | vvll g(n + 1, vll()); 40 | 41 | for (int i = 0; i < m; i++) { 42 | cin >> u >> v; 43 | g[u].push_back(v); 44 | g[v].push_back(u); 45 | } 46 | 47 | cin >> s >> e; 48 | 49 | vector visited(n + 1); 50 | queue q; 51 | bool found = false; 52 | 53 | q.push(s); 54 | 55 | while (!q.empty()) { 56 | ll node = q.front(); 57 | q.pop(); 58 | 59 | if (node == e) { 60 | found = true; 61 | break; 62 | } 63 | 64 | visited[node] = true; 65 | 66 | for (ll& next: g[node]) { 67 | if (!visited[next]) { 68 | q.push(next); 69 | } 70 | } 71 | } 72 | 73 | cout << int(found) << endl; 74 | 75 | return 0; 76 | } -------------------------------------------------------------------------------- /algorithms-on-graphs/week-2/acyclicity.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | bool dfs(vvll& g, ll node, vector& visited) { 30 | visited[node] = true; 31 | 32 | bool ans = true; 33 | 34 | for (ll& next: g[node]) { 35 | if (visited[next] || !dfs(g, next, visited)) { 36 | ans = false; 37 | break; 38 | } 39 | } 40 | 41 | visited[node] = false; 42 | 43 | return ans; 44 | } 45 | 46 | int main() { 47 | ios_base::sync_with_stdio(0); 48 | cin.tie(0); 49 | cout.tie(0); 50 | // freopen("input.txt", "r", stdin); 51 | // freopen("output.txt", "w", stdout); 52 | 53 | ll n, m, u, v; 54 | cin >> n >> m; 55 | 56 | vvll g(n + 1, vll()); 57 | 58 | for (int i = 0; i < m; i++) { 59 | cin >> u >> v; 60 | g[u].push_back(v); 61 | } 62 | 63 | bool isAcyclic = true; 64 | vector visited(n + 1); 65 | 66 | for (ll i = 1; i <= n; i++) { 67 | if (!dfs(g, i, visited)) { 68 | isAcyclic = false; 69 | break; 70 | } 71 | } 72 | 73 | cout << int(!isAcyclic) << endl; 74 | 75 | return 0; 76 | } -------------------------------------------------------------------------------- /algorithms-on-graphs/week-2/strongly_connected.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | void topoSort(vvll& g, stack& st, vector& visited, ll node) { 30 | visited[node] = true; 31 | 32 | for (ll& next: g[node]) { 33 | if (!visited[next]) { 34 | topoSort(g, st, visited, next); 35 | } 36 | } 37 | 38 | st.push(node); 39 | } 40 | 41 | void dfs(vvll& g, vector& visited, ll node) { 42 | visited[node] = true; 43 | 44 | for (ll& next: g[node]) { 45 | if (!visited[next]) { 46 | dfs(g, visited, next); 47 | } 48 | } 49 | } 50 | 51 | int main() { 52 | ios_base::sync_with_stdio(0); 53 | cin.tie(0); 54 | cout.tie(0); 55 | // freopen("input.txt", "r", stdin); 56 | // freopen("output.txt", "w", stdout); 57 | 58 | ll n, m, u, v; 59 | cin >> n >> m; 60 | 61 | vvll g(n + 1, vll()), gr(n + 1, vll()); 62 | 63 | for (int i = 0; i < m; i++) { 64 | cin >> u >> v; 65 | g[u].push_back(v); 66 | gr[v].push_back(u); 67 | } 68 | 69 | ll ans = 0; 70 | vector visited(n + 1); 71 | stack st; 72 | 73 | for (ll i = 1; i <= n; i++) { 74 | if (!visited[i]) { 75 | topoSort(g, st, visited, i); 76 | } 77 | } 78 | 79 | visited.assign(n + 1, false); 80 | 81 | while (!st.empty()) { 82 | ll node = st.top(); 83 | st.pop(); 84 | 85 | if (!visited[node]) { 86 | dfs(gr, visited, node); 87 | ans++; 88 | } 89 | } 90 | 91 | cout << ans << endl; 92 | 93 | return 0; 94 | } -------------------------------------------------------------------------------- /algorithms-on-graphs/week-2/toposort.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | void topoSort(vvll& g, stack& st, vector& visited, ll node) { 30 | visited[node] = true; 31 | 32 | for (ll& next: g[node]) { 33 | if (!visited[next]) { 34 | topoSort(g, st, visited, next); 35 | } 36 | } 37 | 38 | st.push(node); 39 | } 40 | 41 | int main() { 42 | ios_base::sync_with_stdio(0); 43 | cin.tie(0); 44 | cout.tie(0); 45 | // freopen("input.txt", "r", stdin); 46 | // freopen("output.txt", "w", stdout); 47 | 48 | ll n, m, u, v; 49 | cin >> n >> m; 50 | 51 | vvll g(n + 1, vll()); 52 | 53 | for (int i = 0; i < m; i++) { 54 | cin >> u >> v; 55 | g[u].push_back(v); 56 | } 57 | 58 | vll ans; 59 | stack st; 60 | vector visited(n + 1); 61 | 62 | for (ll i = 1; i <= n; i++) { 63 | if (!visited[i]) { 64 | topoSort(g, st, visited, i); 65 | } 66 | } 67 | 68 | while (!st.empty()) { 69 | ans.push_back(st.top()); 70 | st.pop(); 71 | } 72 | 73 | copy(ans.begin(), ans.end(), ostream_iterator(cout, " ")); 74 | cout << endl; 75 | 76 | return 0; 77 | } -------------------------------------------------------------------------------- /algorithms-on-graphs/week-3/bfs.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | int main() { 30 | ios_base::sync_with_stdio(0); 31 | cin.tie(0); 32 | cout.tie(0); 33 | // freopen("input.txt", "r", stdin); 34 | // freopen("output.txt", "w", stdout); 35 | 36 | ll n, m, u, v; 37 | cin >> n >> m; 38 | 39 | vvll g(n + 1, vll()); 40 | 41 | for (int i = 0; i < m; i++) { 42 | cin >> u >> v; 43 | g[u].push_back(v); 44 | g[v].push_back(u); 45 | } 46 | 47 | cin >> u >> v; 48 | 49 | ll ans = -1, level = 0; 50 | vector visited(n + 1); 51 | queue q; 52 | q.push(u); 53 | 54 | while (!q.empty()) { 55 | bool found = false; 56 | 57 | for (int qlen = q.size(); qlen > 0; qlen--) { 58 | ll node = q.front(); 59 | q.pop(); 60 | 61 | if (node == v) { 62 | found = true; 63 | break; 64 | } 65 | 66 | visited[node] = true; 67 | 68 | for (ll& next: g[node]) { 69 | if (!visited[next]) { 70 | q.push(next); 71 | } 72 | } 73 | } 74 | 75 | if (found) { 76 | ans = level; 77 | break; 78 | } 79 | 80 | level++; 81 | } 82 | 83 | cout << ans << endl; 84 | 85 | return 0; 86 | } -------------------------------------------------------------------------------- /algorithms-on-graphs/week-3/bipartite.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | int isBipartite(vvll& g, ll& n) { 30 | vector colors(n + 1, -1); 31 | queue q; 32 | 33 | for (ll i = 1; i <= n; i++) { 34 | if (colors[i] == -1) { 35 | colors[i] = 1; 36 | q.push(i); 37 | 38 | while (!q.empty()) { 39 | ll u = q.front(); 40 | q.pop(); 41 | 42 | for (ll& v: g[u]) { 43 | if (colors[v] == -1) { 44 | q.push(v); 45 | colors[v] = colors[u] ^ 1; 46 | } else if (colors[v] == colors[u]) { 47 | return 0; 48 | } 49 | } 50 | } 51 | } 52 | } 53 | 54 | return 1; 55 | } 56 | 57 | int main() { 58 | ios_base::sync_with_stdio(0); 59 | cin.tie(0); 60 | cout.tie(0); 61 | // freopen("input.txt", "r", stdin); 62 | // freopen("output.txt", "w", stdout); 63 | 64 | ll n, m, u, v; 65 | cin >> n >> m; 66 | 67 | vvll g(n + 1, vll()); 68 | 69 | for (int i = 0; i < m; i++) { 70 | cin >> u >> v; 71 | g[u].push_back(v); 72 | g[v].push_back(u); 73 | } 74 | 75 | cout << isBipartite(g, n) << endl; 76 | 77 | return 0; 78 | } -------------------------------------------------------------------------------- /algorithms-on-graphs/week-4/dijkstra.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | int main() { 30 | ios_base::sync_with_stdio(0); 31 | cin.tie(0); 32 | cout.tie(0); 33 | // freopen("input.txt", "r", stdin); 34 | // freopen("output.txt", "w", stdout); 35 | 36 | ll n, m, u, v, wi; 37 | cin >> n >> m; 38 | 39 | // vvll g(n + 1, vll()); 40 | vector>> w(n + 1); 41 | 42 | for (int i = 0; i < m; i++) { 43 | cin >> u >> v >> wi; 44 | // g[u].push_back(v); 45 | w[u].push_back({v, wi}); 46 | } 47 | 48 | cin >> u >> v; 49 | 50 | priority_queue, vector>, greater>> q; 51 | vll dist(n + 1, INT_MAX); 52 | 53 | dist[u] = 0; 54 | q.push({0, u}); 55 | 56 | while (!q.empty()) { 57 | pair node = q.top(); 58 | q.pop(); 59 | 60 | for (pair next: w[node.second]) { 61 | ll curDist = dist[node.second] + next.second; 62 | 63 | if (curDist < dist[next.first]) { 64 | dist[next.first] = curDist; 65 | q.push({dist[next.first], next.first}); 66 | } 67 | } 68 | } 69 | 70 | cout << (dist[v] == INT_MAX ? -1 : dist[v]) << endl; 71 | 72 | return 0; 73 | } -------------------------------------------------------------------------------- /algorithms-on-graphs/week-4/negative_cycle.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | int negativeCycle(int& n, vvi& edges) { 30 | vi dist(n + 1, 1001); 31 | deque negNodes; 32 | dist[1] = 0; 33 | 34 | for (int i = 0; i < n; i++) { 35 | for (const vector& e: edges) { 36 | int u = e[0], v = e[1], wi = e[2]; 37 | 38 | if (dist[v] > dist[u] + wi) { 39 | dist[v] = dist[u] + wi; 40 | 41 | if (i == n - 1) { 42 | negNodes.push_back(v); 43 | } 44 | } 45 | } 46 | } 47 | 48 | return negNodes.empty() ? 0 : 1; 49 | } 50 | 51 | int main() { 52 | ios_base::sync_with_stdio(0); 53 | cin.tie(0); 54 | cout.tie(0); 55 | // freopen("input.txt", "r", stdin); 56 | // freopen("output.txt", "w", stdout); 57 | 58 | int n, m, u, v, wi; 59 | cin >> n >> m; 60 | 61 | vvi edges; 62 | 63 | for (int i = 0; i < m; i++) { 64 | cin >> u >> v >> wi; 65 | edges.push_back({u, v, wi}); 66 | } 67 | 68 | cout << negativeCycle(n, edges) << endl; 69 | 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /algorithms-on-graphs/week-4/shortest_paths.py: -------------------------------------------------------------------------------- 1 | # python3 2 | 3 | from collections import deque 4 | 5 | 6 | def BellmanFord(n, graph, adj, s): 7 | dist = [float('inf')] * (n + 1) 8 | dist[s] = 0 9 | prev = [None] * (n + 1) 10 | negative_nodes = deque() 11 | for i in range(n): 12 | for u, v, w in graph: 13 | if dist[v] > dist[u] + w: 14 | dist[v] = dist[u] + w 15 | prev[v] = u 16 | if i == n - 1: 17 | negative_nodes.append(v) 18 | 19 | visited = [False] * (n + 1) 20 | while negative_nodes: 21 | u = negative_nodes.popleft() 22 | visited[u] = True 23 | dist[u] = '-' # the mark of nodes reachable from negative cycle 24 | for v in adj[u]: 25 | if not visited[v]: 26 | negative_nodes.append(v) 27 | return dist 28 | 29 | 30 | if __name__ == '__main__': 31 | n_vertices, n_edges = map(int, input().split()) 32 | edges = [] 33 | adjacency_list = [[] for _ in range(n_vertices + 1)] 34 | for i in range(n_edges): 35 | a, b, w = map(int, input().split()) 36 | edges.append((a, b, w)) # (start, end, weight) 37 | adjacency_list[a].append(b) # start : [end, weight] 38 | start = int(input()) 39 | distance = BellmanFord(n_vertices, edges, adjacency_list, start) 40 | for dist in distance[1:]: 41 | if dist == float('inf'): 42 | print('*') 43 | else: 44 | print(dist) -------------------------------------------------------------------------------- /algorithms-on-graphs/week-5/clustering.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | class disjoint_set { 30 | private: 31 | vector id, rank; 32 | ll size; 33 | 34 | public: 35 | disjoint_set(ll n) { 36 | size = n; 37 | 38 | id.resize(n); 39 | rank.resize(n, 1); 40 | iota(id.begin(), id.end(), 0); 41 | } 42 | 43 | ll find(ll p) { 44 | ll root = p; 45 | //find the root 46 | while(root != id[root]) { 47 | root = id[root]; 48 | } 49 | 50 | //perform path compression 51 | while(p != root) { 52 | ll newp = id[p]; 53 | id[p] = root; 54 | p = newp; 55 | } 56 | 57 | return root; 58 | } 59 | 60 | bool merge(ll x, ll y) { 61 | x = find(x); 62 | y = find(y); 63 | 64 | if (x == y) { 65 | return false; 66 | } 67 | 68 | if (rank[x] > rank[y]) { 69 | id[y] = x; 70 | } else { 71 | id[x] = y; 72 | } 73 | 74 | if (rank[x] == rank[y]) { 75 | rank[y] += 1; 76 | } 77 | 78 | return true; 79 | } 80 | }; 81 | 82 | double minDist(const vector>& edges, ll n, ll k) { 83 | ll u, v, nEdges = 0; 84 | double w; 85 | disjoint_set ds(n); 86 | 87 | for (const tuple& edge: edges) { 88 | tie(u, v, w) = edge; 89 | 90 | if (ds.find(u) != ds.find(v)) { 91 | if (nEdges == n - k) { 92 | return w; 93 | } else { 94 | nEdges++; 95 | 96 | ds.merge(u, v); 97 | } 98 | } 99 | } 100 | 101 | return 0; 102 | } 103 | 104 | int main() { 105 | ios_base::sync_with_stdio(0); 106 | cin.tie(0); 107 | cout.tie(0); 108 | // freopen("input.txt", "r", stdin); 109 | // freopen("output.txt", "w", stdout); 110 | 111 | ll n, k, x, y; 112 | cin >> n; 113 | 114 | vector> points; 115 | 116 | for (int i = 0; i < n; i++) { 117 | cin >> x >> y; 118 | points.push_back({x, y}); 119 | } 120 | 121 | cin >> k; 122 | 123 | ll x0, y0, x1, y1; 124 | vector> edges; 125 | 126 | for (int i = 0; i < n; i++) { 127 | tie(x0, y0) = points[i]; 128 | 129 | for (int j = i + 1; j < n; j++) { 130 | tie(x1, y1) = points[j]; 131 | double dist = sqrt(pow((double) (x1 - x0), 2) + pow((double) (y1 - y0), 2)); 132 | 133 | edges.push_back({i, j, dist}); 134 | } 135 | } 136 | 137 | sort(begin(edges), end(edges), [](const tuple& lhs, const tuple& rhs) { 138 | return get<2>(lhs) < get<2>(rhs); 139 | }); 140 | 141 | cout << setprecision(10) << minDist(edges, n, k); 142 | 143 | return 0; 144 | } 145 | -------------------------------------------------------------------------------- /algorithms-on-graphs/week-5/connecting_points.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | class disjoint_set { 30 | private: 31 | vector id, rank; 32 | ll size; 33 | 34 | public: 35 | disjoint_set(ll n) { 36 | size = n; 37 | 38 | id.resize(n); 39 | rank.resize(n, 1); 40 | iota(id.begin(), id.end(), 0); 41 | } 42 | 43 | ll find(ll p) { 44 | ll root = p; 45 | //find the root 46 | while(root != id[root]) { 47 | root = id[root]; 48 | } 49 | 50 | //perform path compression 51 | while(p != root) { 52 | ll newp = id[p]; 53 | id[p] = root; 54 | p = newp; 55 | } 56 | 57 | return root; 58 | } 59 | 60 | bool merge(ll x, ll y) { 61 | x = find(x); 62 | y = find(y); 63 | 64 | if (x == y) { 65 | return false; 66 | } 67 | 68 | if (rank[x] > rank[y]) { 69 | id[y] = x; 70 | } else { 71 | id[x] = y; 72 | } 73 | 74 | if (rank[x] == rank[y]) { 75 | rank[y] += 1; 76 | } 77 | 78 | return true; 79 | } 80 | }; 81 | 82 | double minDist(int& n, vector>& edges) { 83 | int u, v; 84 | double w, ans = 0.0; 85 | disjoint_set ds(n); 86 | 87 | sort(edges.begin(), edges.end(), [](const tuple& lhs, const tuple& rhs) { 88 | return get<2>(lhs) < get<2>(rhs); 89 | }); 90 | 91 | for (const auto& e: edges) { 92 | tie(u, v, w) = e; 93 | 94 | if (ds.find(u) != ds.find(v)) { 95 | ds.merge(u, v); 96 | ans += w; 97 | } 98 | } 99 | 100 | return ans; 101 | } 102 | 103 | int main() { 104 | ios_base::sync_with_stdio(0); 105 | cin.tie(0); 106 | cout.tie(0); 107 | // freopen("input.txt", "r", stdin); 108 | // freopen("output.txt", "w", stdout); 109 | 110 | int n, x, y; 111 | cin >> n; 112 | 113 | vector> points; 114 | 115 | for (int i = 0; i < n; i++) { 116 | cin >> x >> y; 117 | points.push_back({x, y}); 118 | } 119 | 120 | vector> edges; 121 | 122 | for (int i = 0; i < n; i++) { 123 | int x0 = points[i].first, y0 = points[i].second; 124 | 125 | for (int j = i + 1; j < n; j++) { 126 | int x = points[j].first, y = points[j].second; 127 | 128 | double dist = sqrt(pow((double) (x - x0), 2) + pow((double) (y - y0), 2)); 129 | 130 | edges.push_back({i, j, dist}); 131 | } 132 | } 133 | 134 | cout << setprecision(10) << minDist(n, edges); 135 | 136 | return 0; 137 | } 138 | -------------------------------------------------------------------------------- /algorithms-on-graphs/week-6/dist_with_coords.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | //const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | using Point = pair; 30 | using Length = long long; 31 | using Edge = pair; 32 | using Adj_List = vector>; 33 | using Distance = vector; 34 | using Queue = priority_queue, greater>; 35 | 36 | Length INF = std::numeric_limits::max() / 4; 37 | 38 | class Graph { 39 | Adj_List adj; 40 | Distance dist; 41 | vector workset; 42 | vector coords; 43 | int t_{0}, s_{0}; 44 | 45 | Length compute_path() noexcept; 46 | 47 | Length potential(int s, int t) noexcept; 48 | 49 | inline void relax(Queue &, Length, int, int) noexcept; 50 | 51 | void clear_workset() noexcept; 52 | 53 | public: 54 | Graph(int n) noexcept: adj(Adj_List(n, vector())), dist(vector(n, INF)) {}; 55 | 56 | Length Astar(int s, int t) noexcept; 57 | 58 | void add_edge(int u, int v, int w) noexcept; 59 | 60 | void add_coords(int x, int y) noexcept; 61 | }; 62 | 63 | Length Graph::potential(int s, int t) noexcept { 64 | return sqrt((coords[s].first - coords[t].first) * (coords[s].first - coords[t].first) + 65 | (coords[s].second - coords[t].second) * (coords[s].second - coords[t].second)); 66 | } 67 | 68 | void Graph::clear_workset() noexcept { 69 | for (auto &u: workset) 70 | dist[u] = INF; 71 | workset.clear(); 72 | } 73 | 74 | void Graph::add_coords(int x, int y) noexcept { 75 | coords.push_back(Point(x, y)); 76 | } 77 | 78 | void Graph::add_edge(int u, int v, int w) noexcept { 79 | adj[u].push_back(Edge(w, v)); 80 | } 81 | 82 | void Graph::relax(Queue& queue, Length weight, int v, int u) noexcept { 83 | auto dist_u_weight = dist[u] + weight - potential(u, t_) + potential(v, t_); 84 | if (dist[v] > dist_u_weight) { 85 | dist[v] = dist_u_weight; 86 | queue.push(Edge(dist[v], v)); 87 | workset.push_back(v); 88 | } 89 | } 90 | 91 | Length Graph::Astar(int s, int t) noexcept { 92 | clear_workset(); 93 | s_ = s, t_ = t; 94 | 95 | Queue queue; 96 | queue.push(Edge(0, s)); 97 | dist[s] = 0; 98 | workset.push_back(s); 99 | 100 | while (!queue.empty()) { 101 | int u = queue.top().second; 102 | queue.pop(); 103 | 104 | if (u == t) 105 | break; 106 | 107 | for (auto &edge: adj[u]) 108 | relax(queue, edge.first, edge.second, u); 109 | } 110 | 111 | return dist[t] == INF ? -1 : dist[t] + potential(s_, t_); 112 | } 113 | 114 | int main() { 115 | ios_base::sync_with_stdio(0); 116 | cin.tie(0); 117 | cout.tie(0); 118 | // freopen("input.txt", "r", stdin); 119 | // freopen("output.txt", "w", stdout); 120 | 121 | int n, m, s, t, q; 122 | cin >> n >> m; 123 | Graph g(n); 124 | 125 | for (int i = 0; i < n; i++) { 126 | int x, y; 127 | std::cin >> x >> y; 128 | g.add_coords(x, y); 129 | } 130 | 131 | for (int i = 0; i < m; i++) { 132 | int x, y, w; 133 | std::cin >> x >> y >> w; 134 | g.add_edge(x - 1, y - 1, w); 135 | } 136 | 137 | std::cin >> q; 138 | while (q--) { 139 | std::cin >> s >> t; 140 | cout << g.Astar(s - 1, t - 1) << endl; 141 | } 142 | 143 | return 0; 144 | } 145 | -------------------------------------------------------------------------------- /algorithms-on-strings/Coursera U84TMFDLT6BM.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virtyaluk/coursera-data-structures-algorithms/9743587e0520ead50d1838fa228877be0282cff1/algorithms-on-strings/Coursera U84TMFDLT6BM.pdf -------------------------------------------------------------------------------- /algorithms-on-strings/week-1/non_shared_substring.py: -------------------------------------------------------------------------------- 1 | # python3 2 | 3 | import sys 4 | import threading 5 | 6 | sys.setrecursionlimit(10 ** 7) 7 | threading.stack_size(2 ** 25) 8 | 9 | 10 | class SuffixTree: 11 | class Node: 12 | def __init__(self, label): 13 | self.label = label 14 | self.out = {} 15 | self.type = 'L' 16 | self.visited = False 17 | self.parent = None 18 | 19 | def __init__(self, s): 20 | self.root = self.Node(None) 21 | self.root.out[s[0]] = self.Node(s) 22 | 23 | for i in range(1, len(s)): 24 | j = i 25 | cur = self.root 26 | while j < len(s): 27 | if s[j] in cur.out: 28 | child = cur.out[s[j]] 29 | label = child.label 30 | k = j + 1 31 | 32 | while k - j < len(label) and s[k] == label[k - j]: 33 | k += 1 34 | 35 | if k - j == len(label): 36 | j = k 37 | cur = child 38 | else: 39 | cExist, cNew = label[k - j], s[k] 40 | mid = self.Node(label[:k - j]) 41 | mid.out[cNew] = self.Node(s[k:]) 42 | child.label = label[k - j:] 43 | mid.out[cExist] = child 44 | cur.out[s[j]] = mid 45 | else: 46 | cur.out[s[j]] = self.Node(s[j:]) 47 | 48 | def explore(self, cur, Lleaves): 49 | cur.visited = True 50 | 51 | if len(cur.out) == 0: 52 | if '#' not in cur.label: 53 | cur.type = 'R' 54 | else: 55 | Lleaves.append(cur) 56 | else: 57 | for a, node in cur.out.items(): 58 | if not node.visited: 59 | node.parent = cur 60 | self.explore(node, Lleaves) 61 | for a, node in cur.out.items(): 62 | if node.type == 'R': 63 | cur.type = 'R' 64 | 65 | def shortest_uncommon_string(self): 66 | Lleaves = [] 67 | 68 | self.explore(self.root, Lleaves) 69 | 70 | results = [] 71 | 72 | for leaf in Lleaves: 73 | char = '' 74 | substring = '' 75 | cur = leaf.parent 76 | 77 | if leaf.label[0] == '#' and cur.type == 'R': 78 | continue 79 | elif cur.type == 'R': 80 | char += leaf.label[0] 81 | 82 | while cur != self.root: 83 | substring = cur.label + substring 84 | cur = cur.parent 85 | 86 | substring += char 87 | results.append(substring) 88 | result = min(results, key=lambda x: len(x)) 89 | 90 | return result 91 | 92 | 93 | def main(): 94 | s = input() 95 | t = input() 96 | 97 | text = s + '#' + t + '$' 98 | suffix_tree = SuffixTree(text) 99 | result = suffix_tree.shortest_uncommon_string() 100 | 101 | print(result) 102 | 103 | 104 | threading.Thread(target=main).start() 105 | -------------------------------------------------------------------------------- /algorithms-on-strings/week-1/suffix_tree.py: -------------------------------------------------------------------------------- 1 | # python3 2 | 3 | from collections import deque 4 | 5 | 6 | class SuffixTree(object): 7 | class Node(object): 8 | def __init__(self, lab): 9 | self.lab = lab 10 | self.out = {} 11 | 12 | def __init__(self, s): 13 | self.root = self.Node(None) 14 | self.root.out[s[0]] = self.Node(s) 15 | 16 | for i in range(1, len(s)): 17 | cur = self.root 18 | j = i 19 | 20 | while j < len(s): 21 | if s[j] in cur.out: 22 | child = cur.out[s[j]] 23 | lab = child.lab 24 | k = j + 1 25 | 26 | while k - j < len(lab) and s[k] == lab[k - j]: 27 | k += 1 28 | if k - j == len(lab): 29 | cur = child 30 | j = k 31 | else: 32 | cExist, cNew = lab[k - j], s[k] 33 | mid = self.Node(lab[:k - j]) 34 | mid.out[cNew] = self.Node(s[k:]) 35 | child.lab = lab[k - j:] 36 | mid.out[cExist] = child 37 | cur.out[s[j]] = mid 38 | else: 39 | cur.out[s[j]] = self.Node(s[j:]) 40 | 41 | def print(self): 42 | queue = deque() 43 | queue.append(self.root) 44 | while queue: 45 | u = queue.popleft() 46 | if u != self.root: 47 | print(u.lab) 48 | for label, node in u.out.items(): 49 | queue.append(node) 50 | 51 | 52 | if __name__ == '__main__': 53 | text = input() 54 | stree = SuffixTree(text) 55 | stree.print() 56 | -------------------------------------------------------------------------------- /algorithms-on-strings/week-1/trie.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | struct TrieNode { 30 | unordered_map children; 31 | bool isEndOfWord = false; 32 | ll pos; 33 | 34 | TrieNode(ll _pos): pos(_pos){} 35 | }; 36 | 37 | class Trie { 38 | private: 39 | TrieNode *root = nullptr; 40 | ll pos = 0; 41 | 42 | public: 43 | Trie() { 44 | root = new TrieNode(pos++); 45 | } 46 | 47 | void insert(const string& s) { 48 | TrieNode *cur = root; 49 | 50 | for (const char& ch: s) { 51 | if (not cur->children.count(ch)) { 52 | cur->children[ch] = new TrieNode(pos++); 53 | } 54 | 55 | cur = cur->children[ch]; 56 | } 57 | 58 | cur->isEndOfWord = true; 59 | } 60 | 61 | TrieNode* _getRoot() { 62 | return root; 63 | } 64 | }; 65 | 66 | int main() { 67 | ios_base::sync_with_stdio(0); 68 | cin.tie(0); 69 | cout.tie(0); 70 | // freopen("input.txt", "r", stdin); 71 | // freopen("output.txt", "w", stdout); 72 | 73 | ll n; 74 | cin >> n; 75 | 76 | Trie *trie = new Trie(); 77 | string s; 78 | 79 | for (ll i = 0; i < n; i++) { 80 | cin >> s; 81 | trie->insert(s); 82 | } 83 | 84 | queue q; 85 | q.push(trie->_getRoot()); 86 | 87 | while (not q.empty()) { 88 | TrieNode *node = q.front(); 89 | q.pop(); 90 | 91 | for (auto it: node->children) { 92 | cout << (node->pos) << "->" << (it.second->pos) << ":" << it.first << '\n'; 93 | 94 | q.push(it.second); 95 | } 96 | } 97 | 98 | return 0; 99 | } -------------------------------------------------------------------------------- /algorithms-on-strings/week-1/trie_matching.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | struct TrieNode { 30 | unordered_map children; 31 | bool isEndOfWord = false; 32 | }; 33 | 34 | class Trie { 35 | private: 36 | TrieNode *root = nullptr; 37 | 38 | public: 39 | Trie() { 40 | root = new TrieNode(); 41 | } 42 | 43 | void insert(const string& s) { 44 | TrieNode *cur = root; 45 | 46 | for (const char& ch: s) { 47 | if (not cur->children.count(ch)) { 48 | cur->children[ch] = new TrieNode(); 49 | } 50 | 51 | cur = cur->children[ch]; 52 | } 53 | 54 | cur->isEndOfWord = true; 55 | } 56 | 57 | bool hasPrefix(const string& text, const int startPosition) { 58 | TrieNode *cur = root; 59 | 60 | for (int i = startPosition; i < text.size(); i++) { 61 | const char ch = text[i]; 62 | 63 | if (cur->children.count(ch)) { 64 | cur = cur->children[ch]; 65 | } else { 66 | break; 67 | } 68 | 69 | if (cur->isEndOfWord) { 70 | return true; 71 | } 72 | } 73 | 74 | return false; 75 | } 76 | }; 77 | 78 | int main() { 79 | ios_base::sync_with_stdio(0); 80 | cin.tie(0); 81 | cout.tie(0); 82 | // freopen("input.txt", "r", stdin); 83 | // freopen("output.txt", "w", stdout); 84 | 85 | string text, pattern; 86 | cin >> text; 87 | 88 | ll n; 89 | Trie *trie = new Trie(); 90 | cin >> n; 91 | 92 | for (ll i = 0; i < n; i++) { 93 | cin >> pattern; 94 | trie->insert(pattern); 95 | } 96 | 97 | vi ans; 98 | 99 | for (int i = 0; i < text.size(); i++) { 100 | if (trie->hasPrefix(text, i)) { 101 | ans.push_back(i); 102 | } 103 | } 104 | 105 | copy(begin(ans), end(ans), ostream_iterator(cout, " ")); 106 | cout << endl; 107 | 108 | return 0; 109 | } -------------------------------------------------------------------------------- /algorithms-on-strings/week-1/trie_matching_extended.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | struct TrieNode { 30 | unordered_map children; 31 | bool isEndOfWord = false; 32 | }; 33 | 34 | class Trie { 35 | private: 36 | TrieNode *root = nullptr; 37 | 38 | public: 39 | Trie() { 40 | root = new TrieNode(); 41 | } 42 | 43 | void insert(const string& s) { 44 | TrieNode *cur = root; 45 | 46 | for (const char& ch: s) { 47 | if (not cur->children.count(ch)) { 48 | cur->children[ch] = new TrieNode(); 49 | } 50 | 51 | cur = cur->children[ch]; 52 | } 53 | 54 | cur->isEndOfWord = true; 55 | } 56 | 57 | bool hasPrefix(const string& text, const int startPosition) { 58 | TrieNode *cur = root; 59 | 60 | for (int i = startPosition; i < text.size(); i++) { 61 | const char ch = text[i]; 62 | 63 | if (cur->children.count(ch)) { 64 | cur = cur->children[ch]; 65 | } else { 66 | break; 67 | } 68 | 69 | if (cur->isEndOfWord) { 70 | return true; 71 | } 72 | } 73 | 74 | return false; 75 | } 76 | }; 77 | 78 | int main() { 79 | ios_base::sync_with_stdio(0); 80 | cin.tie(0); 81 | cout.tie(0); 82 | // freopen("input.txt", "r", stdin); 83 | // freopen("output.txt", "w", stdout); 84 | 85 | string text, pattern; 86 | cin >> text; 87 | 88 | ll n; 89 | Trie *trie = new Trie(); 90 | cin >> n; 91 | 92 | for (ll i = 0; i < n; i++) { 93 | cin >> pattern; 94 | trie->insert(pattern); 95 | } 96 | 97 | vi ans; 98 | 99 | for (int i = 0; i < text.size(); i++) { 100 | if (trie->hasPrefix(text, i)) { 101 | ans.push_back(i); 102 | } 103 | } 104 | 105 | copy(begin(ans), end(ans), ostream_iterator(cout, " ")); 106 | cout << endl; 107 | 108 | return 0; 109 | } -------------------------------------------------------------------------------- /algorithms-on-strings/week-2/bwmatching.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | pair, unordered_map> process(const string& text) { 30 | unordered_map freq = {{'$', 0}, {'A', 0}, {'C', 0}, {'G', 0}, {'T', 0}}, firstOccur = {{'$', 0}}; 31 | unordered_map count; 32 | vector ele = {'$', 'A', 'C', 'G', 'T'}; 33 | 34 | for (const char& ch: text) { 35 | freq[ch]++; 36 | } 37 | 38 | for (int i = 1; i < 5; i++) { 39 | firstOccur[ele[i]] = firstOccur[ele[i - 1]] + freq[ele[i - 1]]; 40 | } 41 | 42 | for (char e: ele) { 43 | count[e].assign(text.size() + 1, 0); 44 | } 45 | 46 | for (int i = 0; i < text.size(); i++) { 47 | unordered_map temp = {{text[i], 1}}; 48 | 49 | for (char e: ele) { 50 | count[e][i + 1] = count[e][i] + (temp.find(e) == temp.end() ? 0 : temp[e]); 51 | } 52 | } 53 | 54 | return {firstOccur, count}; 55 | } 56 | 57 | int BWmatching(const string& text, string pattern, unordered_map& firstOccur, unordered_map& count) { 58 | int top = 0, bottom = text.size() - 1; 59 | 60 | while (top <= bottom) { 61 | if (not pattern.empty()) { 62 | char symb = pattern.back(); 63 | pattern = pattern.substr(0, pattern.size() - 1); 64 | top = firstOccur[symb] + count[symb][top]; 65 | bottom = firstOccur[symb] + count[symb][bottom + 1] - 1; 66 | } else { 67 | return bottom - top + 1; 68 | } 69 | } 70 | 71 | return 0; 72 | } 73 | 74 | int main() { 75 | ios_base::sync_with_stdio(0); 76 | cin.tie(0); 77 | cout.tie(0); 78 | // freopen("input.txt", "r", stdin); 79 | // freopen("output.txt", "w", stdout); 80 | 81 | string text, pattern; 82 | int n; 83 | cin >> text; 84 | cin >> n; 85 | 86 | pair, unordered_map> pres = process(text); 87 | 88 | for (int i = 0; i < n; i++) { 89 | cin >> pattern; 90 | 91 | cout << BWmatching(text, pattern, pres.first, pres.second) << " "; 92 | } 93 | 94 | cout << endl; 95 | 96 | return 0; 97 | } -------------------------------------------------------------------------------- /algorithms-on-strings/week-2/bwt.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | string BWT(const string& text) { 30 | vector m = {text}; 31 | 32 | for (int i = 1; i < text.size(); i++) { 33 | m.push_back(text.substr(i) + text.substr(0, i)); 34 | } 35 | 36 | sort(begin(m), end(m)); 37 | 38 | return accumulate(begin(m), end(m), string(), [](string bwt, string mRow) { 39 | return bwt + "" + mRow.back(); 40 | }); 41 | } 42 | 43 | int main() { 44 | ios_base::sync_with_stdio(0); 45 | cin.tie(0); 46 | cout.tie(0); 47 | // freopen("input.txt", "r", stdin); 48 | // freopen("output.txt", "w", stdout); 49 | 50 | string text; 51 | cin >> text; 52 | 53 | cout << BWT(text) << endl; 54 | 55 | return 0; 56 | } -------------------------------------------------------------------------------- /algorithms-on-strings/week-2/bwtinverse.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | vi lastToFirst(const string& text) { 30 | unordered_map counts = {{'$', 0}, {'A', 0}, {'C', 0}, {'G', 0}, {'T', 0}}, position; 31 | vi ans(text.size()); 32 | int temp = -1; 33 | 34 | for (const char& ch: text) { 35 | counts[ch]++; 36 | } 37 | 38 | for (char t: "$ACGT") { 39 | temp += counts[t]; 40 | position[t] = temp; 41 | } 42 | 43 | for (int i = text.size() - 1; i >= 0; i--) { 44 | ans[i] = position[text[i]]; 45 | position[text[i]]--; 46 | } 47 | 48 | return ans; 49 | } 50 | 51 | string invertBWT(const string& text) { 52 | string ans = "$"; 53 | int pos = 0; 54 | vi ltf = lastToFirst(text); 55 | 56 | for (int i = 0; i < text.size() - 1; i++) { 57 | ans += text[pos]; 58 | pos = ltf[pos]; 59 | } 60 | 61 | reverse(begin(ans), end(ans)); 62 | 63 | return ans; 64 | } 65 | 66 | int main() { 67 | ios_base::sync_with_stdio(0); 68 | cin.tie(0); 69 | cout.tie(0); 70 | // freopen("input.txt", "r", stdin); 71 | // freopen("output.txt", "w", stdout); 72 | 73 | string text; 74 | cin >> text; 75 | 76 | cout << invertBWT(text) << endl; 77 | 78 | return 0; 79 | } -------------------------------------------------------------------------------- /algorithms-on-strings/week-2/suffix_array.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | int main() { 30 | ios_base::sync_with_stdio(0); 31 | cin.tie(0); 32 | cout.tie(0); 33 | // freopen("input.txt", "r", stdin); 34 | // freopen("output.txt", "w", stdout); 35 | 36 | string text; 37 | cin >> text; 38 | 39 | vector> sa; 40 | 41 | for (int i = 0; i < text.size(); i++) { 42 | sa.push_back({text.substr(i), i}); 43 | } 44 | 45 | sort(begin(sa), end(sa)); 46 | 47 | for (auto suf: sa) { 48 | cout << suf.second << " "; 49 | } 50 | 51 | cout << endl; 52 | 53 | return 0; 54 | } -------------------------------------------------------------------------------- /algorithms-on-strings/week-4/kmp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | vi prefixFunction(const string& text) { 30 | vi s(text.size()); 31 | int border = 0; 32 | 33 | for (int i = 1; i < text.size(); i++) { 34 | while (border > 0 and text[i] != text[border]) { 35 | border = s[border - 1]; 36 | } 37 | 38 | if (text[i] == text[border]) { 39 | border++; 40 | } else { 41 | border = 0; 42 | } 43 | 44 | s[i] = border; 45 | } 46 | 47 | return s; 48 | } 49 | 50 | vi KMP(const string& text, const string pattern) { 51 | string s = pattern + "$" + text; 52 | vi pres = prefixFunction(s), res; 53 | 54 | for (int i = pattern.size() + 1; i < s.size(); i++) { 55 | if (pres[i] == pattern.size()) { 56 | res.push_back(i - 2 * pattern.size()); 57 | } 58 | } 59 | 60 | return res; 61 | } 62 | 63 | int main() { 64 | ios_base::sync_with_stdio(0); 65 | cin.tie(0); 66 | cout.tie(0); 67 | // freopen("input.txt", "r", stdin); 68 | // freopen("output.txt", "w", stdout); 69 | 70 | string pattern, text; 71 | cin >> pattern >> text; 72 | 73 | vi positions = KMP(text, pattern); 74 | 75 | copy(begin(positions), end(positions), ostream_iterator(cout, " ")); 76 | cout << endl; 77 | 78 | return 0; 79 | } -------------------------------------------------------------------------------- /algorithms-on-strings/week-4/suffix_array_long.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | vi sortChars(string s) { 30 | vi order(s.size()); 31 | unordered_map count = {{'$', 0}, {'A', 0}, {'C', 0}, {'G', 0}, {'T', 0}}; 32 | vector ele = {'$', 'A', 'C', 'G', 'T'}; 33 | 34 | for (const char& ch: s) { 35 | count[ch]++; 36 | } 37 | 38 | for (int i = 1; i < 5; i++) { 39 | count[ele[i]] += count[ele[i - 1]]; 40 | } 41 | 42 | for (int j = s.size() - 1; j >= 0; j--) { 43 | char ch = s[j]; 44 | count[ch]--; 45 | order[count[ch]] = j; 46 | } 47 | 48 | return order; 49 | } 50 | 51 | vi computeCharClasses(string s, vi order) { 52 | vi charClass(s.size()); 53 | 54 | for (int i = 1; i < s.size(); i++) { 55 | if (s[order[i]] == s[order[i - 1]]) { 56 | charClass[order[i]] = charClass[order[i - 1]]; 57 | } else { 58 | charClass[order[i]] = charClass[order[i - 1]] + 1; 59 | } 60 | } 61 | 62 | return charClass; 63 | } 64 | 65 | vi sortDoubled(string s, int L, vi oldOrder, vi oldClass) { 66 | vi count(s.size()), newOrder(s.size()); 67 | 68 | for (int i = 0; i < s.size(); i++) { 69 | count[oldClass[i]]++; 70 | } 71 | 72 | for (int i = 1; i < s.size(); i++) { 73 | count[i] += count[i - 1]; 74 | } 75 | 76 | for (int j = s.size() - 1; j >= 0; j--) { 77 | int start = (oldOrder[j] - L + s.size()) % s.size(); 78 | int cl = oldClass[start]; 79 | count[cl]--; 80 | newOrder[count[cl]] = start; 81 | } 82 | 83 | return newOrder; 84 | } 85 | 86 | vi updateClasses(vi newOrder, vi oldClass, int L) { 87 | int n = newOrder.size(); 88 | vi newClass(n); 89 | 90 | for (int i = 1; i < n; i++) { 91 | int cur = newOrder[i]; 92 | int mid = (cur + L) % n; 93 | int prev = newOrder[i - 1]; 94 | int midPrev = (prev + L) % n; 95 | 96 | if (oldClass[cur] == oldClass[prev] and oldClass[mid] == oldClass[midPrev]) { 97 | newClass[cur] = newClass[prev]; 98 | } else { 99 | newClass[cur] = newClass[prev] + 1; 100 | } 101 | } 102 | 103 | return newClass; 104 | } 105 | 106 | vi buildSuffixArray(string s) { 107 | vi order = sortChars(s); 108 | vi klass = computeCharClasses(s, order); 109 | int L = 1; 110 | 111 | while (L < s.size()) { 112 | order = sortDoubled(s, L, order, klass); 113 | klass = updateClasses(order, klass, L); 114 | L = 2 * L; 115 | } 116 | 117 | return order; 118 | } 119 | 120 | int main() { 121 | ios_base::sync_with_stdio(0); 122 | cin.tie(0); 123 | cout.tie(0); 124 | // freopen("input.txt", "r", stdin); 125 | // freopen("output.txt", "w", stdout); 126 | 127 | string text; 128 | cin >> text; 129 | 130 | vi suffixArray = buildSuffixArray(text); 131 | 132 | copy(begin(suffixArray), end(suffixArray), ostream_iterator(cout, " ")); 133 | cout << endl; 134 | 135 | return 0; 136 | } -------------------------------------------------------------------------------- /algorithms-on-strings/week-4/suffix_array_matching.py: -------------------------------------------------------------------------------- 1 | # python3 2 | 3 | 4 | def sort_characters(s): 5 | order = [0] * len(s) 6 | count = {'$': 0, "A": 0, 'C': 0, 'G': 0, 'T': 0} 7 | 8 | for char in s: 9 | count[char] += 1 10 | 11 | ele = ['$', 'A', 'C', 'G', 'T'] 12 | 13 | for i in range(1, 5): 14 | count[ele[i]] += count[ele[i-1]] 15 | 16 | for j in range(len(s) - 1, -1, -1): 17 | c = s[j] 18 | count[c] -= 1 19 | order[count[c]] = j 20 | 21 | return order 22 | 23 | 24 | def compute_char_classes(s, order): 25 | char_class = [0] * len(s) 26 | 27 | for i in range(1, len(s)): 28 | if s[order[i]] == s[order[i-1]]: 29 | char_class[order[i]] = char_class[order[i-1]] 30 | else: 31 | char_class[order[i]] = char_class[order[i-1]] + 1 32 | 33 | return char_class 34 | 35 | 36 | def sort_doubled(s, L, old_order, old_class): 37 | count = [0] * len(s) 38 | new_order = [0] * len(s) 39 | 40 | for i in range(len(s)): 41 | count[old_class[i]] += 1 42 | 43 | for i in range(1, len(s)): 44 | count[i] += count[i-1] 45 | 46 | for j in range(len(s) - 1, -1, -1): 47 | start = (old_order[j] - L + len(s)) % len(s) 48 | cl = old_class[start] 49 | count[cl] -= 1 50 | new_order[count[cl]] = start 51 | 52 | return new_order 53 | 54 | 55 | def update_classes(new_order, old_class, L): 56 | n = len(new_order) 57 | new_class = [0] * n 58 | 59 | for i in range(1, n): 60 | cur = new_order[i] 61 | mid = (cur + L) % n 62 | prev = new_order[i-1] 63 | mid_prev = (prev + L) % n 64 | 65 | if old_class[cur] == old_class[prev] and old_class[mid] == old_class[mid_prev]: 66 | new_class[cur] = new_class[prev] 67 | else: 68 | new_class[cur] = new_class[prev] + 1 69 | 70 | return new_class 71 | 72 | 73 | def build_suffix_array(s): 74 | order = sort_characters(s) 75 | _class = compute_char_classes(s, order) 76 | L = 1 77 | 78 | while L < len(s): 79 | order = sort_doubled(s, L, order, _class) 80 | _class = update_classes(order, _class, L) 81 | L = 2 * L 82 | 83 | return order[1:] 84 | 85 | 86 | def pattern_matching_with_suffix_array(t, p, sa): 87 | min = 0 88 | max = len(t) 89 | 90 | while min < max: 91 | mid = (min + max) // 2 92 | suffix = sa[mid] 93 | i = 0 94 | 95 | while i < len(p) and suffix + i < len(t): 96 | if p[i] > t[suffix + i]: 97 | min = mid + 1 98 | break 99 | elif p[i] < t[suffix + i]: 100 | max = mid 101 | break 102 | 103 | i += 1 104 | 105 | if i == len(p): 106 | max = mid 107 | elif suffix + i == len(t): 108 | min = mid + 1 109 | 110 | start = min 111 | max = len(t) 112 | 113 | while min < max: 114 | mid = (min + max) // 2 115 | suffix = sa[mid] 116 | i = 0 117 | 118 | while i < len(p) and suffix + i < len(t): 119 | if p[i] < t[suffix + i]: 120 | max = mid 121 | break 122 | 123 | i += 1 124 | 125 | if i == len(p) and i <= len(t) - suffix: 126 | min = mid + 1 127 | 128 | end = max - 1 129 | 130 | return start, end 131 | 132 | 133 | if __name__ == '__main__': 134 | text = input() 135 | n_patterns = int(input()) 136 | patterns = list(input().split()) 137 | suffix_array = build_suffix_array(text+'$') 138 | result = [0] * len(text) 139 | 140 | for pattern in patterns: 141 | s, e = pattern_matching_with_suffix_array(text, pattern, suffix_array) 142 | 143 | if s <= e: 144 | for i in range(s, e + 1): 145 | pos = suffix_array[i] 146 | 147 | if result[pos] == 0: 148 | print(pos, end=' ') 149 | 150 | result[pos] += 1 151 | -------------------------------------------------------------------------------- /algorithms-on-strings/week-4/suffix_tree_from_array.py: -------------------------------------------------------------------------------- 1 | # python3 2 | 3 | import sys 4 | import threading 5 | 6 | sys.setrecursionlimit(10 ** 7) 7 | threading.stack_size(2 ** 27) 8 | 9 | 10 | class SuffixTree: 11 | class Node: 12 | def __init__(self, node, depth, start, end): 13 | self.parent = node 14 | self.children = {} 15 | self.depth = depth 16 | self.start = start 17 | self.end = end 18 | self.visited = False 19 | 20 | def __init__(self, s, order, LCP): 21 | self.s = s 22 | self.ele = ['$', 'A', 'C', 'G', 'T'] 23 | self.order = order 24 | self.LCP = LCP 25 | self.root = self.Node(None, 0, -1, -1) 26 | 27 | def create_new_leaf(self, node, suffix): 28 | leaf = self.Node(node, len(self.s) - suffix, suffix + node.depth, len(self.s)) 29 | 30 | node.children[self.s[leaf.start]] = leaf 31 | 32 | return leaf 33 | 34 | def break_edge(self, node, mid_start, offset): 35 | mid_char = self.s[mid_start] 36 | left_char = self.s[mid_start + offset] 37 | mid = self.Node(node, node.depth + offset, mid_start, mid_start + offset) 38 | 39 | mid.children[left_char] = node.children[mid_char] 40 | node.children[mid_char].parent = mid 41 | node.children[mid_char].start += offset 42 | node.children[mid_char] = mid 43 | 44 | return mid 45 | 46 | def st_from_sa(self): 47 | lcp_prev = 0 48 | cur = self.root 49 | 50 | for i in range(len(self.s)): 51 | suffix = self.order[i] 52 | 53 | while cur.depth > lcp_prev: 54 | cur = cur.parent 55 | 56 | if cur.depth == lcp_prev: 57 | cur = self.create_new_leaf(cur, suffix) 58 | else: 59 | mid_start = self.order[i - 1] + cur.depth 60 | offset = lcp_prev - cur.depth 61 | mid = self.break_edge(cur, mid_start, offset) 62 | cur = self.create_new_leaf(mid, suffix) 63 | 64 | if i < len(self.s) - 1: 65 | lcp_prev = self.LCP[i] 66 | 67 | def print_edges(self, cur): 68 | cur.visited = True 69 | 70 | if cur != self.root: 71 | print(cur.start, cur.end) 72 | 73 | for i in range(5): 74 | child = cur.children.get(self.ele[i], None) 75 | 76 | if child is not None and not child.visited: 77 | self.print_edges(child) 78 | 79 | 80 | def main(): 81 | text = input() 82 | suffix_array = list(map(int, input().split())) 83 | lcp = list(map(int, input().split())) 84 | 85 | print(text) 86 | 87 | suffix_tree = SuffixTree(text, suffix_array, lcp) 88 | suffix_tree.st_from_sa() 89 | suffix_tree.print_edges(suffix_tree.root) 90 | 91 | 92 | threading.Thread(target=main).start() 93 | -------------------------------------------------------------------------------- /assembling-genomes/Coursera 5QGPB9XKACS7.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virtyaluk/coursera-data-structures-algorithms/9743587e0520ead50d1838fa228877be0282cff1/assembling-genomes/Coursera 5QGPB9XKACS7.pdf -------------------------------------------------------------------------------- /assembling-genomes/week-1/phiX174_error_free_overlap.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | int calculateOverlap(const string& a, const string& b, const int& mer) { 30 | for (int i = 0, n = 1 + a.size() - mer; i < n; i++) { 31 | if (strncmp(b.c_str(), a.c_str() + i, a.size() - i) == 0) { 32 | return a.size() - i; 33 | } 34 | } 35 | 36 | return 0; 37 | } 38 | 39 | string assembleGenome(vector reads, const int mer) { 40 | string genome; 41 | genome.reserve(1000); 42 | genome += reads.front(); 43 | string firstRead = reads.front(), curRead = ""; 44 | int curIdx = 0; 45 | 46 | while (reads.size() > 1) { 47 | curRead = move(reads[curIdx]); 48 | reads.erase(reads.begin() + curIdx); 49 | 50 | int maxOverlap = -1; 51 | 52 | for (int j = 0; j < reads.size(); j++) { 53 | int overlap = calculateOverlap(curRead, reads[j], mer); 54 | 55 | if (overlap > maxOverlap) { 56 | maxOverlap = overlap; 57 | curIdx = j; 58 | } 59 | } 60 | 61 | genome += reads[curIdx].substr(maxOverlap); 62 | } 63 | 64 | genome.erase(0, calculateOverlap(reads[0], firstRead, mer)); 65 | 66 | return genome; 67 | } 68 | 69 | int main() { 70 | ios_base::sync_with_stdio(0); 71 | cin.tie(0); 72 | cout.tie(0); 73 | // freopen("input.txt", "r", stdin); 74 | // freopen("output.txt", "w", stdout); 75 | 76 | string s; 77 | vector reads; 78 | reads.reserve(1618); 79 | 80 | while (cin >> s) { 81 | if (reads.back() != s) { 82 | reads.emplace_back(move(s)); 83 | } 84 | } 85 | 86 | cout << assembleGenome(move(reads), 12) << endl; 87 | 88 | return 0; 89 | } 90 | -------------------------------------------------------------------------------- /assembling-genomes/week-1/phiX174_error_prone_overlap.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | constexpr int MAX_ERRORS = 2; 30 | 31 | int calculate_overlap(const string & a, const string & b, const int mer) noexcept { 32 | for (int i = 0, n = 1 + a.size() - mer; i < n; ++i) { 33 | int errors = 0; 34 | 35 | for (int j = 0, s = a.size() - i; j < s && errors <= MAX_ERRORS; ++j) { 36 | if (a[i + j] != b[j]) { 37 | errors++; 38 | } 39 | } 40 | 41 | if (errors <= MAX_ERRORS) { 42 | return a.size() - i; 43 | } 44 | } 45 | 46 | return 0; 47 | } 48 | 49 | char get_most_frq(const vector chars) { 50 | map counts; 51 | 52 | for (auto c: chars) { 53 | counts[c]++; 54 | } 55 | 56 | pair most_frq = *counts.begin(); 57 | 58 | for (auto each: counts) { 59 | if (each.second > most_frq.second) { 60 | most_frq = each; 61 | } 62 | } 63 | 64 | return most_frq.first; 65 | } 66 | 67 | string assemble_genome(vector reads, const int mer) noexcept { 68 | string genome; 69 | genome.reserve(1000); 70 | genome += reads.front(); 71 | 72 | string first_read = reads.front(), cur_read = ""; 73 | int cur_index = 0; 74 | 75 | while (reads.size() > 1) { 76 | cur_read = move(reads[cur_index]); 77 | reads.erase(reads.begin() + cur_index); 78 | 79 | int max_overlap = -1; 80 | 81 | vector overlaps; 82 | vector positions; 83 | 84 | for (int j = 0; j < reads.size(); ++j) { 85 | int overlap = calculate_overlap(cur_read, reads[j], mer); 86 | 87 | if (overlaps.empty() || overlap >= overlaps.back()) { 88 | overlaps.push_back(overlap); 89 | positions.push_back(j); 90 | cur_index = j; 91 | } 92 | } 93 | 94 | if (overlaps.size() > 3) { 95 | char *suffix = &genome[genome.size() - overlaps[overlaps.size() - 4]]; 96 | char *prefix1 = &reads[positions[positions.size() - 4]][0]; 97 | char *prefix2 = &reads[positions[positions.size() - 3]][ 98 | (overlaps[overlaps.size() - 3] - overlaps[overlaps.size() - 4])]; 99 | char *prefix3 = &reads[positions[positions.size() - 2]][ 100 | (overlaps[overlaps.size() - 2] - overlaps[overlaps.size() - 4])]; 101 | char *prefix4 = &reads[positions[positions.size() - 1]][ 102 | (overlaps[overlaps.size() - 1] - overlaps[overlaps.size() - 4])]; 103 | 104 | for (int i = 0, n = overlaps[overlaps.size() - 4]; i < n; ++i, 105 | ++suffix, ++prefix1, ++prefix2, ++prefix3, ++prefix4) { 106 | if (*suffix == *prefix1 && *prefix1 == *prefix2 && 107 | *prefix2 == *prefix3 && *prefix3 == *prefix4) { 108 | continue; 109 | } 110 | 111 | const char c = get_most_frq({*suffix, *prefix1, *prefix2, *prefix3, *prefix4}); 112 | *suffix = *prefix1 = *prefix2 = *prefix3 = *prefix4 = c; 113 | } 114 | } 115 | 116 | genome += reads[cur_index].substr(overlaps.back()); 117 | } 118 | 119 | genome.erase(0, calculate_overlap(reads[0], first_read, mer)); 120 | return genome; 121 | } 122 | 123 | int main () { 124 | ios::sync_with_stdio(false); 125 | cin.tie(NULL); 126 | 127 | vector reads; 128 | reads.reserve(1618); 129 | string s; 130 | 131 | while (cin >> s) { 132 | reads.emplace_back(move(s)); 133 | } 134 | 135 | random_device rd; 136 | mt19937 g(rd()); 137 | 138 | shuffle(reads.begin(), reads.end(), g); 139 | 140 | cout << assemble_genome(move(reads), 12) << endl; 141 | 142 | return 0; 143 | } 144 | -------------------------------------------------------------------------------- /assembling-genomes/week-2/eulerian_cycle.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | bool checkDegrees(const vll& in, const vll& out) { 30 | for (ll i = 0; i < in.size(); i++) { 31 | if (in[i] != out[i]) { 32 | return false; 33 | } 34 | } 35 | 36 | return true; 37 | } 38 | 39 | vll makeEulerCycle(vvll& g) { 40 | stack v; 41 | vll path; 42 | ll cur = 0; 43 | v.push(0); 44 | 45 | while (not v.empty()) { 46 | cur = v.top(); 47 | 48 | if (not g[cur].empty()) { 49 | v.push(g[cur].back()); 50 | g[cur].pop_back(); 51 | continue; 52 | } 53 | 54 | path.push_back(cur); 55 | v.pop(); 56 | } 57 | 58 | reverse(begin(path), end(path)); 59 | path.pop_back(); 60 | 61 | return path; 62 | } 63 | 64 | int main() { 65 | ios_base::sync_with_stdio(0); 66 | cin.tie(0); 67 | cout.tie(0); 68 | // freopen("input.txt", "r", stdin); 69 | // freopen("output.txt", "w", stdout); 70 | 71 | ll n, m, u, v; 72 | cin >> n >> m; 73 | 74 | vvll g(n); 75 | vll in(n), out(n); 76 | 77 | for (ll i = 0; i < m; i++) { 78 | cin >> u >> v; 79 | g[--u].push_back(--v); 80 | in[v]++; 81 | out[u]++; 82 | } 83 | 84 | if (not checkDegrees(in, out)) { 85 | cout << 0 << endl; 86 | return 0; 87 | } 88 | 89 | const vll cycle = makeEulerCycle(g); 90 | 91 | cout << 1 << endl; 92 | 93 | for (const ll& vc: cycle) { 94 | cout << vc + 1 << " "; 95 | } 96 | 97 | cout << endl; 98 | 99 | return 0; 100 | } 101 | -------------------------------------------------------------------------------- /assembling-genomes/week-2/phiX174_kmer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | vector makeEulerCycle(map> graph) { 30 | stack verteces; 31 | vector path; 32 | path.reserve(graph.size()); 33 | verteces.push(graph.begin()->first); 34 | string current = verteces.top(); 35 | 36 | while (not verteces.empty()) { 37 | current = verteces.top(); 38 | 39 | if (not graph[current].empty()) { 40 | verteces.push(move(graph[current].back())); 41 | graph[current].pop_back(); 42 | continue; 43 | } 44 | 45 | path.emplace_back(move(current)); 46 | verteces.pop(); 47 | } 48 | 49 | reverse(path.begin(), path.end()); 50 | return path; 51 | } 52 | 53 | int main() { 54 | ios_base::sync_with_stdio(0); 55 | cin.tie(0); 56 | cout.tie(0); 57 | // freopen("input.txt", "r", stdin); 58 | // freopen("output.txt", "w", stdout); 59 | 60 | string s; 61 | map> graph; 62 | 63 | while (cin >> s) { 64 | graph[s.substr(0, s.size() - 1)].emplace_back(s.substr(1)); 65 | } 66 | 67 | const vector cycle = makeEulerCycle(graph); 68 | 69 | cout << cycle.front(); 70 | 71 | for (int i = 1; i < cycle.size() - 9; i++) { 72 | cout << cycle[i].back(); 73 | } 74 | 75 | cout << endl; 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /assembling-genomes/week-2/universal_string.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | vector makeEulerCycle(map> graph) { 30 | stack verteces; 31 | vector path; 32 | verteces.push(graph.begin()->first); 33 | string current = verteces.top(); 34 | 35 | while (not verteces.empty()) { 36 | current = verteces.top(); 37 | 38 | if (not graph[current].empty()) { 39 | verteces.push(*graph[current].begin()); 40 | graph[current].erase(graph[current].begin()); 41 | continue; 42 | } 43 | 44 | path.push_back(current); 45 | verteces.pop(); 46 | } 47 | 48 | reverse(path.begin(), path.end()); 49 | return path; 50 | } 51 | 52 | map> makeDeBruijnGraph(const int k, const int n) { 53 | map> graph; 54 | 55 | for (size_t i = 0; i < n; i++) { 56 | auto s1 = bitset < 16 > {i}.to_string().substr(16 - k, k - 1), 57 | s2 = bitset < 16 > {i * 2 % n}.to_string().substr(16 - k), 58 | s3 = bitset < 16 > {i * 2 % n + 1}.to_string().substr(16 - k); 59 | 60 | graph[s1].emplace(s2.substr(0, k - 1)); 61 | graph[s1].emplace(s3.substr(0, k - 1)); 62 | } 63 | 64 | return graph; 65 | } 66 | 67 | int main() { 68 | ios_base::sync_with_stdio(0); 69 | cin.tie(0); 70 | cout.tie(0); 71 | // freopen("input.txt", "r", stdin); 72 | // freopen("output.txt", "w", stdout); 73 | 74 | int k, n; 75 | cin >> k; 76 | n = pow(2, k); 77 | 78 | const vector cycle = makeEulerCycle(makeDeBruijnGraph(k, n)); 79 | 80 | for (int i = 0; i < cycle.size() - 1; i++) { 81 | const auto &s = cycle[i]; 82 | cout << s.substr(0, s.size() - (k - 2)); 83 | } 84 | 85 | cout << endl; 86 | 87 | return 0; 88 | } 89 | -------------------------------------------------------------------------------- /assembling-genomes/week-3/bubble_detection.py: -------------------------------------------------------------------------------- 1 | # python3 2 | 3 | import sys 4 | import itertools 5 | 6 | class BubbleDetection: 7 | 8 | # Bubble (in a de Bruijn graph) is defined as a pair of short 9 | # non-overlapping disjoint paths between some vertces V and W. 10 | 11 | def __init__(self, k, t, reads): 12 | self.k = k 13 | self.threshold = t 14 | self.graph = {} 15 | self.paths = {} 16 | self.bubbles = 0 17 | 18 | self.multiple_incoming = lambda vertex: self.graph[vertex][1] > 1 19 | self.multiple_outgoing = lambda vertex: len(self.graph[vertex][0]) > 1 20 | 21 | self.build_deBruijn_graph(self.break_reads_into_kmers(reads)) 22 | 23 | def break_reads_into_kmers(self, reads): 24 | break_read = lambda read: [ read[j:j + self.k] for j in range(len(read) - self.k + 1) ] 25 | return [ kmer for read in reads for kmer in break_read(read) ] 26 | 27 | def build_deBruijn_graph(self, kmers): 28 | 29 | def add_edge(graph, left, right): 30 | graph.setdefault(left, [set(), 0]) 31 | graph.setdefault(right, [set(), 0]) 32 | 33 | if right not in graph[left][0]: 34 | graph[left][0].add(right) 35 | graph[right][1] += 1 36 | 37 | for kmer in kmers: 38 | left, right = kmer[:-1], kmer[1:] 39 | if left != right: 40 | add_edge(self.graph, left, right) 41 | 42 | def count_bubbles(self): 43 | for k, v in self.graph.items(): 44 | if self.multiple_outgoing(k): 45 | self.dfs(path=[k], start=k, current=k, depth=0) 46 | 47 | for _, candidates_list in self.paths.items(): 48 | for pair in itertools.combinations(candidates_list, r=2): 49 | if self.paths_disjoint(pair): 50 | self.bubbles += 1 51 | 52 | return self.bubbles 53 | 54 | def paths_disjoint(self, pair): 55 | return len(set(pair[0]) & set(pair[1])) == 2 # only V and W are shared 56 | 57 | def dfs(self, path, start, current, depth): 58 | if current != start and self.multiple_incoming(current): 59 | self.paths.setdefault((start, current), list()).append(path[:]) 60 | 61 | if depth == self.threshold: 62 | return 63 | 64 | for next_ in self.graph[current][0]: 65 | if next_ not in path: 66 | path.append(next_) 67 | self.dfs(path, start, next_, depth + 1) 68 | path.remove(next_) 69 | 70 | 71 | if __name__ == "__main__": 72 | data = sys.stdin.read().split() 73 | k, t, reads = data[0], data[1], data[2:] 74 | print(BubbleDetection(int(k), int(t), reads).count_bubbles()) 75 | -------------------------------------------------------------------------------- /assembling-genomes/week-3/optimal_kmer_size.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | enum class result { 30 | no_cycle, 31 | one_cycle, 32 | multiple_cycles 33 | }; 34 | 35 | result check_Euler_cycle(const map> graph) { 36 | for (auto &kv : graph) { 37 | if (kv.second.empty()) return result::no_cycle; 38 | if (kv.second.size() > 1) return result::multiple_cycles; 39 | } 40 | 41 | return result::one_cycle; 42 | } 43 | 44 | map> construct_DeBruijn_graph(const vector& reads, const int k) { 45 | map > graph; 46 | 47 | for (const auto &read : reads) { 48 | for (size_t i = 0; i + k < read.size(); ++i) { 49 | graph[read.substr(i, k - 1)].emplace(read.substr(i + 2, k - 1)); 50 | if (i + k + 1 < read.size()) graph[read.substr(i + 2, k - 1)]; 51 | } 52 | } 53 | 54 | return graph; 55 | } 56 | 57 | int binary_search_k(const vector reads, int l, int r) { 58 | while (r >= l) { 59 | int mid = l + (r - l) / 2; 60 | 61 | result res = check_Euler_cycle(construct_DeBruijn_graph(reads, mid)); 62 | switch (res) { 63 | case result::one_cycle: 64 | return mid; 65 | case result::no_cycle: 66 | r = mid - 1; 67 | continue; 68 | case result::multiple_cycles: 69 | l = mid + 1; 70 | continue; 71 | } 72 | } 73 | 74 | throw logic_error{"optimal k not found"}; 75 | } 76 | 77 | int main() { 78 | ios_base::sync_with_stdio(0); 79 | cin.tie(0); 80 | cout.tie(0); 81 | // freopen("input.txt", "r", stdin); 82 | // freopen("output.txt", "w", stdout); 83 | 84 | vector reads; 85 | string s; 86 | 87 | while (cin >> s) { 88 | reads.emplace_back(move(s)); 89 | } 90 | 91 | const int mer_size = 100; 92 | cout << binary_search_k(reads, 0, mer_size) << endl; 93 | 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /assembling-genomes/week-3/tip_removal.py: -------------------------------------------------------------------------------- 1 | # python3 2 | 3 | import sys 4 | import itertools 5 | 6 | class TipRemoval: 7 | 8 | # Tips are error-prone ends of the reads that do not form a bubble but instead 9 | # form a path starting in a vertex without incoming edges or ending in a vertex 10 | # without outgoing edges in the de Bruijn graph. 11 | 12 | def __init__(self, k, reads): 13 | self.k = k 14 | self.threshold = self.k 15 | self.graph = {} 16 | self.paths = {} 17 | self.edges_removed = 0 18 | 19 | self.build_deBruijn_graph(self.break_reads_into_kmers(reads)) 20 | 21 | def break_reads_into_kmers(self, reads): 22 | break_read = lambda read: [ read[j:j + self.k] for j in range(len(read) - self.k + 1) ] 23 | return [ kmer for read in reads for kmer in break_read(read) ] 24 | 25 | def build_deBruijn_graph(self, kmers): 26 | 27 | def add_edge(graph, left, right): 28 | graph.setdefault(left, [set(), 0]) 29 | graph.setdefault(right, [set(), 0]) 30 | 31 | if right not in graph[left][0]: 32 | graph[left][0].add(right) 33 | graph[right][1] += 1 34 | 35 | for kmer in kmers: 36 | left, right = kmer[:-1], kmer[1:] 37 | if left != right: 38 | add_edge(self.graph, left, right) 39 | 40 | def remove_tips(self): 41 | for k, v in self.graph.items(): 42 | find_and_remove = None 43 | 44 | if len(v[0]) == 1 and v[1] == 0: 45 | find_and_remove = self.find_and_remove_incoming 46 | elif len(v[0]) > 1: 47 | find_and_remove = self.find_and_remove_outgoing 48 | else : continue 49 | 50 | condition = True 51 | while condition: 52 | condition = False 53 | for edge in v[0]: 54 | if find_and_remove(edge, 0): 55 | v[0].remove(edge) 56 | self.edges_removed += 1 57 | condition = True 58 | break 59 | 60 | return self.edges_removed 61 | 62 | def find_and_remove_outgoing(self, current, depth): 63 | if self.outgoing_num(current) > 1 or self.incoming_num(current) > 1: 64 | return False 65 | 66 | if depth == self.threshold: 67 | return False 68 | 69 | if self.outgoing_num(current) == 0: 70 | return True 71 | 72 | if self.find_and_remove_outgoing(next(iter(self.graph[current][0])), depth + 1): 73 | self.graph[current][0].pop() 74 | self.edges_removed += 1 75 | return True 76 | 77 | return False 78 | 79 | def find_and_remove_incoming(self, current, depth): 80 | if depth == self.threshold: 81 | return False 82 | 83 | if self.outgoing_num(current) == 0 or self.incoming_num(current) > 1: 84 | return True 85 | 86 | if self.find_and_remove_incoming(next(iter(self.graph[current][0])), depth + 1): 87 | self.graph[current][0].pop() 88 | self.edges_removed += 1 89 | return True 90 | 91 | return False 92 | 93 | def incoming_num(self, v): 94 | return self.graph[v][1] 95 | 96 | def outgoing_num(self, v): 97 | return len(self.graph[v][0]) 98 | 99 | if __name__ == "__main__": 100 | k, reads = 15, sys.stdin.read().split() 101 | print(TipRemoval(k, reads).remove_tips()) 102 | -------------------------------------------------------------------------------- /data-structures/Coursera BMUSAKGNSU4P.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virtyaluk/coursera-data-structures-algorithms/9743587e0520ead50d1838fa228877be0282cff1/data-structures/Coursera BMUSAKGNSU4P.pdf -------------------------------------------------------------------------------- /data-structures/week-1/brackets_in_code.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | string findMismatch(string s) { 30 | stack> st; 31 | ll ans; 32 | 33 | for (int i = 0; i < s.size(); i++) { 34 | char ch = s[i]; 35 | 36 | if (ch == '(' || ch == '{' || ch == '[') { 37 | st.push({ch, i}); 38 | } else if (ch == ')' || ch == '}' || ch == ']') { 39 | if (st.empty()) { 40 | return to_string(i + 1); 41 | } 42 | 43 | char top = st.top().first; 44 | st.pop(); 45 | 46 | if ((top == '(' && ch != ')') || (top == '{' && ch != '}') || (top == '[' && ch != ']')) { 47 | return to_string(i + 1); 48 | } 49 | } 50 | } 51 | 52 | if (!st.empty()) { 53 | return to_string(st.top().second + 1); 54 | } 55 | 56 | return "Success"; 57 | } 58 | 59 | int main() { 60 | ios_base::sync_with_stdio(0); 61 | cin.tie(0); 62 | cout.tie(0); 63 | // freopen("input.txt", "r", stdin); 64 | // freopen("output.txt", "w", stdout); 65 | 66 | string s; 67 | cin >> s; 68 | 69 | cout << findMismatch(s) << endl; 70 | 71 | return 0; 72 | } -------------------------------------------------------------------------------- /data-structures/week-1/max_sliding_window.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | int main() { 30 | ios_base::sync_with_stdio(0); 31 | cin.tie(0); 32 | cout.tie(0); 33 | // freopen("input.txt", "r", stdin); 34 | // freopen("output.txt", "w", stdout); 35 | 36 | ll n, m; 37 | cin >> n; 38 | 39 | vll a, ans; 40 | copy_n(istream_iterator(cin), n, back_inserter(a)); 41 | cin >> m; 42 | 43 | deque q; 44 | 45 | for (int i = 0; i < n; i++) { 46 | if (!q.empty() && q.front() == i - m) { 47 | q.pop_front(); 48 | } 49 | 50 | while (!q.empty() && a[i] >= a[q.back()]) { 51 | q.pop_back(); 52 | } 53 | 54 | q.push_back(i); 55 | 56 | if (i >= m - 1) { 57 | ans.push_back(a[q.front()]); 58 | } 59 | } 60 | 61 | copy(ans.begin(), ans.end(), ostream_iterator(cout, " ")); 62 | cout << endl; 63 | 64 | return 0; 65 | } -------------------------------------------------------------------------------- /data-structures/week-1/network_simulation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct Request { 6 | Request(int arrival_time, int process_time): 7 | arrival_time(arrival_time), 8 | process_time(process_time) 9 | {} 10 | 11 | int arrival_time; 12 | int process_time; 13 | }; 14 | 15 | struct Response { 16 | Response(bool dropped, int start_time): 17 | dropped(dropped), 18 | start_time(start_time) 19 | {} 20 | 21 | bool dropped; 22 | int start_time; 23 | }; 24 | 25 | class Buffer { 26 | public: 27 | Buffer(int size): 28 | size_(size), 29 | finish_time_() 30 | {} 31 | 32 | Response Process(const Request &request) { 33 | int arrivalTime = request.arrival_time; 34 | 35 | if (maxFinishTime < arrivalTime) { 36 | maxFinishTime = arrivalTime; 37 | } 38 | 39 | while (!finish_time_.empty() && arrivalTime >= finish_time_.front()) { 40 | finish_time_.pop(); 41 | } 42 | 43 | int countPacketsInBuffer = finish_time_.size(); 44 | 45 | if (countPacketsInBuffer < size_) { 46 | int bufferFinishTime = maxFinishTime; 47 | 48 | maxFinishTime += request.process_time; 49 | finish_time_.push(maxFinishTime); 50 | 51 | return Response(false, bufferFinishTime); 52 | } else { 53 | return Response(true, -1); 54 | } 55 | } 56 | private: 57 | int size_, maxFinishTime = 0; 58 | std::queue finish_time_; 59 | }; 60 | 61 | std::vector ReadRequests() { 62 | std::vector requests; 63 | int count; 64 | std::cin >> count; 65 | for (int i = 0; i < count; ++i) { 66 | int arrival_time, process_time; 67 | std::cin >> arrival_time >> process_time; 68 | requests.push_back(Request(arrival_time, process_time)); 69 | } 70 | return requests; 71 | } 72 | 73 | std::vector ProcessRequests(const std::vector &requests, Buffer *buffer) { 74 | std::vector responses; 75 | for (int i = 0; i < requests.size(); ++i) 76 | responses.push_back(buffer->Process(requests[i])); 77 | return responses; 78 | } 79 | 80 | void PrintResponses(const std::vector &responses) { 81 | for (int i = 0; i < responses.size(); ++i) 82 | std::cout << (responses[i].dropped ? -1 : responses[i].start_time) << std::endl; 83 | } 84 | 85 | int main() { 86 | int size; 87 | std::cin >> size; 88 | std::vector requests = ReadRequests(); 89 | 90 | Buffer buffer(size); 91 | std::vector responses = ProcessRequests(requests, &buffer); 92 | 93 | PrintResponses(responses); 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /data-structures/week-1/stack_with_max.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | int main() { 30 | ios_base::sync_with_stdio(0); 31 | cin.tie(0); 32 | cout.tie(0); 33 | // freopen("input.txt", "r", stdin); 34 | // freopen("output.txt", "w", stdout); 35 | 36 | ll n; 37 | cin >> n; 38 | 39 | stack st; 40 | 41 | for (int i = 0; i < n; i++) { 42 | string cmd; 43 | cin >> cmd; 44 | 45 | if (cmd == "push") { 46 | ll v; 47 | cin >> v; 48 | 49 | if (!st.empty() && st.top() > v) { 50 | v = st.top(); 51 | } 52 | 53 | st.push(v); 54 | } else if (cmd == "pop") { 55 | st.pop(); 56 | } else if (cmd == "max") { 57 | cout << st.top() << endl; 58 | } 59 | } 60 | 61 | return 0; 62 | } -------------------------------------------------------------------------------- /data-structures/week-1/tree_height.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | int treeHeight(vll& tree) { 30 | int n = tree.size(), root = -1; 31 | unordered_map> um; 32 | function getTreeHeight; 33 | 34 | getTreeHeight = [&](int node) { 35 | int curHeight = 0; 36 | 37 | for (int next: um[node]) { 38 | curHeight = max(curHeight, getTreeHeight(next)); 39 | } 40 | 41 | return curHeight + 1; 42 | }; 43 | 44 | // [4, -1, 4, 1, 1] 45 | 46 | for (int i = 0; i < n; i++) { 47 | um[tree[i]].insert(i); 48 | // um[i].insert(tree[i]); 49 | 50 | if (tree[i] == -1) { 51 | root = i; 52 | } 53 | } 54 | 55 | return getTreeHeight(root); 56 | } 57 | 58 | int main() { 59 | ios_base::sync_with_stdio(0); 60 | cin.tie(0); 61 | cout.tie(0); 62 | // freopen("input.txt", "r", stdin); 63 | // freopen("output.txt", "w", stdout); 64 | 65 | ll n; 66 | cin >> n; 67 | 68 | vll tree; 69 | copy_n(istream_iterator(cin), n, back_inserter(tree)); 70 | 71 | cout << treeHeight(tree) << endl; 72 | 73 | return 0; 74 | } -------------------------------------------------------------------------------- /data-structures/week-3/make_heap.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | void siftDown(vll& a, vector>& swaps, int i) { 30 | int minIdx = i, left = 2 * i + 1, right = 2 * i + 2; 31 | 32 | if (left < a.size() && a[left] < a[minIdx]) { 33 | minIdx = left; 34 | } 35 | 36 | if (right < a.size() && a[right] < a[minIdx]) { 37 | minIdx = right; 38 | } 39 | 40 | if (minIdx != i) { 41 | swaps.push_back({i, minIdx}); 42 | swap(a[i], a[minIdx]); 43 | siftDown(a, swaps, minIdx); 44 | } 45 | } 46 | 47 | void buildHeap(vll& a, vector>& swaps) { 48 | int n = a.size(); 49 | 50 | for (int i = n / 2; i >= 0; i--) { 51 | siftDown(a, swaps, i); 52 | } 53 | } 54 | 55 | int main() { 56 | ios_base::sync_with_stdio(0); 57 | cin.tie(0); 58 | cout.tie(0); 59 | // freopen("input.txt", "r", stdin); 60 | // freopen("output.txt", "w", stdout); 61 | 62 | ll n; 63 | cin >> n; 64 | 65 | vector> swaps; 66 | vll a; 67 | copy_n(istream_iterator(cin), n, back_inserter(a)); 68 | 69 | buildHeap(a, swaps); 70 | 71 | cout << swaps.size() << endl; 72 | 73 | for (pair& swap: swaps) { 74 | cout << swap.first << " " << swap.second << endl; 75 | } 76 | 77 | return 0; 78 | } -------------------------------------------------------------------------------- /data-structures/week-3/merging_tables.py: -------------------------------------------------------------------------------- 1 | # python3 2 | 3 | 4 | class DataBases: 5 | def __init__(self, row_counts): 6 | self.max_row_count = max(row_counts) 7 | self.row_counts = row_counts 8 | n_tables = len(row_counts) 9 | self.parent = list(range(n_tables)) 10 | self.rank = [0] * n_tables 11 | 12 | def FindParent(self, i): 13 | if i != self.parent[i]: 14 | self.parent[i] = self.FindParent(self.parent[i]) 15 | return self.parent[i] 16 | 17 | def MergeTables(self, dst, src): 18 | src_parent = self.FindParent(src) 19 | dst_parent = self.FindParent(dst) 20 | if src_parent == dst_parent: 21 | return 22 | if self.rank[src_parent] > self.rank[dst_parent]: 23 | self.parent[dst_parent] = src_parent 24 | self.row_counts[src_parent] += self.row_counts[dst_parent] 25 | self.row_counts[dst_parent] = 0 26 | self.max_row_count = max(self.max_row_count, self.row_counts[src_parent]) 27 | else: 28 | self.parent[src_parent] = dst_parent 29 | self.row_counts[dst_parent] += self.row_counts[src_parent] 30 | self.row_counts[src_parent] = 0 31 | self.max_row_count = max(self.max_row_count, self.row_counts[dst_parent]) 32 | if self.rank[src_parent] == self.rank[dst_parent]: 33 | self.rank[dst_parent] += 1 34 | 35 | 36 | def main(): 37 | n_tables, n_queries = map(int, input().split()) 38 | counts = list(map(int, input().split())) 39 | assert(n_tables == len(counts)) 40 | db = DataBases(counts) 41 | for i in range(n_queries): 42 | dst, src = map(int, input().split()) 43 | db.MergeTables(dst - 1, src - 1) 44 | print(db.max_row_count) 45 | 46 | 47 | 48 | if __name__ == "__main__": 49 | main() -------------------------------------------------------------------------------- /data-structures/week-3/parallel_processing.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | class myComparator 30 | { 31 | public: 32 | int operator() (const pair& lhs, const pair& rhs) 33 | { 34 | if (lhs.second == rhs.second) { 35 | return lhs.first > rhs.first; 36 | } 37 | 38 | return lhs.second > rhs.second; 39 | } 40 | }; 41 | 42 | int main() { 43 | ios_base::sync_with_stdio(0); 44 | cin.tie(0); 45 | cout.tie(0); 46 | // freopen("input.txt", "r", stdin); 47 | // freopen("output.txt", "w", stdout); 48 | 49 | ll n, m; 50 | cin >> n >> m; 51 | 52 | vll t; 53 | copy_n(istream_iterator(cin), m, back_inserter(t)); 54 | 55 | priority_queue, vector>, myComparator> q; 56 | 57 | for (int i = 0; i < n; i++) { 58 | q.push({i, 0}); 59 | } 60 | 61 | for (ll& ti: t) { 62 | pair w = q.top(); 63 | q.pop(); 64 | 65 | cout << w.first << " " << w.second << endl; 66 | q.push({w.first, w.second + ti}); 67 | } 68 | 69 | return 0; 70 | } -------------------------------------------------------------------------------- /data-structures/week-4/common_substring.py: -------------------------------------------------------------------------------- 1 | # python3 2 | 3 | 4 | def PolyHash(s, prime, multiplier): 5 | hash_value = 0 6 | for i in range(len(s) - 1, -1, -1): 7 | hash_value = (hash_value * multiplier + ord(s[i])) % prime 8 | return hash_value 9 | 10 | 11 | def HashTable(s, p_len, prime, multiplier): 12 | H = list([] for _ in range(len(s) - p_len + 1)) 13 | substring = s[len(s) - p_len:] 14 | H[len(s) - p_len] = PolyHash(substring, prime, multiplier) 15 | y = pow(multiplier, p_len, prime) 16 | for i in range(len(s) - p_len - 1, - 1, - 1): 17 | H[i] = (multiplier * H[i + 1] + ord(s[i]) - y * ord(s[i + p_len])) % prime 18 | return H 19 | 20 | 21 | def HashDict(s, p_len, prime, multiplier): 22 | D = {} 23 | substring = s[len(s) - p_len:] 24 | last = PolyHash(substring, prime, multiplier) 25 | D[last] = len(s) - p_len 26 | y = pow(multiplier, p_len, prime) 27 | for j in range(len(s) - p_len - 1, - 1, - 1): 28 | current = (multiplier * last + ord(s[j]) - y * ord(s[j + p_len])) % prime 29 | D[current] = j 30 | last = current 31 | return D 32 | 33 | 34 | def SearchSubstring(hash_table, hash_dict): 35 | check = False 36 | matches = {} 37 | for i in range(len(hash_table)): 38 | b_start = hash_dict.get(hash_table[i], -1) 39 | if b_start != -1: 40 | check = True 41 | matches[i] = b_start 42 | return check, matches 43 | 44 | 45 | def MaxLength(string_a, string_b, low, high, max_length, aStart, bStart): 46 | # a is long string --> hash table, b is short string --> hash dict 47 | mid = (low + high) // 2 # mid is the length of the tested common substring 48 | if low > high: 49 | return aStart, bStart, max_length 50 | prime1 = 1000000007 51 | prime2 = 1000004249 52 | x = 263 53 | aHash1 = HashTable(string_a, mid, prime1, x) 54 | aHash2 = HashTable(string_a, mid, prime2, x) 55 | bHash1 = HashDict(string_b, mid, prime1, x) 56 | bHash2 = HashDict(string_b, mid, prime2, x) 57 | check1, matches1 = SearchSubstring(aHash1, bHash1) 58 | check2, matches2 = SearchSubstring(aHash2, bHash2) 59 | if check1 and check2: 60 | for a, b in matches1.items(): 61 | temp = matches2.get(a, -1) 62 | if temp != -1: 63 | max_length = mid 64 | aStart, bStart = a, b 65 | del aHash1, aHash2, bHash1, bHash2, matches1, matches2 66 | return MaxLength(string_a, string_b, mid + 1, high, max_length, aStart, bStart) 67 | return MaxLength(string_a, string_b, low, mid - 1, max_length, aStart, bStart) 68 | 69 | 70 | while True: 71 | line = input() 72 | if line == '': 73 | break 74 | else: 75 | s, t = line.split() 76 | k = min(len(s), len(t)) 77 | if len(s) <= len(t): 78 | short_string, long_string = s, t 79 | else: 80 | short_string, long_string = t, s 81 | l, i, j = MaxLength(long_string, short_string, 0, k, 0, 0, 0) 82 | if len(s) <= len(t): 83 | print(i, l, j) 84 | else: 85 | print(l, i, j) -------------------------------------------------------------------------------- /data-structures/week-4/hash_chain.py: -------------------------------------------------------------------------------- 1 | # python3 2 | 3 | from collections import deque 4 | 5 | 6 | class Query: 7 | def __init__(self, query): 8 | self.type = query[0] 9 | if self.type == "check": 10 | self.index = int(query[1]) 11 | else: 12 | self.word = query[1] 13 | 14 | 15 | class QueryProcessor: 16 | _multiplier = 263 17 | _prime = 1000000007 18 | 19 | def __init__(self, bucket_count): 20 | self.bucket_count = bucket_count 21 | self.hash_table = list(deque() for _ in range(self.bucket_count)) 22 | 23 | def HashFunction(self, word): 24 | hash_value = 0 25 | for char in reversed(word): 26 | hash_value = (hash_value * self._multiplier + ord(char)) % self._prime 27 | return hash_value % self.bucket_count 28 | 29 | def ProcessQuery(self, query): 30 | if query.type == 'check': 31 | if self.hash_table[query.index]: 32 | print(' '.join(self.hash_table[query.index])) 33 | else: 34 | print() 35 | else: 36 | hash_value = self.HashFunction(query.word) 37 | if query.type == "add": 38 | if query.word not in self.hash_table[hash_value]: 39 | self.hash_table[hash_value].appendleft(query.word) 40 | elif query.type == "del": 41 | if query.word in self.hash_table[hash_value]: 42 | self.hash_table[hash_value].remove(query.word) 43 | elif query.type == "find": 44 | if query.word in self.hash_table[hash_value]: 45 | print('yes') 46 | else: 47 | print('no') 48 | 49 | 50 | if __name__ == '__main__': 51 | n_buckets = int(input()) 52 | hash_table = QueryProcessor(n_buckets) 53 | n_queries = int(input()) 54 | for _ in range(n_queries): 55 | command = Query(input().split()) 56 | hash_table.ProcessQuery(command) 57 | -------------------------------------------------------------------------------- /data-structures/week-4/hash_substring.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | ll hashf(string& s, ll prime, ll x) { 30 | ll hv = 0; 31 | 32 | for (int i = s.size() - 1; i >= 0; i--) { 33 | hv = (hv * x + s[i]) % prime; 34 | } 35 | 36 | return hv; 37 | } 38 | 39 | vll precomputeHashes(string& text, string& pattern, ll prime, ll x) { 40 | int t = text.size(), p = pattern.size(); 41 | string s = text.substr(t - p, string::npos); 42 | vll h(t - p + 1); 43 | ll y = 1; 44 | 45 | h[t - p] = hashf(s, prime, x); 46 | 47 | for (int i = 1; i <= p; i++) { 48 | y = (y * x) % prime; 49 | } 50 | 51 | for (int i = t - p - 1; i >= 0; i--) { 52 | h[i] = (x * h[i + 1] + text[i] - y * text[i + p]) % prime; 53 | } 54 | 55 | return h; 56 | } 57 | 58 | int main() { 59 | ios_base::sync_with_stdio(0); 60 | cin.tie(0); 61 | cout.tie(0); 62 | // freopen("input.txt", "r", stdin); 63 | // freopen("output.txt", "w", stdout); 64 | 65 | string text, pattern; 66 | cin >> pattern >> text; 67 | 68 | ll prime = 1000000007, x = 236; 69 | ll phash = hashf(pattern, prime, x); 70 | vll h = precomputeHashes(text, pattern, prime, x); 71 | vi ans; 72 | 73 | for (int i = 0; i < (text.size() - pattern.size() + 1); i++) { 74 | if (phash == h[i]) { 75 | ans.push_back(i); 76 | } 77 | } 78 | 79 | copy(ans.begin(), ans.end(), ostream_iterator(cout, " ")); 80 | cout << endl; 81 | 82 | return 0; 83 | } -------------------------------------------------------------------------------- /data-structures/week-4/hash_substring.py: -------------------------------------------------------------------------------- 1 | # python3 2 | 3 | 4 | def PolyHash(string, prime, multiplier): 5 | hash_value = 0 6 | for i in range(len(string) - 1, -1, -1): 7 | hash_value = (hash_value * multiplier + ord(string[i])) % prime 8 | return hash_value 9 | 10 | 11 | def PrecomputedHashes(text, pattern, prime, multiplier): 12 | t = len(text) 13 | p = len(pattern) 14 | s = text[t - p:] 15 | H = list([] for _ in range(t - p + 1)) 16 | H[t - p] = PolyHash(s, prime, multiplier) 17 | y = 1 18 | for i in range(1, p + 1): 19 | y = (y * multiplier) % prime 20 | for i in range(t - p - 1, -1, -1): 21 | H[i] = (multiplier * H[i + 1] + ord(text[i]) - y * ord(text[i + p])) % prime 22 | return H 23 | 24 | 25 | def RabinKarp(text, pattern): 26 | t = len(text) 27 | p = len(pattern) 28 | prime = 1000000007 29 | multiplier = 236 30 | result = [] 31 | pattern_hash = PolyHash(pattern, prime, multiplier) 32 | hash_substrings = PrecomputedHashes(text, pattern, prime, multiplier) 33 | for i in range(t - p + 1): 34 | if pattern_hash == hash_substrings[i]: 35 | result.append(i) 36 | return result 37 | 38 | 39 | if __name__ == '__main__': 40 | pattern = input() 41 | text = input() 42 | positions = RabinKarp(text, pattern) 43 | for pos in positions: 44 | print(pos, end=' ') -------------------------------------------------------------------------------- /data-structures/week-4/matching_with_mismatches.py: -------------------------------------------------------------------------------- 1 | # python3 2 | 3 | import sys 4 | from collections import deque 5 | 6 | 7 | def HashTable(s, prime, x): 8 | hash_table = list([] for _ in range(len(s) + 1)) 9 | hash_table[0] = 0 10 | for i in range(1, len(s) + 1): 11 | hash_table[i] = (hash_table[i - 1] * x + ord(s[i - 1])) % prime 12 | return hash_table 13 | 14 | 15 | def HashValue(hash_table, prime, x, start, length): 16 | y = pow(x, length, prime) 17 | hash_value = (hash_table[start + length] - y * hash_table[start]) % prime 18 | return hash_value 19 | 20 | 21 | def PreCompute(text, pattern): 22 | global m, x 23 | h1 = HashTable(text, m, x) 24 | h2 = HashTable(pattern, m, x) 25 | return h1, h2 26 | 27 | 28 | def CheckMatch(a_start, length, p_len, k): 29 | global m, h1, h2 30 | stack = deque() 31 | stack.append((a_start, 0, length, 1)) 32 | stack.append((a_start+length, length, p_len-length, 1)) 33 | count = 0 34 | temp = 2 35 | C = 0 36 | while stack: 37 | a, b, L, n = stack.popleft() 38 | u1 = HashValue(h1, m, x, a, L) 39 | v1 = HashValue(h2, m, x, b, L) 40 | if temp != n: 41 | count = C 42 | if u1 != v1: 43 | count += 1 44 | if L > 1: 45 | stack.append((a, b, L//2, n+1)) 46 | stack.append((a + L//2, b + L//2, L - L//2, n+1)) 47 | else: 48 | C += 1 49 | if count > k: 50 | return False 51 | temp = n 52 | if count > k: 53 | return False 54 | else: 55 | return True 56 | 57 | 58 | def Solve(t, p, k): 59 | global h1, h2 60 | h1, h2 = PreCompute(t, p) 61 | pos = [] 62 | for i in range(len(t) - len(p) + 1): 63 | if CheckMatch(i, len(p) // 2, len(p), k): 64 | pos.append(i) 65 | return pos 66 | 67 | 68 | m = 1000000007 69 | x = 263 70 | 71 | for line in sys.stdin.readlines(): 72 | k, t, p = line.split() 73 | results = Solve(t, p, int(k)) 74 | print(len(results), *results) -------------------------------------------------------------------------------- /data-structures/week-4/phone_book.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | int main() { 30 | ios_base::sync_with_stdio(0); 31 | cin.tie(0); 32 | cout.tie(0); 33 | // freopen("input.txt", "r", stdin); 34 | // freopen("output.txt", "w", stdout); 35 | 36 | ll n; 37 | cin >> n; 38 | 39 | unordered_map m; 40 | vector ans; 41 | 42 | for (int i = 0; i < n; i++) { 43 | string cmd; 44 | cin >> cmd; 45 | 46 | if (cmd == "add") { 47 | int num; 48 | string name; 49 | cin >> num >> name; 50 | m[num] = name; 51 | } else if (cmd == "del") { 52 | int num; 53 | cin >> num; 54 | 55 | if (m.find(num) != m.end()) { 56 | m.erase(num); 57 | } 58 | } else if (cmd == "find") { 59 | int num; 60 | cin >> num; 61 | 62 | ans.push_back(m.count(num) ? m[num] : "not found"); 63 | } 64 | } 65 | 66 | copy(ans.begin(), ans.end(), ostream_iterator(cout, "\n")); 67 | cout << endl; 68 | 69 | return 0; 70 | } -------------------------------------------------------------------------------- /data-structures/week-4/substr.py: -------------------------------------------------------------------------------- 1 | # python3 2 | 3 | 4 | def HashTable(s, prime, x): 5 | hash_table = list([] for _ in range(len(s) + 1)) 6 | hash_table[0] = 0 7 | for i in range(1, len(s) + 1): 8 | hash_table[i] = (hash_table[i - 1] * x + ord(s[i - 1])) % prime 9 | return hash_table 10 | 11 | 12 | def HashValue(hash_table, prime, x, start, length): 13 | y = pow(x, length, prime) 14 | hash_value = (hash_table[start + length] - y * hash_table[start]) % prime 15 | return hash_value 16 | 17 | 18 | def AreEqual(table1, table2, prime1, prime2, x, a, b, l): 19 | a_hash1 = HashValue(table1, prime1, x, a, l) 20 | a_hash2 = HashValue(table2, prime2, x, a, l) 21 | b_hash1 = HashValue(table1, prime1, x, b, l) 22 | b_hash2 = HashValue(table2, prime2, x, b, l) 23 | if a_hash1 == b_hash1 and a_hash2 == b_hash2: 24 | return 'Yes' 25 | else: 26 | return 'No' 27 | 28 | 29 | if __name__ == '__main__': 30 | string = input() 31 | n_queries = int(input()) 32 | m = 1000000007 33 | m2 = 1000000009 34 | x = 263 35 | hash_table1 = HashTable(string, m, x) 36 | hash_table2 = HashTable(string, m2, x) 37 | # print(hash_table1, hash_table2) 38 | for i in range(n_queries): 39 | a, b, l = map(int, input().split()) 40 | print(AreEqual(hash_table1, hash_table2, m, m2, x, a, b, l)) -------------------------------------------------------------------------------- /data-structures/week-6/is_bst.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | class Node { 30 | private: 31 | int l, r; 32 | unordered_map *m; 33 | public: 34 | int val; 35 | 36 | Node(int v, int _l, int _r, unordered_map *_m) { 37 | val = v; 38 | l = _l; 39 | r = _r; 40 | m = _m; 41 | } 42 | 43 | Node* left() { 44 | if (l == -1) { 45 | return nullptr; 46 | } 47 | 48 | return (*m)[l]; 49 | } 50 | 51 | Node* right() { 52 | if (r == -1) { 53 | return nullptr; 54 | } 55 | 56 | return (*m)[r]; 57 | } 58 | }; 59 | 60 | int main() { 61 | ios_base::sync_with_stdio(0); 62 | cin.tie(0); 63 | cout.tie(0); 64 | // freopen("input.txt", "r", stdin); 65 | // freopen("output.txt", "w", stdout); 66 | 67 | ll n; 68 | cin >> n; 69 | 70 | int v, l, r; 71 | bool isValid = true; 72 | vi in; 73 | unordered_map m; 74 | 75 | for (int i = 0; i < n; i++) { 76 | cin >> v >> l >> r; 77 | 78 | m[i] = new Node(v, l, r, &m); 79 | } 80 | 81 | // in-order 82 | stack st; 83 | Node *cur = m.empty() ? nullptr : m[0]; 84 | 85 | while (!st.empty() || cur != nullptr) { 86 | if (cur != nullptr) { 87 | st.push(cur); 88 | cur = cur->left(); 89 | } else { 90 | cur = st.top(); 91 | st.pop(); 92 | 93 | in.push_back(cur->val); 94 | 95 | cur = cur->right(); 96 | } 97 | } 98 | 99 | for (int i = 1; i < n; i++) { 100 | if (in[i] <= in[i - 1]) { 101 | isValid = false; 102 | break; 103 | } 104 | } 105 | 106 | cout << (isValid ? "CORRECT" : "INCORRECT") << endl; 107 | 108 | return 0; 109 | } -------------------------------------------------------------------------------- /data-structures/week-6/is_bst_hard.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | class Node { 30 | private: 31 | int l, r; 32 | unordered_map *m; 33 | public: 34 | ll val; 35 | 36 | Node(ll v, int _l, int _r, unordered_map *_m) { 37 | val = v; 38 | l = _l; 39 | r = _r; 40 | m = _m; 41 | } 42 | 43 | Node* left() { 44 | if (l == -1) { 45 | return nullptr; 46 | } 47 | 48 | return (*m)[l]; 49 | } 50 | 51 | Node* right() { 52 | if (r == -1) { 53 | return nullptr; 54 | } 55 | 56 | return (*m)[r]; 57 | } 58 | }; 59 | 60 | int main() { 61 | ios_base::sync_with_stdio(0); 62 | cin.tie(0); 63 | cout.tie(0); 64 | // freopen("input.txt", "r", stdin); 65 | // freopen("output.txt", "w", stdout); 66 | 67 | ll n, v; 68 | cin >> n; 69 | 70 | int l, r; 71 | bool isValid = true; 72 | unordered_map m; 73 | 74 | for (int i = 0; i < n; i++) { 75 | cin >> v >> l >> r; 76 | 77 | m[i] = new Node(v, l, r, &m); 78 | } 79 | 80 | stack> st; 81 | 82 | if (!m.empty()) { 83 | st.push({-LINF, m[0], LINF}); 84 | } 85 | 86 | while (!st.empty()) { 87 | ll m = get<0>(st.top()), M = get<2>(st.top()); 88 | Node *node = get<1>(st.top()); 89 | 90 | st.pop(); 91 | 92 | if (node->val < m || node->val >= M) { 93 | isValid = false; 94 | break; 95 | } 96 | 97 | if (node->left()) { 98 | st.push({m, node->left(), node->val}); 99 | } 100 | 101 | if (node->right()) { 102 | st.push({node->val, node->right(), M}); 103 | } 104 | } 105 | 106 | cout << (isValid ? "CORRECT" : "INCORRECT") << endl; 107 | 108 | return 0; 109 | } -------------------------------------------------------------------------------- /data-structures/week-6/rope.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import sys, random 4 | 5 | class Node: 6 | def __init__(v, x, y, l, r): 7 | v.size, v.x, v.y, v.l, v.r = 1, x, y, l, r 8 | def calc(v): 9 | v.size = v.l.size + v.r.size + 1 10 | @staticmethod 11 | def init(): 12 | p = Node(0, 0, None, None) 13 | p.size = 0 14 | Node.nul = p.l = p.r = p 15 | Node.cnt = 0 16 | Node.init() 17 | 18 | class Rope: 19 | @staticmethod 20 | def split(t, k): 21 | if t == Node.nul: 22 | return (Node.nul, Node.nul) 23 | if t.l.size < k: 24 | (l, r) = Rope.split(t.r, k - t.l.size - 1) 25 | t.r = l 26 | t.calc() 27 | return (t, r) 28 | else: 29 | (l, r) = Rope.split(t.l, k) 30 | t.l = r 31 | t.calc() 32 | return (l, t) 33 | 34 | @staticmethod 35 | def merge(l, r): 36 | if l == Node.nul: 37 | return r 38 | if r == Node.nul: 39 | return l 40 | if l.y < r.y: 41 | l.r = Rope.merge(l.r, r) 42 | l.calc() 43 | return l 44 | else: 45 | r.l = Rope.merge(l, r.l) 46 | r.calc() 47 | return r 48 | 49 | @staticmethod 50 | def out(t, buf): 51 | if t == Node.nul: 52 | return 53 | Rope.out(t.l, buf) 54 | buf.append(t.x) 55 | Rope.out(t.r, buf) 56 | 57 | def result(self): 58 | buf = [] 59 | Rope.out(self.root, buf) 60 | return "".join(buf) 61 | 62 | def __init__(self, s): 63 | self.root = Node.nul 64 | for c in s: 65 | self.root = Rope.merge(self.root, Node(c, random.randint(0, 1 << 30), Node.nul, Node.nul)) 66 | 67 | def process(self, i, j, k): 68 | j += 1 69 | (l, r) = Rope.split(self.root, i) 70 | (m, r) = Rope.split(r, j - i) 71 | (l, r) = Rope.split(Rope.merge(l, r), k) 72 | self.root = Rope.merge(Rope.merge(l, m), r) 73 | 74 | s = sys.stdin.readline().strip() 75 | rope = Rope(s) 76 | q = int(sys.stdin.readline()) 77 | for _ in range(q): 78 | i, j, k = map(int, sys.stdin.readline().strip().split()) 79 | rope.process(i, j, k) 80 | print(rope.result()) -------------------------------------------------------------------------------- /data-structures/week-6/set_range_sum.py: -------------------------------------------------------------------------------- 1 | # python 3 2 | 3 | 4 | class Vertex: 5 | def __init__(self, key, sum, left, right, parent): 6 | (self.key, self.sum, self.left, self.right, self.parent) = (key, sum, left, right, parent) 7 | 8 | 9 | def update(v): 10 | if v is None: 11 | return 12 | v.sum = v.key + (v.left.sum if v.left is not None else 0) + (v.right.sum if v.right is not None else 0) 13 | if v.left is not None: 14 | v.left.parent = v 15 | if v.right is not None: 16 | v.right.parent = v 17 | 18 | 19 | def smallRotation(v): 20 | parent = v.parent 21 | if parent is None: 22 | return 23 | grandparent = v.parent.parent 24 | if parent.left == v: 25 | m = v.right 26 | v.right = parent 27 | parent.left = m 28 | else: 29 | m = v.left 30 | v.left = parent 31 | parent.right = m 32 | update(parent) 33 | update(v) 34 | v.parent = grandparent 35 | if grandparent is not None: 36 | if grandparent.left == parent: 37 | grandparent.left = v 38 | else: 39 | grandparent.right = v 40 | 41 | 42 | def bigRotation(v): 43 | if v.parent.left == v and v.parent.parent.left == v.parent: 44 | smallRotation(v.parent) 45 | smallRotation(v) 46 | elif v.parent.right == v and v.parent.parent.right == v.parent: 47 | smallRotation(v.parent) 48 | smallRotation(v) 49 | else: 50 | smallRotation(v) 51 | smallRotation(v) 52 | 53 | 54 | def splay(v): 55 | if v is None: 56 | return None 57 | while v.parent is not None: 58 | if v.parent.parent == None: 59 | smallRotation(v) 60 | break 61 | bigRotation(v) 62 | return v 63 | 64 | 65 | def find(root, key): 66 | v = root 67 | last = root 68 | next = None 69 | while v is not None: 70 | if v.key >= key and (next is None or v.key < next.key): 71 | next = v 72 | last = v 73 | if v.key == key: 74 | break 75 | if v.key < key: 76 | v = v.right 77 | else: 78 | v = v.left 79 | root = splay(last) 80 | if next is not None: 81 | root = splay(next) 82 | return next, root 83 | 84 | 85 | def split(root, key): 86 | result, root = find(root, key) 87 | if result is None: 88 | return root, None 89 | right = splay(result) 90 | left = right.left 91 | right.left = None 92 | if left is not None: 93 | left.parent = None 94 | update(left) 95 | update(right) 96 | return left, right 97 | 98 | 99 | def merge(left, right): 100 | if left is None: 101 | return right 102 | if right is None: 103 | return left 104 | while right.left is not None: 105 | right = right.left 106 | right = splay(right) 107 | right.left = left 108 | left.parent = right 109 | update(right) 110 | return right 111 | 112 | 113 | root = None 114 | 115 | 116 | def insert(x): 117 | global root 118 | (left, right) = split(root, x) 119 | new_vertex = None 120 | if right is None or right.key != x: 121 | new_vertex = Vertex(x, x, None, None, None) 122 | root = merge(merge(left, new_vertex), right) 123 | 124 | 125 | def erase(x): 126 | global root 127 | (left, middle) = split(root, x) 128 | (middle, right) = split(middle, x + 1) 129 | root = merge(left, right) 130 | 131 | 132 | def search(x): 133 | global root 134 | (result, root) = find(root, x) 135 | if result is None or result.key != x: 136 | return False 137 | else: 138 | return True 139 | 140 | 141 | def sum(fr, to): 142 | global root 143 | (left, middle) = split(root, fr) 144 | (middle, right) = split(middle, to + 1) 145 | ans = 0 146 | if middle is not None: 147 | ans += middle.sum 148 | root = merge(merge(left, middle), right) 149 | return ans 150 | 151 | 152 | MODULO = 1000000001 153 | n_operations = int(input()) 154 | last_sum_result = 0 155 | for _ in range(n_operations): 156 | line = list(input().split()) 157 | if line[0] == '+': 158 | x = int(line[1]) 159 | insert((x + last_sum_result) % MODULO) 160 | elif line[0] == '-': 161 | x = int(line[1]) 162 | erase((x + last_sum_result) % MODULO) 163 | elif line[0] == '?': 164 | x = int(line[1]) 165 | if search((x + last_sum_result) % MODULO): 166 | print('Found') 167 | else: 168 | print('Not found') 169 | elif line[0] == 's': 170 | l = int(line[1]) 171 | r = int(line[2]) 172 | res = sum((l + last_sum_result) % MODULO, (r + last_sum_result) % MODULO) 173 | print(res) 174 | last_sum_result = res % MODULO -------------------------------------------------------------------------------- /data-structures/week-6/tree_orders.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: This template uses some c++11 functions , so you have to compile it with c++11 flag. 3 | * Example: $ g++ -std=c++11 c++ source.cpp 4 | * 5 | * Author: Bohdan Shtepan 6 | * GitHub: https://github.com/virtyaluk 7 | * Site: https://modern-dev.com 8 | * 9 | */ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | #define ar array 16 | #define ll long long int 17 | typedef vector vi; 18 | typedef vector vll; 19 | typedef vector vvi; 20 | typedef vector vvll; 21 | typedef vector vf; 22 | typedef vector vd; 23 | 24 | const int MAX_N = 1e5 + 1; 25 | const int MOD = 1e9 + 7; 26 | const int INF = 1e9; 27 | const ll LINF = 1e18; 28 | 29 | class Node { 30 | private: 31 | int l, r; 32 | unordered_map *m; 33 | public: 34 | int val; 35 | 36 | Node(int v, int _l, int _r, unordered_map *_m) { 37 | val = v; 38 | l = _l; 39 | r = _r; 40 | m = _m; 41 | } 42 | 43 | Node* left() { 44 | if (l == -1) { 45 | return nullptr; 46 | } 47 | 48 | return (*m)[l]; 49 | } 50 | 51 | Node* right() { 52 | if (r == -1) { 53 | return nullptr; 54 | } 55 | 56 | return (*m)[r]; 57 | } 58 | }; 59 | 60 | int main() { 61 | ios_base::sync_with_stdio(0); 62 | cin.tie(0); 63 | cout.tie(0); 64 | // freopen("input.txt", "r", stdin); 65 | // freopen("output.txt", "w", stdout); 66 | 67 | ll n; 68 | cin >> n; 69 | 70 | int v, l, r; 71 | vi in, pre, post; 72 | unordered_map m; 73 | Node *head = nullptr; 74 | 75 | for (int i = 0; i < n; i++) { 76 | cin >> v >> l >> r; 77 | 78 | Node *node = new Node(v, l, r, &m); 79 | m[i] = node; 80 | 81 | if (!head) { 82 | head = node; 83 | } 84 | } 85 | 86 | // in-order 87 | stack st; 88 | Node *cur = head; 89 | 90 | while (!st.empty() || cur != nullptr) { 91 | if (cur != nullptr) { 92 | st.push(cur); 93 | cur = cur->left(); 94 | } else { 95 | cur = st.top(); 96 | st.pop(); 97 | 98 | in.push_back(cur->val); 99 | 100 | cur = cur->right(); 101 | } 102 | } 103 | 104 | // pre-order 105 | st = {}; 106 | st.push(head); 107 | 108 | while (!st.empty()) { 109 | cur = st.top(); 110 | st.pop(); 111 | 112 | pre.push_back(cur->val); 113 | 114 | if (cur->right()) { 115 | st.push(cur->right()); 116 | } 117 | 118 | if (cur->left()) { 119 | st.push(cur->left()); 120 | } 121 | } 122 | 123 | // post-order 124 | st = {}; 125 | st.push(head); 126 | 127 | while (!st.empty()) { 128 | cur = st.top(); 129 | st.pop(); 130 | 131 | post.push_back(cur->val); 132 | 133 | if (cur->left()) { 134 | st.push(cur->left()); 135 | } 136 | 137 | if (cur->right()) { 138 | st.push(cur->right()); 139 | } 140 | } 141 | 142 | reverse(post.begin(), post.end()); 143 | 144 | copy(in.begin(), in.end(), ostream_iterator(cout, " ")); 145 | cout << endl; 146 | copy(pre.begin(), pre.end(), ostream_iterator(cout, " ")); 147 | cout << endl; 148 | copy(post.begin(), post.end(), ostream_iterator(cout, " ")); 149 | cout << endl; 150 | 151 | return 0; 152 | } --------------------------------------------------------------------------------