aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2026-07-06 19:08:08 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2026-07-06 19:08:08 +0200
commit96254947699986c59f0dc63d69fd4b76bd3ed43e (patch)
tree6c4dca945d7f7427c48be234d827fe4d33be02c5
downloadcses-96254947699986c59f0dc63d69fd4b76bd3ed43e.tar.gz
cses-96254947699986c59f0dc63d69fd4b76bd3ed43e.zip
Initial commit
-rwxr-xr-x01_introductory_problems/a.outbin0 -> 18512 bytes
-rw-r--r--01_introductory_problems/apple_division_1623.cpp21
-rw-r--r--01_introductory_problems/bit_strings_1617.cpp10
-rw-r--r--01_introductory_problems/chessboard_and_queens_1624.cpp42
-rw-r--r--01_introductory_problems/coin_piles_1754.cpp18
-rw-r--r--01_introductory_problems/creating_strings_1622.cpp30
-rw-r--r--01_introductory_problems/digit_queries_2431.cpp23
-rw-r--r--01_introductory_problems/gray_code_2205.cpp22
-rw-r--r--01_introductory_problems/grid_coloring_i_3311.cpp17
-rw-r--r--01_introductory_problems/grid_path_description_1625.cpp150
-rw-r--r--01_introductory_problems/increasing_array_1094.cpp12
-rw-r--r--01_introductory_problems/knight_moves_grid_3217.cpp40
-rw-r--r--01_introductory_problems/mex_grid_construction_3419.cpp30
-rw-r--r--01_introductory_problems/missing_number_1083.cpp9
-rw-r--r--01_introductory_problems/number_spiral_1071.cpp27
-rw-r--r--01_introductory_problems/palindrome_reorder_1755.cpp35
-rw-r--r--01_introductory_problems/permutations_1070.cpp15
-rw-r--r--01_introductory_problems/raab_game_i_3399.cpp67
-rw-r--r--01_introductory_problems/repetitions_1069.cpp20
-rw-r--r--01_introductory_problems/string_reorder_1743.cpp38
-rw-r--r--01_introductory_problems/tower_of_hanoi_2165.cpp17
-rw-r--r--01_introductory_problems/trailing_zeros_1618.cpp9
-rw-r--r--01_introductory_problems/two_knights_1072.cpp24
-rw-r--r--01_introductory_problems/two_sets_1092.cpp53
-rw-r--r--01_introductory_problems/weird_algorithm_1068.cpp12
-rwxr-xr-x02_sorting_and_searching/a.outbin0 -> 18400 bytes
-rw-r--r--02_sorting_and_searching/apartments_1084.cpp27
-rw-r--r--02_sorting_and_searching/collecting_numbers_2216.cpp46
-rw-r--r--02_sorting_and_searching/concert_tickets_1091.cpp25
-rw-r--r--02_sorting_and_searching/distinct_numbers_1621.cpp13
-rw-r--r--02_sorting_and_searching/ferris_wheel_1090.cpp17
-rw-r--r--02_sorting_and_searching/maximum_subarray_sum_1643.cpp19
-rw-r--r--02_sorting_and_searching/missing_coin_sum_2183.cpp16
-rw-r--r--02_sorting_and_searching/movie_festival_1629.cpp21
-rw-r--r--02_sorting_and_searching/playlist_1141.cpp22
-rw-r--r--02_sorting_and_searching/restaurant_customers_1619.cpp24
-rw-r--r--02_sorting_and_searching/room_allocation_1164.cpp38
-rw-r--r--02_sorting_and_searching/stick_lengths_1074.cpp16
-rw-r--r--02_sorting_and_searching/sum_of_two_values_1640.cpp27
-rw-r--r--02_sorting_and_searching/towers_1063.cpp17
-rwxr-xr-x03_dynamic_programming/a.outbin0 -> 13520 bytes
-rw-r--r--03_dynamic_programming/coin_combinations_i_1635.cpp25
-rw-r--r--03_dynamic_programming/coin_combinations_ii_1636.cpp28
-rw-r--r--03_dynamic_programming/counting_towers_2413.cpp38
-rw-r--r--03_dynamic_programming/dice_combinations_1633.cpp19
-rw-r--r--03_dynamic_programming/edit_distance_1639.cpp22
-rw-r--r--03_dynamic_programming/longest_common_subsequence_3403.cpp44
-rw-r--r--03_dynamic_programming/minimizing_coins_1634.cpp33
-rw-r--r--03_dynamic_programming/removing_digits_1637.cpp28
-rwxr-xr-x04_graph_algorithms/a.outbin0 -> 14176 bytes
-rw-r--r--04_graph_algorithms/building_roads_1666.cpp32
-rw-r--r--04_graph_algorithms/building_teams_1668.cpp37
-rw-r--r--04_graph_algorithms/counting_rooms_1192.cpp62
-rw-r--r--04_graph_algorithms/high_score_1673.cpp61
-rw-r--r--04_graph_algorithms/labyrinth_1193.cpp131
-rw-r--r--04_graph_algorithms/message_route_1667.cpp54
-rw-r--r--04_graph_algorithms/round_trip_1669.cpp44
-rw-r--r--04_graph_algorithms/shortest_routes_i_1671.cpp43
-rw-r--r--04_graph_algorithms/shortest_routes_ii_1672.cpp30
-rwxr-xr-x05_range_queries/a.outbin0 -> 15808 bytes
-rw-r--r--05_range_queries/dynamic_range_minimum_queries_1649.cpp54
-rw-r--r--05_range_queries/dynamic_range_sum_queries_1648.cpp50
-rw-r--r--05_range_queries/range_xor_queries_1650.cpp20
-rw-r--r--05_range_queries/static_range_minimum_queries_1647.cpp47
-rw-r--r--05_range_queries/static_range_sum_queries_1646.cpp17
-rwxr-xr-x06_tree_algorithms/a.outbin0 -> 34024 bytes
-rw-r--r--06_tree_algorithms/subordinates_1674.cpp23
-rw-r--r--06_tree_algorithms/tree_matching_1130.cpp41
-rwxr-xr-x07_mathematics/a.outbin0 -> 48984 bytes
-rw-r--r--07_mathematics/common_divisors_1081.cpp53
-rw-r--r--07_mathematics/counting_divisors_1713.cpp34
-rw-r--r--07_mathematics/exponentiation_1095.cpp19
-rw-r--r--07_mathematics/exponentiation_ii_1712.cpp20
-rw-r--r--07_mathematics/josephus_queries_2164.cpp17
-rwxr-xr-x08_string_algorithms/a.outbin0 -> 27192 bytes
-rw-r--r--08_string_algorithms/finding_borders_1732.cpp23
-rw-r--r--08_string_algorithms/finding_periods_1733.cpp29
-rw-r--r--08_string_algorithms/string_matching_1753.cpp32
-rw-r--r--08_string_algorithms/word_combinations_1731.cpp63
-rwxr-xr-x09_geometry/a.outbin0 -> 13208 bytes
-rw-r--r--09_geometry/line_segment_intersection_2190.cpp41
-rw-r--r--09_geometry/point_location_test_2189.cpp21
-rwxr-xr-x10_advanced_techniques/a.outbin0 -> 25000 bytes
-rw-r--r--10_advanced_techniques/hamming_distance_2136.cpp22
-rw-r--r--10_advanced_techniques/meet_in_the_middle_1628.cpp42
-rwxr-xr-x11_sliding_window_problems/a.outbin0 -> 65568 bytes
-rw-r--r--11_sliding_window_problems/sliding_window_minimum_3221.cpp29
-rw-r--r--11_sliding_window_problems/sliding_window_or_3405.cpp28
-rw-r--r--11_sliding_window_problems/sliding_window_sum_3220.cpp25
-rw-r--r--11_sliding_window_problems/sliding_window_xor_3426.cpp26
-rwxr-xr-x12_interactive_problems/a.outbin0 -> 14296 bytes
-rw-r--r--12_interactive_problems/hidden_integer_3112.cpp16
-rw-r--r--12_interactive_problems/hidden_permutation_3139.cpp45
-rwxr-xr-x13_bitwise_operations/a.outbin0 -> 14488 bytes
-rw-r--r--13_bitwise_operations/counting_bits_1146.cpp14
-rw-r--r--13_bitwise_operations/maximum_xor_subarray_1655.cpp53
-rwxr-xr-x14_construction_problems/a.outbin0 -> 16048 bytes
-rw-r--r--14_construction_problems/inverse_inversions_2214.cpp22
-rwxr-xr-x15_advanced_graph_problems/a.outbin0 -> 18368 bytes
-rw-r--r--15_advanced_graph_problems/nearest_shops_3303.cpp55
-rwxr-xr-x16_counting_problems/a.outbin0 -> 14160 bytes
-rw-r--r--16_counting_problems/filled_subgrid_count_i_3413.cpp38
-rwxr-xr-x17_additional_problems_i/a.outbin0 -> 13816 bytes
-rw-r--r--17_additional_problems_i/shortest_subsequence_1087.cpp66
-rwxr-xr-x18_additional_problems_ii/a.outbin0 -> 13040 bytes
-rw-r--r--18_additional_problems_ii/bouncing_ball_steps_3215.cpp24
-rw-r--r--README.md6
-rw-r--r--notes.txt5
108 files changed, 2920 insertions, 0 deletions
diff --git a/01_introductory_problems/a.out b/01_introductory_problems/a.out
new file mode 100755
index 0000000..8c1bdbd
--- /dev/null
+++ b/01_introductory_problems/a.out
Binary files differ
diff --git a/01_introductory_problems/apple_division_1623.cpp b/01_introductory_problems/apple_division_1623.cpp
new file mode 100644
index 0000000..fb367b4
--- /dev/null
+++ b/01_introductory_problems/apple_division_1623.cpp
@@ -0,0 +1,21 @@
1#include <iostream>
2#include <numeric>
3#include <vector>
4
5long long md(std::vector<long long>& a, long long p, long long t, size_t i) {
6 if (2*p >= t)
7 return 2*p - t;
8 if (i == a.size())
9 return t;
10 return std::min(md(a, p, t, i+1), md(a, p+a[i], t, i+1));
11}
12
13int main() {
14 size_t n;
15 std::cin >> n;
16 std::vector<long long> a(n);
17 for (size_t i = 0; i < n; i++)
18 std::cin >> a[i];
19 auto s = md(a, 0, std::accumulate(a.begin(), a.end(), (long long)0), 0);
20 std::cout << s << "\n";
21}
diff --git a/01_introductory_problems/bit_strings_1617.cpp b/01_introductory_problems/bit_strings_1617.cpp
new file mode 100644
index 0000000..6be46ac
--- /dev/null
+++ b/01_introductory_problems/bit_strings_1617.cpp
@@ -0,0 +1,10 @@
1#include <iostream>
2
3int main() {
4 constexpr long long M = 1e9+7;
5 long long n, a{1};
6 std::cin >> n;
7 while (--n >= 0)
8 a = (a * 2) % M;
9 std::cout << a << std::endl;
10}
diff --git a/01_introductory_problems/chessboard_and_queens_1624.cpp b/01_introductory_problems/chessboard_and_queens_1624.cpp
new file mode 100644
index 0000000..d595232
--- /dev/null
+++ b/01_introductory_problems/chessboard_and_queens_1624.cpp
@@ -0,0 +1,42 @@
1#include <bitset>
2#include <iostream>
3#include <string>
4
5void set_bit(std::bitset<64>& r, int i, int j) {
6 if (i >= 0 && i < 8 && j >= 0 && j < 8)
7 r |= 1ULL << (unsigned long long)(8*i + j);
8}
9
10std::bitset<64> maskall(const std::bitset<64>& b, int i, int j) {
11 std::bitset<64> r{b};
12 r |= 0x0101010101010101ULL << (unsigned long long)j;
13 for (int k = 0; k < 8; k++) {
14 set_bit(r, k, k+j-i);
15 set_bit(r, k, -k+j+i);
16 }
17 return r;
18}
19
20long long f(std::bitset<64>& b, int i) {
21 if (i == 8)
22 return 1;
23 long long s{0};
24 for (int j = 0; j < 8; j++) {
25 if (!b[8*i+j]) {
26 auto rr = maskall(b, i, j);
27 s += f(rr, i+1);
28 }
29 }
30 return s;
31}
32
33int main() {
34 std::bitset<64> b{0};
35 std::string s;
36 for (int i = 0; i < 8; i++) {
37 std::cin >> s;
38 for (int j = 0; j < 8; j++)
39 b[8*i+j] = s[j] == '*';
40 }
41 std::cout << f(b, 0) << "\n";
42}
diff --git a/01_introductory_problems/coin_piles_1754.cpp b/01_introductory_problems/coin_piles_1754.cpp
new file mode 100644
index 0000000..c54cdf1
--- /dev/null
+++ b/01_introductory_problems/coin_piles_1754.cpp
@@ -0,0 +1,18 @@
1#include <algorithm>
2#include <iostream>
3
4bool f(int a, int b) {
5 auto max = std::max(a, b);
6 auto min = std::min(a, b);
7
8 return max <= 2*min && (2*min - max) % 3 == 0;
9}
10
11int main() {
12 int t, a, b;
13 std::cin >> t;
14 for (int i = 0; i < t; i++) {
15 std::cin >> a >> b;
16 std::cout << (f(a, b) ? "YES" : "NO") << std::endl;
17 }
18}
diff --git a/01_introductory_problems/creating_strings_1622.cpp b/01_introductory_problems/creating_strings_1622.cpp
new file mode 100644
index 0000000..689e083
--- /dev/null
+++ b/01_introductory_problems/creating_strings_1622.cpp
@@ -0,0 +1,30 @@
1#include <iostream>
2#include <string>
3#include <map>
4#include <vector>
5
6void gen(std::map<char, int>& a, int count,
7 std::string start, std::vector<std::string>& res) {
8 if (count == 0)
9 res.push_back(start);
10 for (auto [k, v] : a) {
11 if (v > 0) {
12 a[k]--;
13 gen(a, count - 1, start + k, res);
14 a[k]++;
15 }
16 }
17}
18
19int main() {
20 std::string s;
21 std::map<char, int> a;
22 std::vector<std::string> sol;
23 std::cin >> s;
24 for (auto c : s)
25 a[c]++;
26 gen(a, s.size(), "", sol);
27 std::cout << sol.size() << "\n";
28 for (auto x : sol)
29 std::cout << x << "\n";
30}
diff --git a/01_introductory_problems/digit_queries_2431.cpp b/01_introductory_problems/digit_queries_2431.cpp
new file mode 100644
index 0000000..28c4a2f
--- /dev/null
+++ b/01_introductory_problems/digit_queries_2431.cpp
@@ -0,0 +1,23 @@
1#include <iostream>
2
3int f(long long k) {
4 long long n{1}, p{1}, d{1}, q{9};
5 while (p + d*q <= k) {
6 n += q;
7 p += d * q;
8 d++;
9 q *= 10;
10 }
11 long long x{(k-p) / d + n};
12 long long m{(k-p) % d};
13 for (long long j = 0; j < d-m-1; j++)
14 x /= (long long)10;
15 return x % (long long)10;
16}
17
18int main() {
19 long long k;
20 std::cin >> k;
21 while (std::cin >> k)
22 std::cout << f(k) << "\n";
23}
diff --git a/01_introductory_problems/gray_code_2205.cpp b/01_introductory_problems/gray_code_2205.cpp
new file mode 100644
index 0000000..4fa8a2d
--- /dev/null
+++ b/01_introductory_problems/gray_code_2205.cpp
@@ -0,0 +1,22 @@
1#include <iostream>
2#include <format>
3
4void print(int number, int ndigits) {
5 std::cout << std::format("{0:0{1}b}", number, ndigits) << "\n";
6}
7
8void print_all(int& start, int digit, int ndigits) {
9 if (digit == 0) {
10 print(start, ndigits);
11 } else {
12 print_all(start, digit-1, ndigits);
13 start ^= 1 << (digit-1);
14 print_all(start, digit-1, ndigits);
15 }
16}
17
18int main() {
19 int n, start{0};
20 std::cin >> n;
21 print_all(start, n, n);
22}
diff --git a/01_introductory_problems/grid_coloring_i_3311.cpp b/01_introductory_problems/grid_coloring_i_3311.cpp
new file mode 100644
index 0000000..b6c59a4
--- /dev/null
+++ b/01_introductory_problems/grid_coloring_i_3311.cpp
@@ -0,0 +1,17 @@
1#include <iostream>
2#include <string>
3
4int main() {
5 int n, m;
6 std::cin >> n >> m;
7 for (int i = 0; i < n; i++) {
8 std::string s;
9 std::cin >> s;
10 for (int j = 0; j < m; j++) {
11 char c = 'A' + 2*((i+j)%2);
12 c += c == s[j];
13 std::cout << c;
14 }
15 std::cout << "\n";
16 }
17}
diff --git a/01_introductory_problems/grid_path_description_1625.cpp b/01_introductory_problems/grid_path_description_1625.cpp
new file mode 100644
index 0000000..b483168
--- /dev/null
+++ b/01_introductory_problems/grid_path_description_1625.cpp
@@ -0,0 +1,150 @@
1#include <algorithm>
2#include <bitset>
3#include <iostream>
4#include <queue>
5#include <string>
6#include <vector>
7
8/*
9The official solution uses the heuristic: if both adjacent squares
10in horizontal direction are visited or wall, and both in vertical direction
11are not visited (or the other way round), then we stop because we borked
12the square. I did not think of this criterion, so to check if the square
13is borked I do a full visit from the bottom-left corner. This is too slow,
14so I do this only at depths 10, 20, 30 and 40. This is good enough.
15*/
16
17class Tile {
18public:
19 int i;
20 int j;
21
22 bool valid() const { return i >= 0 && i < 7 && j >= 0 && j < 7; }
23 bool end() const { return i == 6 && j == 0; }
24 bool operator==(const Tile& t) const { return i == t.i && j == t.j; }
25 Tile u() const { return Tile{i-1, j}; }
26 Tile d() const { return Tile{i+1, j}; }
27 Tile l() const { return Tile{i, j-1}; }
28 Tile r() const { return Tile{i, j+1}; }
29 static Tile err() { return Tile{-1, -1}; }
30
31 Tile move(char c) const {
32 if (c == 'U') return u();
33 if (c == 'D') return d();
34 if (c == 'L') return l();
35 if (c == 'R') return r();
36 return err();
37 }
38
39 std::vector<Tile> neighbors() const {
40 return std::vector { u(), d(), l(), r() };
41 }
42};
43
44class Map {
45public:
46 Map() : b(), v(49, 4) {
47 for (int i = 0; i < 7; i++) {
48 v[index(Tile{i, 0})]--;
49 v[index(Tile{i, 6})]--;
50 v[index(Tile{0, i})]--;
51 v[index(Tile{6, i})]--;
52 }
53 }
54
55 bool visited(Tile t) const {
56 return !t.valid() || b.test(index(t));
57 }
58
59 void set(Tile t) {
60 if (!t.valid()) return;
61 b.set(index(t));
62 for (auto u : t.neighbors())
63 if (u.valid())
64 v[index(u)]--;
65 }
66
67 void reset(Tile t) {
68 if (!t.valid()) return;
69 b.reset(index(t));
70 for (auto u : t.neighbors())
71 if (u.valid())
72 v[index(u)]++;
73 }
74
75 std::vector<Tile> locked_neighbors(Tile t) const {
76 std::vector<Tile> r{};
77 for (auto u : t.neighbors())
78 if (locked(u))
79 r.push_back(u);
80 return r;
81 }
82
83 int count() const { return b.count(); }
84
85 bool borked() const {
86 std::bitset<49> vv{};
87 std::queue<Tile> q;
88 q.push(Tile{6, 0});
89 vv.set(index(Tile{6, 0}));
90 int c{1};
91 while (!q.empty()) {
92 Tile t = q.front();
93 q.pop();
94 for (auto u : t.neighbors()) {
95 if (!visited(u) && !vv.test(index(u))) {
96 vv.set(index(u));
97 c++;
98 q.push(u);
99 }
100 }
101 }
102
103 return c + count() < 49;
104 }
105
106private:
107 std::bitset<49> b;
108 std::vector<int> v;
109 static int index(Tile t) { return 7*t.i + t.j; }
110
111 bool locked(Tile t) const {
112 return t.valid() && !visited(t) && !t.end() && v[index(t)] < 2;
113 }
114};
115
116int f(Map& m, const std::string& s, size_t n, Tile t) {
117 if (n == 48) return t.end();
118 if (m.visited(t) || t.end()) return 0;
119
120 m.set(t);
121 if (n % 10 == 0 && m.borked()) {
122 m.reset(t);
123 return 0;
124 }
125
126 auto ln = m.locked_neighbors(t);
127
128 int r{0};
129 if (s[n] != '?') {
130 Tile nt = t.move(s[n]);
131 if (ln.size() == 0 || (ln.size() == 1 && ln[0] == nt))
132 r = f(m, s, n+1, nt);
133 } else {
134 if (ln.size() == 0)
135 r = f(m, s, n+1, t.u()) + f(m, s, n+1, t.d())
136 + f(m, s, n+1, t.l()) + f(m, s, n+1, t.r());
137 if (ln.size() == 1)
138 r = f(m, s, n+1, ln[0]);
139 }
140
141 m.reset(t);
142 return r;
143}
144
145int main() {
146 Map m;
147 std::string s;
148 std::cin >> s;
149 std::cout << f(m, s, 0, Tile{0, 0}) << "\n";
150}
diff --git a/01_introductory_problems/increasing_array_1094.cpp b/01_introductory_problems/increasing_array_1094.cpp
new file mode 100644
index 0000000..314c686
--- /dev/null
+++ b/01_introductory_problems/increasing_array_1094.cpp
@@ -0,0 +1,12 @@
1#include <algorithm>
2#include <iostream>
3
4int main() {
5 long long n, prev{0}, sum{0};
6 std::cin >> n;
7 while (std::cin >> n) {
8 sum += std::max<long long>(0, prev - n);
9 prev = std::max(prev, n);
10 }
11 std::cout << sum << std::endl;
12}
diff --git a/01_introductory_problems/knight_moves_grid_3217.cpp b/01_introductory_problems/knight_moves_grid_3217.cpp
new file mode 100644
index 0000000..212e82c
--- /dev/null
+++ b/01_introductory_problems/knight_moves_grid_3217.cpp
@@ -0,0 +1,40 @@
1#include <iostream>
2#include <queue>
3#include <tuple>
4#include <vector>
5
6struct Node {
7 int i;
8 int j;
9 int d;
10};
11
12int main() {
13 int n;
14 std::cin >> n;
15 std::vector<std::vector<int>> a(n, std::vector<int>(n, 1e7));
16 std::queue<Node> q;
17
18 q.push(Node{0, 0, 0});
19 while (!q.empty()) {
20 auto v = q.front();
21 q.pop();
22 if (v.i < 0 || v.j < 0 || v.i >= n || v.j >= n || a[v.i][v.j] <= v.d)
23 continue;
24 a[v.i][v.j] = v.d;
25 q.push(Node{v.i-2, v.j-1, v.d+1});
26 q.push(Node{v.i-2, v.j+1, v.d+1});
27 q.push(Node{v.i-1, v.j-2, v.d+1});
28 q.push(Node{v.i-1, v.j+2, v.d+1});
29 q.push(Node{v.i+2, v.j-1, v.d+1});
30 q.push(Node{v.i+2, v.j+1, v.d+1});
31 q.push(Node{v.i+1, v.j-2, v.d+1});
32 q.push(Node{v.i+1, v.j+2, v.d+1});
33 }
34
35 for (auto& v : a) {
36 for (auto& x : v)
37 std::cout << x << " ";
38 std::cout << "\n";
39 }
40}
diff --git a/01_introductory_problems/mex_grid_construction_3419.cpp b/01_introductory_problems/mex_grid_construction_3419.cpp
new file mode 100644
index 0000000..feb1171
--- /dev/null
+++ b/01_introductory_problems/mex_grid_construction_3419.cpp
@@ -0,0 +1,30 @@
1#include <algorithm>
2#include <bitset>
3#include <iostream>
4#include <vector>
5
6int firstzero(const std::bitset<200>& b) {
7 for (int i = 0; i < 200; i++)
8 if (!b.test(i))
9 return i;
10 return -1;
11}
12
13int next(int i, int j, std::vector<std::bitset<200>>& col,
14 std::vector<std::bitset<200>>& row) {
15 int r = firstzero(row[i] | col[j]);
16 row[i][r] = col[j][r] = 1;
17 return r;
18}
19
20int main() {
21 int n;
22 std::cin >> n;
23 std::vector<std::bitset<200>> col(n), row(n);
24
25 for (int i = 0; i < n; i++) {
26 for (int j = 0; j < n; j++)
27 std::cout << next(i, j, col, row) << " ";
28 std::cout << "\n";
29 }
30}
diff --git a/01_introductory_problems/missing_number_1083.cpp b/01_introductory_problems/missing_number_1083.cpp
new file mode 100644
index 0000000..527abb2
--- /dev/null
+++ b/01_introductory_problems/missing_number_1083.cpp
@@ -0,0 +1,9 @@
1#include <iostream>
2
3int main() {
4 long long n, m, sum{0};
5 std::cin >> n;
6 while (std::cin >> m)
7 sum += m;
8 std::cout << n*(n+1)/2 - sum << std::endl;
9}
diff --git a/01_introductory_problems/number_spiral_1071.cpp b/01_introductory_problems/number_spiral_1071.cpp
new file mode 100644
index 0000000..d4df631
--- /dev/null
+++ b/01_introductory_problems/number_spiral_1071.cpp
@@ -0,0 +1,27 @@
1#include <algorithm>
2#include <iostream>
3
4long long f(long long x, long long y) {
5 long long c = std::max(x, y);
6 if (c % 2) {
7 if (y >= x)
8 return (c-1)*(c-1)+x;
9 else
10 return c*c-y+1;
11 } else {
12 if (y >= x)
13 return c*c-x+1;
14 else
15 return (c-1)*(c-1)+y;
16 }
17}
18
19int main() {
20 int t;
21 std::cin >> t;
22 for (int i = 0; i < t; i++) {
23 long long x, y;
24 std::cin >> y >> x;
25 std:: cout << f(x, y) << std::endl;
26 }
27}
diff --git a/01_introductory_problems/palindrome_reorder_1755.cpp b/01_introductory_problems/palindrome_reorder_1755.cpp
new file mode 100644
index 0000000..8ebf4f4
--- /dev/null
+++ b/01_introductory_problems/palindrome_reorder_1755.cpp
@@ -0,0 +1,35 @@
1#include <iostream>
2#include <string>
3
4void printn(char c, int n) {
5 for (int i = 0; i < n; i++)
6 std::cout << c;
7}
8
9int main() {
10 std::string s;
11 int odd{0}, a['Z'+1] = {0};
12 char oddc{0};
13 std::cin >> s;
14 for (auto c : s)
15 a[(size_t)c]++;
16 for (char c = 'A'; c <= 'Z'; c++) {
17 if (a[(size_t)c] % 2) {
18 odd++;
19 oddc = c;
20 }
21 }
22 if (odd > 1) {
23 std::cout << "NO SOLUTION\n";
24 } else {
25 for (char c = 'A'; c <= 'Z'; c++)
26 if (c != oddc)
27 printn(c, a[(size_t)c]/2);
28 if (odd)
29 printn(oddc, a[(size_t)oddc]);
30 for (char c = 'Z'; c >= 'A'; c--)
31 if (c != oddc)
32 printn(c, a[(size_t)c]/2);
33 std::cout << std::endl;
34 }
35}
diff --git a/01_introductory_problems/permutations_1070.cpp b/01_introductory_problems/permutations_1070.cpp
new file mode 100644
index 0000000..4438795
--- /dev/null
+++ b/01_introductory_problems/permutations_1070.cpp
@@ -0,0 +1,15 @@
1#include <iostream>
2
3int main() {
4 int n;
5 std::cin >> n;
6 if (n == 2 || n == 3) {
7 std::cout << "NO SOLUTION" << std::endl;
8 } else {
9 for (int i = 2; i <= n; i += 2)
10 std::cout << i << " ";
11 for (int i = 1; i <= n; i += 2)
12 std::cout << i << " ";
13 std::cout << std::endl;
14 }
15}
diff --git a/01_introductory_problems/raab_game_i_3399.cpp b/01_introductory_problems/raab_game_i_3399.cpp
new file mode 100644
index 0000000..bfa5193
--- /dev/null
+++ b/01_introductory_problems/raab_game_i_3399.cpp
@@ -0,0 +1,67 @@
1#include <iostream>
2#include <utility>
3#include <vector>
4
5class Game {
6public:
7 bool y;
8 std::vector<int> a;
9 std::vector<int> b;
10 int apts = 0;
11 int bpts = 0;
12
13 Game(int n, bool w)
14 : y{w}, a{std::vector<int>(n)}, b{std::vector<int>(n)} {}
15
16 void play(int i, int j) {
17 this->a[this->next] = i;
18 this->b[this->next] = j;
19 this->apts += i > j;
20 this->bpts += j > i;
21 this->next++;
22 }
23
24 friend std::ostream& operator<<(std::ostream& os, const Game g) {
25 if (!g.y) {
26 os << "NO\n";
27 } else {
28 os << "YES\n";
29 for (auto x : g.a)
30 os << x << " ";
31 os << "\n";
32 for (auto x : g.b)
33 os << x << " ";
34 os << "\n";
35 }
36 return os;
37 }
38private:
39 int next = 0;
40};
41
42Game play(int n, int a, int b) {
43 if (a + b > n)
44 return Game(1, false);
45
46 Game g(n, true);
47 for (int i = 0; i < n - (a+b); i++)
48 g.play(i+1, i+1);
49 for (int i = 0; i < a; i++)
50 g.play(n-a+i+1, n-(a+b)+i+1);
51 for (int i = 0; i < b; i++)
52 g.play(n-(a+b)+i+1, n-b+i+1);
53
54 if (g.apts != a || g.bpts != b)
55 g.y = false;
56
57 return g;
58}
59
60int main() {
61 int n, a, b, t;
62 std::cin >> t;
63 for (int i = 0; i < t; i++) {
64 std::cin >> n >> a >> b;
65 std::cout << play(n, a, b);
66 }
67}
diff --git a/01_introductory_problems/repetitions_1069.cpp b/01_introductory_problems/repetitions_1069.cpp
new file mode 100644
index 0000000..790f315
--- /dev/null
+++ b/01_introductory_problems/repetitions_1069.cpp
@@ -0,0 +1,20 @@
1#include <algorithm>
2#include <iostream>
3#include <string>
4
5int main() {
6 char cur{'x'};
7 int n{0}, m{0};
8 std::string str;
9 std::cin >> str;
10 for (auto c : str) {
11 if (c == cur) {
12 n++;
13 } else {
14 m = std::max(m, n);
15 n = 1;
16 cur = c;
17 }
18 }
19 std::cout << std::max(m, n) << std::endl;
20}
diff --git a/01_introductory_problems/string_reorder_1743.cpp b/01_introductory_problems/string_reorder_1743.cpp
new file mode 100644
index 0000000..d22041d
--- /dev/null
+++ b/01_introductory_problems/string_reorder_1743.cpp
@@ -0,0 +1,38 @@
1#include <algorithm>
2#include <array>
3#include <iostream>
4#include <iterator>
5#include <sstream>
6#include <string>
7
8int main() {
9 std::array<size_t, 26> a{};
10 std::string s;
11 std::cin >> s;
12 for (auto c : s) a[c-'A']++;
13
14 size_t i{0}, j{1}, tot{s.size()}, c{99};
15 std::stringstream ss{};
16 while (*std::max_element(a.begin(), a.end()) <= tot / 2) {
17 while (a[i] == 0) i++;
18 while (a[j] == 0 || j <= i) j++;
19 c = i == c ? j : i;
20 ss << (char)('A' + c);
21 a[c]--;
22 tot--;
23 }
24
25 j = std::distance(a.begin(), std::max_element(a.begin(), a.end()));
26 while (a[j] > 1) {
27 if (tot == a[j]) {
28 std::cout << "-1\n";
29 return 0;
30 }
31 while (a[i] == 0 || i == j) i++;
32 ss << (char)('A' + j) << (char)('A' + i);
33 a[i]--;
34 a[j]--;
35 tot -= 2;
36 }
37 std::cout << ss.str() << (char)('A' + j) << "\n";
38}
diff --git a/01_introductory_problems/tower_of_hanoi_2165.cpp b/01_introductory_problems/tower_of_hanoi_2165.cpp
new file mode 100644
index 0000000..2b83788
--- /dev/null
+++ b/01_introductory_problems/tower_of_hanoi_2165.cpp
@@ -0,0 +1,17 @@
1#include <iostream>
2
3void do_hanoi(int n, int l, int m, int r) {
4 if (n != 0) {
5 do_hanoi(n-1, l, r, m);
6 std::cout << l << " " << r << "\n";
7 do_hanoi(n-1, m, l, r);
8 }
9}
10
11int main() {
12 int n;
13 std::cin >> n;
14
15 std::cout << (1 << n) - 1 << "\n";
16 do_hanoi(n, 1, 2, 3);
17}
diff --git a/01_introductory_problems/trailing_zeros_1618.cpp b/01_introductory_problems/trailing_zeros_1618.cpp
new file mode 100644
index 0000000..04cf85b
--- /dev/null
+++ b/01_introductory_problems/trailing_zeros_1618.cpp
@@ -0,0 +1,9 @@
1#include <iostream>
2
3int main() {
4 int n, c{0};
5 std::cin >> n;
6 while (n > 0)
7 c += (n /= 5);
8 std::cout << c << std::endl;
9}
diff --git a/01_introductory_problems/two_knights_1072.cpp b/01_introductory_problems/two_knights_1072.cpp
new file mode 100644
index 0000000..15d5f55
--- /dev/null
+++ b/01_introductory_problems/two_knights_1072.cpp
@@ -0,0 +1,24 @@
1#include <iostream>
2#include <vector>
3
4int main() {
5 long long n, a;
6 std::vector<long long> b = {0, 0, 6, 28, 96};
7 std::cin >> n;
8
9 for (long long k = 1; k <= n; k++) {
10 if (k <= 4) {
11 a = b[k];
12 } else {
13 // Both knights in new strip
14 a += (2*k - 1)*(k - 1) - 2;
15
16 // One knight in new strip, one in previous square
17 const long long s = (k-1)*(k-1);
18 a += 5*(s - 2);
19 a += 4*(s - 3);
20 a += (2*k - 10)*(s - 4);
21 }
22 std::cout << a << std::endl;
23 }
24}
diff --git a/01_introductory_problems/two_sets_1092.cpp b/01_introductory_problems/two_sets_1092.cpp
new file mode 100644
index 0000000..4314654
--- /dev/null
+++ b/01_introductory_problems/two_sets_1092.cpp
@@ -0,0 +1,53 @@
1#include <iostream>
2#include <vector>
3
4void printarr(const std::vector<int>& a) {
5 std::cout << a.size() << std::endl;
6 for (auto x : a)
7 std::cout << x << " ";
8 std::cout << std::endl;
9}
10
11int main() {
12 int n;
13 std::cin >> n;
14
15 switch (n % 4) {
16 case 1:
17 case 2:
18 std::cout << "NO\n";
19 break;
20 case 0:
21 std::cout << "YES\n";
22 {
23 std::vector<int> a(n/2), b(n/2);
24 for (int i = 0; i < n/4; i++) {
25 a[2*i] = 4*i+1;
26 a[2*i+1] = 4*i+4;
27 b[2*i] = 4*i+2;
28 b[2*i+1] = 4*i+3;
29 }
30 printarr(a);
31 printarr(b);
32 }
33 break;
34 case 3:
35 std::cout << "YES\n";
36 if (n == 3) {
37 std::cout << "2\n1 2\n1\n3\n";
38 } else {
39 std::vector<int> a(n/2+1), b(n/2);
40 a[0] = 1; a[1] = 2; a[2] = 4; a[3] = 7;
41 b[0] = 3; b[1] = 5; b[2] = 6;
42 for (int i = 1; i < n/4; i++) {
43 a[2*i+2] = 4*i+4;
44 a[2*i+3] = 4*i+7;
45 b[2*i+1] = 4*i+5;
46 b[2*i+2] = 4*i+6;
47 }
48 printarr(a);
49 printarr(b);
50 }
51 break;
52 }
53}
diff --git a/01_introductory_problems/weird_algorithm_1068.cpp b/01_introductory_problems/weird_algorithm_1068.cpp
new file mode 100644
index 0000000..35cbdfa
--- /dev/null
+++ b/01_introductory_problems/weird_algorithm_1068.cpp
@@ -0,0 +1,12 @@
1#include <iostream>
2
3int main() {
4 long long n;
5 std::cin >> n;
6
7 while (n != 1) {
8 std::cout << n << " ";
9 n = (n % 2) ? n * 3 + 1 : n / 2;
10 }
11 std::cout << 1 << std::endl;
12}
diff --git a/02_sorting_and_searching/a.out b/02_sorting_and_searching/a.out
new file mode 100755
index 0000000..1156f0d
--- /dev/null
+++ b/02_sorting_and_searching/a.out
Binary files differ
diff --git a/02_sorting_and_searching/apartments_1084.cpp b/02_sorting_and_searching/apartments_1084.cpp
new file mode 100644
index 0000000..b5ee47f
--- /dev/null
+++ b/02_sorting_and_searching/apartments_1084.cpp
@@ -0,0 +1,27 @@
1#include <algorithm>
2#include <iostream>
3#include <vector>
4
5std::vector<int> readn(int n) {
6 std::vector<int> v(n);
7 for (int i = 0; i < n; i++)
8 std::cin >> v[i];
9 return v;
10}
11
12int main() {
13 int n, m, k;
14 std::cin >> n >> m >> k;
15 auto a = readn(n);
16 auto b = readn(m);
17 std::sort(a.begin(), a.end());
18 std::sort(b.begin(), b.end());
19
20 size_t s{0}, i{0}, j{0};
21 while (i < a.size() && j < b.size()) {
22 if (b[j] > a[i] + k) i++;
23 else if (b[j] < a[i] - k) j++;
24 else { s++; i++; j++; }
25 }
26 std::cout << s << "\n";
27}
diff --git a/02_sorting_and_searching/collecting_numbers_2216.cpp b/02_sorting_and_searching/collecting_numbers_2216.cpp
new file mode 100644
index 0000000..1adcf28
--- /dev/null
+++ b/02_sorting_and_searching/collecting_numbers_2216.cpp
@@ -0,0 +1,46 @@
1#include <iostream>
2#include <vector>
3
4int main() {
5 size_t n, x, s{1}, l{0};
6 std::cin >> n;
7 std::vector<size_t> b(n);
8 for (size_t i = 0; i < n; i++) {
9 std::cin >> x;
10 b[x-1] = i;
11 }
12 for (size_t i = 0; i < n; i++) {
13 s += b[i] < l;
14 l = b[i];
15 }
16 std::cout << s << "\n";
17}
18
19
20// The code below solves a different problem: it finds the minimum number
21// of ascending chains needed to partition the given list of numbers.
22
23#if 0
24
25#include <algorithm>
26#include <iostream>
27#include <vector>
28
29int main() {
30 size_t n;
31 std::vector<size_t> s;
32 std::cin >> n;
33 for (size_t i = 0; i < n; i++) {
34 size_t x;
35 std::cin >> x;
36 auto it = std::lower_bound(
37 s.begin(), s.end(), x, std::greater<size_t>());
38 if (it != s.end())
39 *it = x;
40 else
41 s.push_back(x);
42 }
43 std::cout << s.size() << std::endl;
44}
45
46#endif
diff --git a/02_sorting_and_searching/concert_tickets_1091.cpp b/02_sorting_and_searching/concert_tickets_1091.cpp
new file mode 100644
index 0000000..20333a6
--- /dev/null
+++ b/02_sorting_and_searching/concert_tickets_1091.cpp
@@ -0,0 +1,25 @@
1#include <algorithm>
2#include <iostream>
3#include <set>
4#include <vector>
5
6int main() {
7 size_t n, m;
8 std::cin >> n >> m;
9 std::vector<int> hv(n), t(m);
10 for (size_t i = 0; i < n; i++)
11 std::cin >> hv[i];
12 for (size_t i = 0; i < m; i++)
13 std::cin >> t[i];
14
15 std::multiset<int, std::greater<int>> h(hv.begin(), hv.end());
16
17 for (auto c : t) {
18 if (auto x = h.lower_bound(c); x == h.end()) {
19 std::cout << "-1\n";
20 } else {
21 std::cout << *x << "\n";
22 h.erase(x);
23 }
24 }
25}
diff --git a/02_sorting_and_searching/distinct_numbers_1621.cpp b/02_sorting_and_searching/distinct_numbers_1621.cpp
new file mode 100644
index 0000000..9c39aa3
--- /dev/null
+++ b/02_sorting_and_searching/distinct_numbers_1621.cpp
@@ -0,0 +1,13 @@
1#include <iostream>
2#include <set>
3
4int main() {
5 int n, x;
6 std::set<int> s;
7 std::cin >> n;
8 for (int i = 0; i < n; i++) {
9 std::cin >> x;
10 s.insert(x);
11 }
12 std::cout << s.size() << "\n";
13}
diff --git a/02_sorting_and_searching/ferris_wheel_1090.cpp b/02_sorting_and_searching/ferris_wheel_1090.cpp
new file mode 100644
index 0000000..f64b33b
--- /dev/null
+++ b/02_sorting_and_searching/ferris_wheel_1090.cpp
@@ -0,0 +1,17 @@
1#include <algorithm>
2#include <iostream>
3#include <vector>
4
5int main() {
6 int n, x;
7 std::cin >> n >> x;
8 std::vector<int> a(n);
9 for (int i = 0; i < n; i++)
10 std::cin >> a[i];
11 std::sort(a.begin(), a.end());
12 size_t i{0}, j{a.size()-1}, s{0};
13 for (; j > i; j--, s++)
14 i += a[i] + a[j] <= x;
15 if (i == j) s++;
16 std::cout << s << "\n";
17}
diff --git a/02_sorting_and_searching/maximum_subarray_sum_1643.cpp b/02_sorting_and_searching/maximum_subarray_sum_1643.cpp
new file mode 100644
index 0000000..24ac320
--- /dev/null
+++ b/02_sorting_and_searching/maximum_subarray_sum_1643.cpp
@@ -0,0 +1,19 @@
1#include <algorithm>
2#include <iostream>
3#include <vector>
4
5int main() {
6 size_t n;
7 std::cin >> n;
8 std::vector<long long> a(n);
9 for (size_t i = 0; i < n; i++)
10 std::cin >> a[i];
11
12 long long scur{0}, smax{0};
13 for (size_t j = 0; j < n; j++) {
14 scur = std::max(0LL, scur + a[j]);
15 smax = std::max(smax, scur);
16 }
17 if (smax == 0) smax = *std::max_element(a.begin(), a.end());
18 std::cout << smax << "\n";
19}
diff --git a/02_sorting_and_searching/missing_coin_sum_2183.cpp b/02_sorting_and_searching/missing_coin_sum_2183.cpp
new file mode 100644
index 0000000..ed7a74b
--- /dev/null
+++ b/02_sorting_and_searching/missing_coin_sum_2183.cpp
@@ -0,0 +1,16 @@
1#include <algorithm>
2#include <iostream>
3#include <vector>
4
5int main() {
6 size_t n, s{1};
7 std::cin >> n;
8 std::vector<size_t> a(n);
9 for (size_t i = 0; i < n; i++)
10 std::cin >> a[i];
11 std::sort(a.begin(), a.end());
12 for (auto c : a)
13 if (s < c) break;
14 else s+= c;
15 std::cout << s << std::endl;
16}
diff --git a/02_sorting_and_searching/movie_festival_1629.cpp b/02_sorting_and_searching/movie_festival_1629.cpp
new file mode 100644
index 0000000..4ec1fca
--- /dev/null
+++ b/02_sorting_and_searching/movie_festival_1629.cpp
@@ -0,0 +1,21 @@
1#include <algorithm>
2#include <iostream>
3#include <vector>
4
5int main() {
6 size_t n;
7 std::cin >> n;
8 std::vector<std::pair<int, int>> v(n);
9 for (size_t i = 0; i < n; i++)
10 std::cin >> v[i].first >> v[i].second;
11 std::sort(v.begin(), v.end());
12 int e{-1}, s{0};
13 for (auto a : v) {
14 if (a.first >= e) {
15 e = a.second;
16 s++;
17 }
18 e = std::min(e, a.second);
19 }
20 std::cout << s << "\n";
21}
diff --git a/02_sorting_and_searching/playlist_1141.cpp b/02_sorting_and_searching/playlist_1141.cpp
new file mode 100644
index 0000000..ff963f7
--- /dev/null
+++ b/02_sorting_and_searching/playlist_1141.cpp
@@ -0,0 +1,22 @@
1#include <algorithm>
2#include <iostream>
3#include <map>
4#include <vector>
5
6int main() {
7 size_t n;
8 std::cin >> n;
9 std::vector<int> v(n);
10 for (size_t i = 0; i < n; i++)
11 std::cin >> v[i];
12
13 size_t l{0}, s{0};
14 std::map<int, size_t> m;
15 for (size_t r = 0; r < n; r++) {
16 if (m.contains(v[r]))
17 l = std::max(l, m.at(v[r])+1);
18 m[v[r]] = r;
19 s = std::max(s, r-l+1);
20 }
21 std::cout << s << "\n";
22}
diff --git a/02_sorting_and_searching/restaurant_customers_1619.cpp b/02_sorting_and_searching/restaurant_customers_1619.cpp
new file mode 100644
index 0000000..8d97e96
--- /dev/null
+++ b/02_sorting_and_searching/restaurant_customers_1619.cpp
@@ -0,0 +1,24 @@
1#include <algorithm>
2#include <iostream>
3#include <queue>
4#include <vector>
5
6int main() {
7 size_t n;
8 std::cin >> n;
9 std::vector<std::pair<int, int>> c(n);
10 for (size_t i = 0; i < n; i++) {
11 int a, b;
12 std::cin >> a >> b;
13 c[i] = {a, b};
14 }
15 std::sort(c.begin(), c.end());
16 std::priority_queue<int, std::vector<int>, std::greater<int>> q;
17 size_t m{0};
18 for (auto d : c) {
19 while (!q.empty() && q.top() < d.first) q.pop();
20 q.push(d.second);
21 m = std::max(m, q.size());
22 }
23 std::cout << m << "\n";
24}
diff --git a/02_sorting_and_searching/room_allocation_1164.cpp b/02_sorting_and_searching/room_allocation_1164.cpp
new file mode 100644
index 0000000..f79cc96
--- /dev/null
+++ b/02_sorting_and_searching/room_allocation_1164.cpp
@@ -0,0 +1,38 @@
1#include <algorithm>
2#include <iostream>
3#include <queue>
4#include <tuple>
5#include <vector>
6
7int main() {
8 int n;
9 std::vector<std::tuple<int, int, int>> v;
10 std::cin >> n;
11 for (int i = 0; i < n; i++) {
12 int a, b;
13 std::cin >> a >> b;
14 v.push_back({a, b, i});
15 }
16 std::sort(v.begin(), v.end());
17
18 using P = std::pair<int, int>;
19 std::priority_queue<P, std::vector<P>, std::greater<>> r;
20 std::vector<int> al(n);
21 for (auto [a, d, i] : v) {
22 int ind = r.size()+1;
23 if (!r.empty()) {
24 auto [x, j] = r.top();
25 if (a > x) {
26 r.pop();
27 ind = j;
28 }
29 }
30 r.push({d, ind});
31 al[i] = ind;
32 }
33
34 std::cout << r.size() << "\n";
35 for (auto i : al)
36 std::cout << i << " ";
37 std::cout << "\n";
38}
diff --git a/02_sorting_and_searching/stick_lengths_1074.cpp b/02_sorting_and_searching/stick_lengths_1074.cpp
new file mode 100644
index 0000000..e41a7d8
--- /dev/null
+++ b/02_sorting_and_searching/stick_lengths_1074.cpp
@@ -0,0 +1,16 @@
1#include <algorithm>
2#include <iostream>
3#include <vector>
4
5int main() {
6 long long n;
7 std::cin >> n;
8 std::vector<long long> a(n);
9 for (long long i = 0; i < n; i++)
10 std::cin >> a[i];
11 std::sort(a.begin(), a.end());
12 long long s{0}, t{a[n/2]};
13 for (auto x : a)
14 s += std::abs(x-t);
15 std::cout << s << "\n";
16}
diff --git a/02_sorting_and_searching/sum_of_two_values_1640.cpp b/02_sorting_and_searching/sum_of_two_values_1640.cpp
new file mode 100644
index 0000000..75b0f54
--- /dev/null
+++ b/02_sorting_and_searching/sum_of_two_values_1640.cpp
@@ -0,0 +1,27 @@
1#include <algorithm>
2#include <iostream>
3#include <vector>
4
5int main() {
6 int n, x;
7 std::cin >> n >> x;
8 std::vector<std::pair<int, int>> a(n);
9 for (int i = 0; i < n; i++) {
10 std::cin >> a[i].first;
11 a[i].second = i;
12 }
13 std::sort(a.begin(), a.end());
14
15 int i{0}, j{n-1};
16 while (i < j) {
17 auto [ai, ii] = a[i];
18 auto [aj, ij] = a[j];
19 if (ai + aj < x) i++;
20 else if (ai + aj > x) j--;
21 else {
22 std::cout << ii+1 << " " << ij+1 << "\n";
23 return 0;
24 }
25 }
26 std::cout << "IMPOSSIBLE\n";
27}
diff --git a/02_sorting_and_searching/towers_1063.cpp b/02_sorting_and_searching/towers_1063.cpp
new file mode 100644
index 0000000..b0656f3
--- /dev/null
+++ b/02_sorting_and_searching/towers_1063.cpp
@@ -0,0 +1,17 @@
1#include <algorithm>
2#include <iostream>
3#include <vector>
4
5int main() {
6 size_t n;
7 std::cin >> n;
8 std::vector<int> v;
9 for (size_t i = 0; i < n; i++) {
10 int x;
11 std::cin >> x;
12 auto it = std::upper_bound(v.begin(), v.end(), x);
13 if (it == v.end()) v.push_back(x);
14 else *it = x;
15 }
16 std::cout << v.size() << "\n";
17}
diff --git a/03_dynamic_programming/a.out b/03_dynamic_programming/a.out
new file mode 100755
index 0000000..f4fc9b1
--- /dev/null
+++ b/03_dynamic_programming/a.out
Binary files differ
diff --git a/03_dynamic_programming/coin_combinations_i_1635.cpp b/03_dynamic_programming/coin_combinations_i_1635.cpp
new file mode 100644
index 0000000..696c1f6
--- /dev/null
+++ b/03_dynamic_programming/coin_combinations_i_1635.cpp
@@ -0,0 +1,25 @@
1#include <iostream>
2#include <vector>
3
4static constexpr int mod = 1000000007;
5static constexpr int X = 1000001;
6
7int f(const std::vector<int>& c, std::vector<int>& a, int x) {
8 if (x < 0) return 0;
9 if (a[x] != -1) return a[x];
10 if (x == 0) return a[x] = 1;
11
12 a[x] = 0;
13 for (auto m : c)
14 a[x] = (a[x] + f(c, a, x-m)) % mod;
15 return a[x];
16}
17
18int main() {
19 int n, x;
20 std::cin >> n >> x;
21 std::vector<int> c(n), a(X, -1);
22 for (int i = 0; i < n; i++)
23 std::cin >> c[i];
24 std::cout << f(c, a, x) << "\n";
25}
diff --git a/03_dynamic_programming/coin_combinations_ii_1636.cpp b/03_dynamic_programming/coin_combinations_ii_1636.cpp
new file mode 100644
index 0000000..75642da
--- /dev/null
+++ b/03_dynamic_programming/coin_combinations_ii_1636.cpp
@@ -0,0 +1,28 @@
1#include <iostream>
2#include <map>
3#include <vector>
4
5static constexpr int mod = 1000000007;
6static constexpr int X = 1000001;
7
8int main() {
9 int n, x;
10 std::cin >> n >> x;
11 std::vector<int> c(n);
12 for (int i = 0; i < n; i++)
13 std::cin >> c[i];
14
15 std::vector<std::vector<int>> a(n, std::vector<int>(X, 0));
16 for (int i = 0; i < (int)c.size(); i++) a[i][0] = 1;
17 for (int j = c.back(); j <= x; j += c.back()) a[c.size()-1][j] = 1;
18 for (int i = c.size()-2; i >= 0; i--) {
19 for (int j = 1; j <= x; j++) {
20 a[i][j] = a[i+1][j];
21 if (j >= c[i]) {
22 a[i][j] += a[i][j-c[i]];
23 a[i][j] %= mod;
24 }
25 }
26 }
27 std::cout << a[0][x] << "\n";
28}
diff --git a/03_dynamic_programming/counting_towers_2413.cpp b/03_dynamic_programming/counting_towers_2413.cpp
new file mode 100644
index 0000000..902956b
--- /dev/null
+++ b/03_dynamic_programming/counting_towers_2413.cpp
@@ -0,0 +1,38 @@
1#include <iostream>
2#include <vector>
3
4// Recurrence relation:
5// f(n) = sum over i from 0 to n-1 of f(i) * p(n-i)
6// where p(n) is the number of indivisible towers of height n,
7// which is easily seen to be 3^(n-1)+1.
8// Then we can expand:
9// f(n) = sum_{i=0}^{n-1} f(i)(3^{n-i-1}+1) = g(n) + h(n)
10// where we define g(n) = sum f(i)3^{n-i-1} and h(n) = sum f(i).
11// Then it's easy to see that:
12// g(n+1) = f(n) + 3g(n)
13// h(n+1) = f(n) + h(n)
14// Initial values are h(1) = 1 and g(1) = 1.
15
16constexpr size_t mod{1000000007};
17constexpr size_t maxn{1000001};
18std::vector<size_t> f(maxn);
19std::vector<size_t> g(maxn);
20std::vector<size_t> h(maxn);
21
22int main() {
23 g[1] = h[1] = 1;
24 f[1] = 2;
25 for (size_t i = 2; i < maxn; i++) {
26 g[i] = (f[i-1] + 3*g[i-1]) % mod;
27 h[i] = (f[i-1] + h[i-1]) % mod;
28 f[i] = (g[i] + h[i]) % mod;
29 }
30
31 size_t t;
32 std::cin >> t;
33 for (size_t i = 0; i < t; i++) {
34 size_t n;
35 std::cin >> n;
36 std::cout << f[n] << "\n";
37 }
38}
diff --git a/03_dynamic_programming/dice_combinations_1633.cpp b/03_dynamic_programming/dice_combinations_1633.cpp
new file mode 100644
index 0000000..4e76d1d
--- /dev/null
+++ b/03_dynamic_programming/dice_combinations_1633.cpp
@@ -0,0 +1,19 @@
1#include <algorithm>
2#include <array>
3#include <iostream>
4
5// We use a funny memory optimization: we only store the last 7 values.
6
7int main() {
8 constexpr unsigned mod = 1e9+7;
9 int n;
10 std::cin >> n;
11 std::array<int, 7> v{0};
12 v[0] = 1;
13 for (int i = 1; i <= n; i++) {
14 v[i%7] = 0;
15 for (int j = std::max(0, i-6); j < i; j++)
16 v[i%7] = (v[i%7]+v[j%7]) % mod;
17 }
18 std::cout << v[n%7] << "\n";
19}
diff --git a/03_dynamic_programming/edit_distance_1639.cpp b/03_dynamic_programming/edit_distance_1639.cpp
new file mode 100644
index 0000000..0d8c6ef
--- /dev/null
+++ b/03_dynamic_programming/edit_distance_1639.cpp
@@ -0,0 +1,22 @@
1#include <algorithm>
2#include <iostream>
3#include <string>
4#include <vector>
5
6int d(const std::string& a, const std::string& b, size_t i, size_t j,
7 std::vector<std::vector<int>>& t) {
8 if (t[i][j] != -1) return t[i][j];
9 if (i == a.size()) return t[i][j] = b.size()-j;
10 if (j == b.size()) return t[i][j] = a.size()-i;
11 if (a[i] == b[j]) return t[i][j] = d(a, b, i+1, j+1, t);
12 return t[i][j] = 1+std::min(d(a, b, i+1, j+1, t),
13 std::min(d(a, b, i+1, j, t), d(a, b, i, j+1, t)));
14}
15
16int main() {
17 std::string a, b;
18 std::cin >> a >> b;
19 std::vector<std::vector<int>>
20 t(a.size()+1, std::vector<int>(b.size()+1, -1));
21 std::cout << d(a, b, 0, 0, t) << "\n";
22}
diff --git a/03_dynamic_programming/longest_common_subsequence_3403.cpp b/03_dynamic_programming/longest_common_subsequence_3403.cpp
new file mode 100644
index 0000000..ca94722
--- /dev/null
+++ b/03_dynamic_programming/longest_common_subsequence_3403.cpp
@@ -0,0 +1,44 @@
1#include <algorithm>
2#include <iostream>
3#include <vector>
4
5int f(const std::vector<int>& a, const std::vector<int>& b, size_t i, size_t j,
6 std::vector<std::vector<int>>& t) {
7 if (i == a.size() || j == b.size()) return t[i][j] = 0;
8 if (t[i][j] != -1) return t[i][j];
9 if (a[i] == b[j]) return t[i][j] = 1+f(a, b, i+1, j+1, t);
10 return t[i][j] = std::max(f(a, b, i+1, j, t), f(a, b, i, j+1, t));
11}
12
13std::vector<int> read(size_t n) {
14 std::vector<int> a(n);
15 for (size_t i = 0; i < n; i++)
16 std::cin >> a[i];
17 return a;
18}
19
20int main() {
21 std::size_t n, m;
22 std::cin >> n >> m;
23 std::vector<int> a = read(n);
24 std::vector<int> b = read(m);
25 std::vector<std::vector<int>> t(n+1, std::vector<int>(m+1, -1));
26 int x = f(a, b, 0, 0, t);
27 std::cout << x << "\n";
28
29 std::vector<int> s;
30 size_t i{0}, j{0};
31 while (x > 0) {
32 if (a[i] == b[j]) {
33 s.push_back(a[i]);
34 i++; j++; x--;
35 } else {
36 if (t[i+1][j] == x) i++;
37 else j++;
38 }
39 }
40
41 for (auto x : s)
42 std::cout << x << " ";
43 std::cout << "\n";
44}
diff --git a/03_dynamic_programming/minimizing_coins_1634.cpp b/03_dynamic_programming/minimizing_coins_1634.cpp
new file mode 100644
index 0000000..f6189da
--- /dev/null
+++ b/03_dynamic_programming/minimizing_coins_1634.cpp
@@ -0,0 +1,33 @@
1#include <algorithm>
2#include <iostream>
3#include <queue>
4#include <vector>
5
6int f(const std::vector<int>& c, int x) {
7 static constexpr int max = 999999999;
8 std::vector<int> a(x+1, max);
9 std::queue<int> q;
10 a[0] = 0;
11 q.push(0);
12 while (!q.empty()) {
13 auto i = q.front();
14 q.pop();
15 for (auto k : c) {
16 if (i + k > x || a[i+k] <= a[i]+1) continue;
17 if (i + k == x) return a[i] + 1;
18 a[i+k] = a[i] + 1;
19 q.push(i + k);
20 }
21 }
22 return -1;
23}
24
25int main() {
26 int n, x;
27 std::cin >> n >> x;
28 std::vector<int> c(n);
29 for (int i = 0; i < n; i++)
30 std::cin >> c[i];
31
32 std::cout << f(c, x) << "\n";
33}
diff --git a/03_dynamic_programming/removing_digits_1637.cpp b/03_dynamic_programming/removing_digits_1637.cpp
new file mode 100644
index 0000000..8b5b334
--- /dev/null
+++ b/03_dynamic_programming/removing_digits_1637.cpp
@@ -0,0 +1,28 @@
1#include <algorithm>
2#include <iostream>
3#include <vector>
4
5static constexpr int inf = 1999999999;
6
7std::vector<int> digits(int n) {
8 std::vector<int> d;
9 for (int i = n; i != 0; i /= 10)
10 d.push_back(i % 10);
11 return d;
12}
13
14int f(std::vector<int>& a, int n) {
15 if (a[n] != inf) return a[n];
16 for (auto d : digits(n))
17 if (d != 0)
18 a[n] = std::min(a[n], 1+f(a, n-d));
19 return a[n];
20}
21
22int main() {
23 int n;
24 std::cin >> n;
25 std::vector<int> a(n+1, inf);
26 a[0] = 0;
27 std::cout << f(a, n) << "\n";
28}
diff --git a/04_graph_algorithms/a.out b/04_graph_algorithms/a.out
new file mode 100755
index 0000000..ae515d4
--- /dev/null
+++ b/04_graph_algorithms/a.out
Binary files differ
diff --git a/04_graph_algorithms/building_roads_1666.cpp b/04_graph_algorithms/building_roads_1666.cpp
new file mode 100644
index 0000000..cf6ac28
--- /dev/null
+++ b/04_graph_algorithms/building_roads_1666.cpp
@@ -0,0 +1,32 @@
1#include <iostream>
2#include <vector>
3
4void visit(size_t i, const std::vector<std::vector<size_t>>& a,
5 std::vector<bool>& c) {
6 if (c[i]) return;
7 c[i] = true;
8 for (auto j : a[i])
9 visit(j, a, c);
10}
11
12int main() {
13 size_t n, m;
14 std::cin >> n >> m;
15 std::vector<std::vector<size_t>> a(n);
16 for (size_t i = 0; i < m; i++) {
17 size_t x, y;
18 std::cin >> x >> y;
19 a[x-1].push_back(y-1);
20 a[y-1].push_back(x-1);
21 }
22
23 std::vector<bool> c(n, false);
24 std::vector<size_t> s;
25 for (size_t i = 0; i < n; i++) {
26 if (c[i]) continue;
27 if (i != 0) s.push_back(i);
28 visit(i, a, c);
29 }
30 std::cout << s.size() << "\n";
31 for (auto x : s) std::cout << "1 " << x+1 << "\n";
32}
diff --git a/04_graph_algorithms/building_teams_1668.cpp b/04_graph_algorithms/building_teams_1668.cpp
new file mode 100644
index 0000000..c98e14d
--- /dev/null
+++ b/04_graph_algorithms/building_teams_1668.cpp
@@ -0,0 +1,37 @@
1#include <iostream>
2#include <vector>
3
4bool visit(size_t i, int c, const std::vector<std::vector<size_t>>& a,
5 std::vector<int>& t) {
6 if (t[i] != 0) return true;
7 t[i] = c;
8 for (auto j : a[i])
9 if (t[j] == c)
10 return false;
11 else if (!visit(j, 3-c, a, t)) return false;
12 return true;
13}
14
15int main() {
16 size_t n, m;
17 std::cin >> n >> m;
18 std::vector<std::vector<size_t>> a(n);
19 for (size_t i = 0; i < m; i++) {
20 size_t x, y;
21 std::cin >> x >> y;
22 a[x-1].push_back(y-1);
23 a[y-1].push_back(x-1);
24 }
25
26 std::vector<int> t(n);
27 for (size_t i = 0; i < n; i++) {
28 if (t[i] == 0) {
29 if (!visit(i, 1, a, t)) {
30 std::cout << "IMPOSSIBLE\n";
31 return 0;
32 }
33 }
34 }
35 for (auto x : t) std::cout << x << " ";
36 std::cout << "\n";
37}
diff --git a/04_graph_algorithms/counting_rooms_1192.cpp b/04_graph_algorithms/counting_rooms_1192.cpp
new file mode 100644
index 0000000..dc71529
--- /dev/null
+++ b/04_graph_algorithms/counting_rooms_1192.cpp
@@ -0,0 +1,62 @@
1#include <iostream>
2#include <string>
3#include <vector>
4
5class Tile {
6public:
7 int i;
8 int j;
9 std::vector<Tile> neighbors() const {
10 return {Tile{i-1,j}, Tile{i+1,j}, Tile{i,j-1}, Tile{i,j+1}};
11 }
12};
13
14class Map {
15public:
16 int n;
17 int m;
18
19 Map(int i, int j) : n{i}, m{j}, c(n*m, 0) {}
20 int color(Tile t) const { return inbound(t) ? c[ind(t)] : -1; }
21 void setcolor(Tile t, int k) { if (inbound(t)) c[ind(t)] = k; }
22 bool wall(Tile t) const { return !inbound(t) || c[ind(t)] == -1; }
23 void setwall(Tile t) { if (inbound(t)) setcolor(t, -1); }
24private:
25 std::vector<int> c;
26
27 size_t ind(Tile t) const { return m*t.i + t.j; }
28 bool inbound(Tile t) const {
29 return t.i >= 0 && t.i < n && t.j >= 0 && t.j < m;
30 }
31};
32
33Map readmap() {
34 int n, m;
35 std::string s;
36 std::cin >> n >> m;
37 Map map(n, m);
38 for (int i = 0; i < n; i++) {
39 std::cin >> s;
40 for (int j = 0; j < m; j++)
41 if (s[j] == '#')
42 map.setwall(Tile{i, j});
43 }
44 return map;
45}
46
47void visit(Map& m, Tile t, int c) {
48 m.setcolor(t, c);
49 for (auto u : t.neighbors())
50 if (m.color(u) == 0)
51 visit(m, u, c);
52}
53
54int main() {
55 auto m = readmap();
56 int c{0};
57 for (int i = 0; i < m.n; i++)
58 for (int j = 0; j < m.m; j++)
59 if (m.color(Tile{i, j}) == 0)
60 visit(m, Tile{i, j}, ++c);
61 std::cout << c << "\n";
62}
diff --git a/04_graph_algorithms/high_score_1673.cpp b/04_graph_algorithms/high_score_1673.cpp
new file mode 100644
index 0000000..c327ba0
--- /dev/null
+++ b/04_graph_algorithms/high_score_1673.cpp
@@ -0,0 +1,61 @@
1#include <algorithm>
2#include <iostream>
3#include <tuple>
4#include <vector>
5
6constexpr long long inf = 999999999999999LL;
7
8size_t findcycle(
9 size_t v,
10 const std::vector<std::tuple<size_t, size_t, long long>>& a,
11 const std::vector<size_t>& p
12) {
13 std::vector<bool> visited(p.size(), false);
14 visited[v] = true;
15 size_t u = p[v];
16 while (!visited[u]) {
17 visited[u] = true;
18 u = p[u];
19 }
20 return u;
21}
22
23int main() {
24 size_t n, m;
25 std::cin >> n >> m;
26 std::vector<std::tuple<size_t, size_t, long long>> a(m);
27 for (size_t i = 0; i < m; i++) {
28 size_t x, y;
29 long long w;
30 std::cin >> x >> y >> w;
31 a[i] = {x-1, y-1, w};
32 }
33
34 std::vector<size_t> p(n, n);
35 std::vector<long long> d(n, -inf);
36 d[0] = 0;
37 std::vector<bool> reach_1(n, false), reach_n(n, false);
38 reach_1[0] = reach_n[n-1] = true;
39 for (size_t i = 0; i < n; i++) {
40 for (auto [v, u, w] : a) {
41 if (d[u] < d[v] + w) {
42 d[u] = d[v] + w;
43 p[u] = v;
44 }
45 reach_n[v] = reach_n[v] || reach_n[u];
46 reach_1[u] = reach_1[u] || reach_1[v];
47 }
48 }
49
50 for (auto [v, u, w] : a) {
51 if (d[u] < d[v] + w) {
52 size_t x = findcycle(u, a, p);
53 if (reach_1[x] && reach_n[x]) {
54 std::cout << "-1\n";
55 return 0;
56 }
57 }
58 }
59
60 std::cout << d[n-1] << "\n";
61}
diff --git a/04_graph_algorithms/labyrinth_1193.cpp b/04_graph_algorithms/labyrinth_1193.cpp
new file mode 100644
index 0000000..30f8c0b
--- /dev/null
+++ b/04_graph_algorithms/labyrinth_1193.cpp
@@ -0,0 +1,131 @@
1#include <iostream>
2#include <queue>
3#include <ranges>
4#include <string>
5#include <tuple>
6#include <vector>
7
8struct Pos {
9 size_t i;
10 size_t j;
11
12 Pos(size_t a = 0, size_t b = 0) : i{a}, j{b} {}
13 bool operator==(const Pos& p) const { return i == p.i && j == p.j; }
14
15 std::vector<Pos> neighbors() const {
16 return {Pos(i+1, j), Pos(i-1, j), Pos(i, j+1), Pos(i, j-1)};
17 }
18
19 char dir(const Pos& p) const {
20 if (p.i == i+1 && p.j == j) return 'D';
21 if (p.i == i-1 && p.j == j) return 'U';
22 if (p.i == i && p.j == j+1) return 'R';
23 if (p.i == i && p.j == j-1) return 'L';
24 return 'X';
25 }
26};
27
28class Map {
29public:
30 Map(size_t i, size_t j) : n{i}, m{j}, v(n, std::vector<bool>(m)) {}
31 Pos start() const { return a; }
32 Pos finish() const { return b; }
33 bool operator[](Pos p) const { return inb(p) && v[p.i][p.j]; }
34
35 friend std::istream& operator>>(std::istream& is, Map& map) {
36 std::string s;
37 is >> s;
38 for (size_t j = 0; j < map.m; j++)
39 map.readchar(s[j], map.l, j);
40 map.l++;
41 return is;
42 }
43
44 friend std::ostream& operator<<(std::ostream& os, const Map& map) {
45 for (size_t i = 0; i < map.n; i++) {
46 for (size_t j = 0; j < map.m; j++) {
47 if (map.a == Pos(i, j)) os << 'A';
48 else if (map.b == Pos(i, j)) os << 'B';
49 else os << (map.v[i][j] ? '.' : '#');
50 }
51 os << "\n";
52 }
53 return os;
54 }
55
56 template<typename T>
57 using Overlay = std::pair<T, std::vector<std::vector<T>>>;
58
59 template<typename T>
60 Overlay<T> overlay(T t) const {
61 auto ov = std::vector<std::vector<T>>(n, std::vector(m, t));
62 return {t, ov};
63 }
64
65 template<typename T>
66 T at(const Overlay<T>& ov, Pos p) const {
67 return inb(p) ? ov.second[p.i][p.j] : ov.first;
68 }
69
70 template<typename T>
71 void set(Overlay<T>& ov, Pos p, T val) const {
72 if (inb(p)) ov.second[p.i][p.j] = val;
73 }
74private:
75 size_t l{0};
76 size_t n;
77 size_t m;
78 Pos a;
79 Pos b;
80 std::vector<std::vector<bool>> v;
81
82 void readchar(char c, size_t i, size_t j) {
83 v[i][j] = c != '#';
84 if (c == 'A') a = {i, j};
85 if (c == 'B') b = {i, j};
86 }
87
88 bool inb(Pos p) const { return p.i < n && p.j < m; }
89};
90
91int main() {
92 size_t n, m;
93 std::cin >> n >> m;
94 Map map(n, m);
95 for (size_t i = 0; i < n; i++)
96 std::cin >> map;
97
98 constexpr size_t inf{999999999};
99 auto d = map.overlay<size_t>(inf);
100 std::queue<std::pair<Pos, size_t>> q;
101 q.push({map.start(), 0});
102 while (!q.empty()) {
103 auto [p, w] = q.front();
104 q.pop();
105 if (!map[p] || map.at(d, p) != inf) continue;
106 map.set(d, p, w);
107 for (auto x : p.neighbors()) q.push({x, w+1});
108 }
109
110 if (map.at(d, map.finish()) == inf) {
111 std::cout << "NO\n";
112 } else {
113 std::cout << "YES\n" << map.at(d, map.finish()) << "\n";
114
115 // Backtrack
116 Pos p = map.finish();
117 std::vector<char> path;
118 do {
119 for (auto x : p.neighbors()) {
120 if (map.at(d, x) == map.at(d, p)-1) {
121 path.push_back(x.dir(p));
122 p = x;
123 break;
124 }
125 }
126 } while (p != map.start());
127 for (auto c : path | std::views::reverse)
128 std::cout << c;
129 std::cout << "\n";
130 }
131}
diff --git a/04_graph_algorithms/message_route_1667.cpp b/04_graph_algorithms/message_route_1667.cpp
new file mode 100644
index 0000000..280f7d6
--- /dev/null
+++ b/04_graph_algorithms/message_route_1667.cpp
@@ -0,0 +1,54 @@
1#include <iostream>
2#include <queue>
3#include <ranges>
4#include <vector>
5
6constexpr size_t inf = 1999999999;
7
8int main() {
9 size_t n, m;
10 std::cin >> n >> m;
11 std::vector<std::vector<size_t>> a(n);
12 for (size_t i = 0; i < m; i++) {
13 size_t x, y;
14 std::cin >> x >> y;
15 a[x-1].push_back(y-1);
16 a[y-1].push_back(x-1);
17 }
18
19 std::queue<size_t> q;
20 std::vector<size_t> d(n, inf);
21 d[0] = 0;
22 q.push(0);
23 while (!q.empty()) {
24 auto i = q.front();
25 q.pop();
26 if (i == n-1) break;
27 for (auto j : a[i]) {
28 if (d[j] > d[i]+1) {
29 d[j] = d[i] + 1;
30 q.push(j);
31 }
32 }
33 }
34
35 if (d[n-1] == inf) {
36 std::cout << "IMPOSSIBLE\n";
37 } else {
38 std::cout << d[n-1]+1 << "\n";
39 // Backtracking
40 std::vector<size_t> v;
41 v.push_back(n-1);
42 while (v.back() != 0) {
43 for (auto j : a[v.back()]) {
44 if (d[j] == d[v.back()]-1) {
45 v.push_back(j);
46 break;
47 }
48 }
49 }
50 for (auto x : v | std::views::reverse)
51 std::cout << x+1 << " ";
52 std::cout << "\n";
53 }
54}
diff --git a/04_graph_algorithms/round_trip_1669.cpp b/04_graph_algorithms/round_trip_1669.cpp
new file mode 100644
index 0000000..c19b29d
--- /dev/null
+++ b/04_graph_algorithms/round_trip_1669.cpp
@@ -0,0 +1,44 @@
1#include <iostream>
2#include <vector>
3
4std::vector<int> cyc;
5
6int dfs(const std::vector<std::vector<int>>& a,
7 std::vector<bool>& v, int i, int p) {
8 v[i] = true;
9 for (auto x : a.at(i)) {
10 if (x == p) continue;
11 if (v.at(x)) {
12 cyc.push_back(x);
13 cyc.push_back(i);
14 return x;
15 }
16 if (int r = dfs(a, v, x, i); r != 0) {
17 cyc.push_back(i);
18 if (r == i) {
19 std::cout << cyc.size() << "\n";
20 for (auto y : cyc) std::cout << y << " ";
21 std::cout << "\n";
22 exit(0);
23 } else return r;
24 }
25 }
26 return 0;
27}
28
29int main() {
30 int n, m;
31 std::cin >> n >> m;
32 std::vector<std::vector<int>> a(n+1);
33 for (int i = 0; i < m; i++) {
34 int x, y;
35 std::cin >> x >> y;
36 a[x].push_back(y);
37 a[y].push_back(x);
38 }
39 std::vector<bool> v(n+1);
40 for (int i = 1; i <= n; i++)
41 if (!v.at(i))
42 dfs(a, v, i, 0);
43 std::cout << "IMPOSSIBLE\n";
44}
diff --git a/04_graph_algorithms/shortest_routes_i_1671.cpp b/04_graph_algorithms/shortest_routes_i_1671.cpp
new file mode 100644
index 0000000..89f675d
--- /dev/null
+++ b/04_graph_algorithms/shortest_routes_i_1671.cpp
@@ -0,0 +1,43 @@
1#include <iostream>
2#include <queue>
3#include <utility>
4#include <vector>
5
6class dvpair {
7public:
8 size_t d;
9 size_t v;
10 auto operator<=>(const dvpair& p) const { return p.d <=> d; }
11};
12
13int main() {
14 size_t n, m;
15 std::cin >> n >> m;
16 std::vector<std::vector<std::pair<size_t, size_t>>> a(n);
17 for (size_t i = 0; i < m; i++) {
18 size_t x, y, z;
19 std::cin >> x >> y >> z;
20 a[x-1].push_back({y-1, z});
21 }
22
23 constexpr size_t inf{999999999999999ULL};
24 std::vector<size_t> d(n, inf);
25 std::priority_queue<dvpair> q;
26 d[0] = 0;
27 q.push({0, 0});
28 while (!q.empty()) {
29 auto [dd, p] = q.top();
30 q.pop();
31 if (dd > d[p])
32 continue;
33 for (auto [r, w] : a[p]) {
34 if (w + d[p] < d[r]) {
35 d[r] = d[p] + w;
36 q.push({d[r], r});
37 }
38 }
39 }
40 for (auto x : d)
41 std::cout << x << " ";
42 std::cout << "\n";
43}
diff --git a/04_graph_algorithms/shortest_routes_ii_1672.cpp b/04_graph_algorithms/shortest_routes_ii_1672.cpp
new file mode 100644
index 0000000..d49cb71
--- /dev/null
+++ b/04_graph_algorithms/shortest_routes_ii_1672.cpp
@@ -0,0 +1,30 @@
1#include <algorithm>
2#include <iostream>
3#include <vector>
4
5constexpr size_t inf{999999999999999ULL};
6
7int main() {
8 size_t n, m, q;
9 std::cin >> n >> m >> q;
10 std::vector<std::vector<size_t>> d(n, std::vector(n, inf));
11 for (size_t i = 0; i < n; i++) d[i][i] = 0;
12 for (size_t i = 0; i < m; i++) {
13 size_t x, y, z;
14 std::cin >> x >> y >> z;
15 d[x-1][y-1] = d[y-1][x-1] = std::min(d[x-1][y-1], z);
16 }
17
18 for (size_t k = 0; k < n; k++)
19 for (size_t i = 0; i < n; i++)
20 for (size_t j = 0; j < n; j++)
21 d[j][i] = d[i][j] =
22 std::min(d[i][j], d[i][k] + d[k][j]);
23
24 for (size_t i = 0; i < q; i++) {
25 size_t x, y;
26 std::cin >> x >> y;
27 long long int dd = d[x-1][y-1];
28 std::cout << (dd == inf ? -1LL : dd) << "\n";
29 }
30}
diff --git a/05_range_queries/a.out b/05_range_queries/a.out
new file mode 100755
index 0000000..27b6efc
--- /dev/null
+++ b/05_range_queries/a.out
Binary files differ
diff --git a/05_range_queries/dynamic_range_minimum_queries_1649.cpp b/05_range_queries/dynamic_range_minimum_queries_1649.cpp
new file mode 100644
index 0000000..c4d9b34
--- /dev/null
+++ b/05_range_queries/dynamic_range_minimum_queries_1649.cpp
@@ -0,0 +1,54 @@
1#include <algorithm>
2#include <iostream>
3#include <vector>
4
5constexpr size_t inf = 1999999999;
6
7class SegmentTree {
8public:
9 SegmentTree(size_t n) : m{pow2ceil(n)}, v(2*m, inf) {}
10
11 void update(size_t i, size_t x) {
12 v[m+i-1] = x;
13 for (size_t p = (m+i-1)/2; p > 0; p /= 2)
14 v[p] = std::min(v[2*p], v[2*p+1]);
15 }
16
17 size_t min(size_t a, size_t b) { return q(a-1, b, 1, 0, m); }
18
19private:
20 size_t m;
21 std::vector<size_t> v;
22 static constexpr size_t pow2ceil(size_t x) {
23 size_t c;
24 for (c = 1; c < x; c *= 2) ;
25 return c;
26 }
27
28 size_t q(size_t a, size_t b, size_t i, size_t l, size_t r) {
29 if (a == l && b == r) return v[i];
30 size_t p{(l+r)/2}, s{inf};
31 if (a < p) s = std::min(s, q(a, std::min(b, p), 2*i, l, p));
32 if (b > p) s = std::min(s, q(std::max(a, p), b, 2*i+1, p, r));
33 return s;
34 }
35};
36
37int main() {
38 size_t n, q;
39 std::cin >> n >> q;
40 SegmentTree t(n);
41 for (size_t i = 0; i < n; i++) {
42 size_t x;
43 std::cin >> x;
44 t.update(i+1, x);
45 }
46 for (size_t i = 0; i < q; i++) {
47 int u, a, b;
48 std::cin >> u >> a >> b;
49 if (u == 1)
50 t.update(a, b);
51 else
52 std::cout << t.min(a, b) << "\n";
53 }
54}
diff --git a/05_range_queries/dynamic_range_sum_queries_1648.cpp b/05_range_queries/dynamic_range_sum_queries_1648.cpp
new file mode 100644
index 0000000..ceb6b0c
--- /dev/null
+++ b/05_range_queries/dynamic_range_sum_queries_1648.cpp
@@ -0,0 +1,50 @@
1#include <algorithm>
2#include <iostream>
3#include <vector>
4
5class SumFenwickTree {
6public:
7 SumFenwickTree(int n) : a(n+1) {}
8 long long sum(int l, int r) const { return psum(r) - psum(l-1); }
9 void update(int k, long long u) { add(k, u - sum(k, k));}
10
11private:
12 std::vector<long long> a;
13
14 static int lsb(int i) { return i & -i; }
15
16 long long psum(int i) const {
17 long long s = 0;
18 while (i > 0) {
19 s += a[i];
20 i -= lsb(i);
21 }
22 return s;
23 }
24
25 void add(int k, long long d) {
26 while (k < (int)a.size()) {
27 a[k] += d;
28 k += lsb(k);
29 }
30 }
31};
32
33int main() {
34 size_t n, q;
35 std::cin >> n >> q;
36 SumFenwickTree t(n);
37 for (size_t i = 0; i < n; i++) {
38 long long x;
39 std::cin >> x;
40 t.update(i+1, x);
41 }
42 for (size_t i = 0; i < q; i++) {
43 long long x, k, u;
44 std::cin >> x >> k >> u;
45 if (x == 1)
46 t.update(k, u);
47 else
48 std::cout << t.sum(k, u) << "\n";
49 }
50}
diff --git a/05_range_queries/range_xor_queries_1650.cpp b/05_range_queries/range_xor_queries_1650.cpp
new file mode 100644
index 0000000..e6a4500
--- /dev/null
+++ b/05_range_queries/range_xor_queries_1650.cpp
@@ -0,0 +1,20 @@
1#include <algorithm>
2#include <iostream>
3#include <vector>
4
5int main() {
6 size_t n, q;
7 std::cin >> n >> q;
8 std::vector<int> p(n);
9 for (size_t i = 0; i < n; i++)
10 std::cin >> p[i];
11 for (size_t i = 1; i < n; i++)
12 p[i] ^= p[i-1];
13 for (size_t i = 0; i < q; i++) {
14 int x, k, s;
15 std::cin >> x >> k;
16 s = p[k-1];
17 if (x > 1) s ^= p[x-2];
18 std::cout << s << "\n";
19 }
20}
diff --git a/05_range_queries/static_range_minimum_queries_1647.cpp b/05_range_queries/static_range_minimum_queries_1647.cpp
new file mode 100644
index 0000000..ef11438
--- /dev/null
+++ b/05_range_queries/static_range_minimum_queries_1647.cpp
@@ -0,0 +1,47 @@
1#include <iostream>
2#include <limits>
3#include <vector>
4
5int minrange(std::vector<int>& a, int x, int y, int i, int p, int l, int r) {
6 if (x == l && y == r)
7 return a[2*p-2-i];
8
9 if (x >= y)
10 return std::numeric_limits<int>::max();
11
12 int lr = (l+r)/2;
13 return std::min(
14 minrange(a, std::max(x, l), std::min(y, lr), 2*i+2, p, l, lr),
15 minrange(a, std::max(x, lr), std::min(y, r), 2*i+1, p, lr, r)
16 );
17}
18
19void compute_mins(std::vector<int>& a, int j, int n) {
20 for (int i = 0; i < n; i += 2)
21 a[j+n+i/2] = std::min(a[j+i], a[j+i+1]);
22}
23
24int main() {
25 int n, q, x, y, p;
26 std::cin >> n >> q;
27
28 // For simplicity, extend n to a power of 2
29 for (p = 1; p < n; p <<= 1) ;
30
31 std::vector<int> a(2*p-1, 0);
32 for (int i = 0; i < n; i++)
33 std::cin >> a[i];
34
35 // a[p], a[p+1] ... a[p+p/2-1] are min of pairs
36 // a[p+p/2], a[p+p/2+1], ... a[p+p/2+p/4] are min of quads
37 // etc...
38 for (int i = 1, j = 0; i < p; i <<= 1) {
39 compute_mins(a, j, p/i);
40 j += p/i;
41 }
42
43 for (int i = 0; i < q; i++) {
44 std::cin >> x >> y;
45 std::cout << minrange(a, x-1, y, 0, p, 0, p) << "\n";
46 }
47}
diff --git a/05_range_queries/static_range_sum_queries_1646.cpp b/05_range_queries/static_range_sum_queries_1646.cpp
new file mode 100644
index 0000000..7de69a2
--- /dev/null
+++ b/05_range_queries/static_range_sum_queries_1646.cpp
@@ -0,0 +1,17 @@
1#include <iostream>
2#include <vector>
3
4int main() {
5 int n, q, x, y;
6 std::cin >> n >> q;
7 std::vector<long long> a(n+1, 0);
8 for (int i = 1; i <= n; i++) {
9 std::cin >> a[i];
10 a[i] += a[i-1];
11 }
12
13 for (int i = 0; i < q; i++) {
14 std::cin >> x >> y;
15 std::cout << a[y]-a[x-1] << "\n";
16 }
17}
diff --git a/06_tree_algorithms/a.out b/06_tree_algorithms/a.out
new file mode 100755
index 0000000..ec817fa
--- /dev/null
+++ b/06_tree_algorithms/a.out
Binary files differ
diff --git a/06_tree_algorithms/subordinates_1674.cpp b/06_tree_algorithms/subordinates_1674.cpp
new file mode 100644
index 0000000..38982ce
--- /dev/null
+++ b/06_tree_algorithms/subordinates_1674.cpp
@@ -0,0 +1,23 @@
1#include <iostream>
2#include <vector>
3
4int f(const std::vector<std::vector<int>>& a, std::vector<int>& b, int i) {
5 for (auto x : a[i])
6 b[i] += f(a, b, x) + 1;
7 return b[i];
8}
9
10int main() {
11 int n, x;
12 std::cin >> n;
13 std::vector<std::vector<int>> a(n);
14 for (int i = 1; i < n; i++) {
15 std::cin >> x;
16 a[x-1].push_back(i);
17 }
18 std::vector<int> b(n, 0);
19 f(a, b, 0);
20 for (auto y : b)
21 std::cout << y << " ";
22 std::cout << std::endl;
23}
diff --git a/06_tree_algorithms/tree_matching_1130.cpp b/06_tree_algorithms/tree_matching_1130.cpp
new file mode 100644
index 0000000..8828f68
--- /dev/null
+++ b/06_tree_algorithms/tree_matching_1130.cpp
@@ -0,0 +1,41 @@
1#include <iostream>
2#include <vector>
3
4int f(const std::vector<std::vector<int>>& a,
5 std::vector<std::vector<int>>& t, int v, int p, bool x) {
6 if (t[v][x] != -1) return t[v][x];
7 if (p != -1 && a[v].size() == 1) return t[v][x] = 0;
8
9 t[v][x] = 0;
10 for (auto u : a[v]) {
11 if (u == p) continue;
12 t[v][x] += f(a, t, u, v, false);
13 }
14 if (x) return t[v][x];
15
16 for (auto u : a[v]) {
17 if (u == p) continue;
18 if (f(a, t, u, v, true) == t[u][false]) {
19 t[v][x]++;
20 break;
21 }
22 }
23 return t[v][x];
24}
25
26int main() {
27 int n, x, y;
28 std::cin >> n;
29 std::vector<std::vector<int>> a(n);
30 for (int i = 0; i < n-1; i++) {
31 std::cin >> x >> y;
32 a[x-1].push_back(y-1);
33 a[y-1].push_back(x-1);
34 }
35 if (n == 1) {
36 std::cout << "0\n";
37 return 0;
38 }
39 std::vector<std::vector<int>> t(n, {-1, -1});
40 std::cout << f(a, t, 0, -1, false) << "\n";
41}
diff --git a/07_mathematics/a.out b/07_mathematics/a.out
new file mode 100755
index 0000000..d03560d
--- /dev/null
+++ b/07_mathematics/a.out
Binary files differ
diff --git a/07_mathematics/common_divisors_1081.cpp b/07_mathematics/common_divisors_1081.cpp
new file mode 100644
index 0000000..497ce4b
--- /dev/null
+++ b/07_mathematics/common_divisors_1081.cpp
@@ -0,0 +1,53 @@
1#include <array>
2#include <bitset>
3#include <iostream>
4
5// This method is very different (and more complicated) than the one used
6// in the official solution.
7// First we save in spf[i] the smallest prime number that divides i.
8// Then we initialize an array d with d[i] being 1 if i is in the input.
9// Then we loop backwards and we search all divisors of the numbers marked
10// in d. For each number we encounter, we look at its maximal divisors.
11// If any of them was already found, we update our candidate solution.
12// To avoid looking at a divisor more than once, we save in d[i] the
13// smallest prime we want to continue diving i by to find more divisors.
14
15constexpr size_t max = 1000001;
16std::array<size_t, max> spf; // Smallest prime factor of i
17std::array<size_t, max> d;
18
19int main() {
20 for (size_t i = 2; i < max; i++) {
21 if (spf[i] != 0) continue;
22 spf[i] = i;
23 for (size_t j = 2; i*j < max; j++)
24 if (spf[i*j] == 0)
25 spf[i*j] = i;
26 }
27
28 size_t n, sol{1};
29 std::cin >> n;
30 for (size_t i = 0; i < n; i++) {
31 size_t x;
32 std::cin >> x;
33 if (d[x] != 0) sol = std::max(sol, x);
34 d[x] = 1;
35 }
36
37 for (size_t i = max-1; i >= sol; i--) {
38 if (d[i] == 0) continue;
39
40 // Loop over maximal divisors of i
41 size_t y{i};
42 while (y != 1) {
43 size_t p = spf[y];
44 if (i/p < sol) break;
45 if (p >= d[i]) {
46 if (d[i/p] != 0) sol = std::max(sol, i/p);
47 d[i/p] = p;
48 }
49 while (y % p == 0) y /= p;
50 }
51 }
52 std::cout << sol << "\n";
53}
diff --git a/07_mathematics/counting_divisors_1713.cpp b/07_mathematics/counting_divisors_1713.cpp
new file mode 100644
index 0000000..fe30ab4
--- /dev/null
+++ b/07_mathematics/counting_divisors_1713.cpp
@@ -0,0 +1,34 @@
1#include <array>
2#include <iostream>
3
4constexpr size_t max = 1000001;
5std::array<size_t, max> spf; // Smallest prime factor of i
6
7size_t ndiv(size_t x) {
8 size_t n{1}, d{0}, e{0};
9 for (size_t i = x; i > 1; i /= spf[i]) {
10 if (spf[i] != d) {
11 n *= e+1;
12 d = spf[i];
13 e = 1;
14 } else e++;
15 }
16 return n * (e+1);
17}
18
19int main() {
20 for (size_t i = 2; i < max; i++) {
21 if (spf[i] != 0) continue;
22 spf[i] = i;
23 for (size_t j = 2; i*j < max; j++)
24 if (spf[i*j] == 0)
25 spf[i*j] = i;
26 }
27
28 size_t n, x;
29 std::cin >> n;
30 for (size_t i = 0; i < n; i++) {
31 std::cin >> x;
32 std::cout << ndiv(x) << "\n";
33 }
34}
diff --git a/07_mathematics/exponentiation_1095.cpp b/07_mathematics/exponentiation_1095.cpp
new file mode 100644
index 0000000..1ba8509
--- /dev/null
+++ b/07_mathematics/exponentiation_1095.cpp
@@ -0,0 +1,19 @@
1#include <iostream>
2
3static constexpr unsigned long long MOD = 1000000007;
4
5unsigned long long pow(unsigned long long a, unsigned long long b) {
6 if (b == 0) return 1;
7 if (a == 0) return 0;
8 if (b % 2 == 0) return pow(a*a % MOD, b/2) % MOD;
9 return (a * pow(a, b-1)) % MOD;
10}
11
12int main() {
13 unsigned long long n, a, b;
14 std::cin >> n;
15 for (unsigned long long i = 0; i < n; i++) {
16 std::cin >> a >> b;
17 std::cout << pow(a, b) << "\n";
18 }
19}
diff --git a/07_mathematics/exponentiation_ii_1712.cpp b/07_mathematics/exponentiation_ii_1712.cpp
new file mode 100644
index 0000000..6a894f5
--- /dev/null
+++ b/07_mathematics/exponentiation_ii_1712.cpp
@@ -0,0 +1,20 @@
1#include <iostream>
2
3static constexpr unsigned long long MOD = 1000000007;
4
5unsigned long long pow(unsigned long long a, unsigned long long b,
6 unsigned long long mod) {
7 if (b == 0) return 1;
8 if (a == 0) return 0;
9 if (b % 2 == 0) return pow(a*a % mod, b/2, mod) % mod;
10 return (a * pow(a, b-1, mod)) % mod;
11}
12
13int main() {
14 unsigned long long n, a, b, c;
15 std::cin >> n;
16 for (unsigned long long i = 0; i < n; i++) {
17 std::cin >> a >> b >> c;
18 std::cout << pow(a, pow(b, c, MOD-1), MOD) << "\n";
19 }
20}
diff --git a/07_mathematics/josephus_queries_2164.cpp b/07_mathematics/josephus_queries_2164.cpp
new file mode 100644
index 0000000..b17f3c9
--- /dev/null
+++ b/07_mathematics/josephus_queries_2164.cpp
@@ -0,0 +1,17 @@
1#include <iostream>
2
3int f(int n, int k, int m) {
4 int h = n/2 + m*(n%2);
5 if (n == 1) return 1;
6 if (k <= h) return 2*k-m;
7 return 2*f(n-h, k-h, m^(n%2))+m-1;
8}
9
10int main() {
11 int q, n, k;
12 std::cin >> q;
13 for (int i = 0; i < q; i++) {
14 std::cin >> n >> k;
15 std::cout << f(n, k, 0) << "\n";
16 }
17}
diff --git a/08_string_algorithms/a.out b/08_string_algorithms/a.out
new file mode 100755
index 0000000..4556b32
--- /dev/null
+++ b/08_string_algorithms/a.out
Binary files differ
diff --git a/08_string_algorithms/finding_borders_1732.cpp b/08_string_algorithms/finding_borders_1732.cpp
new file mode 100644
index 0000000..d5cbbd4
--- /dev/null
+++ b/08_string_algorithms/finding_borders_1732.cpp
@@ -0,0 +1,23 @@
1#include <algorithm>
2#include <iostream>
3#include <string>
4#include <vector>
5
6int main() {
7 std::string s;
8 std::cin >> s;
9 std::vector<size_t> z(s.size(), 0), c;
10 z[0] = s.size();
11 for (size_t i = 1, j = 0, k = 0; i < s.size(); i++) {
12 if (j < i || z[i-k] == j-i) {
13 for (j = std::max(i, j); j < s.size() && s[j] == s[j-i]; j++) ;
14 z[k=i] = j-i;
15 } else z[i] = std::min(z[i-k], j-i);
16 if (z[i] == s.size()-i)
17 c.push_back(z[i]);
18 }
19 std::sort(c.begin(), c.end());
20 for (auto x : c)
21 std::cout << x << " ";
22 std::cout << "\n";
23}
diff --git a/08_string_algorithms/finding_periods_1733.cpp b/08_string_algorithms/finding_periods_1733.cpp
new file mode 100644
index 0000000..edaa1d1
--- /dev/null
+++ b/08_string_algorithms/finding_periods_1733.cpp
@@ -0,0 +1,29 @@
1#include <algorithm>
2#include <iostream>
3#include <string>
4#include <vector>
5
6bool isp(const std::vector<size_t>& z, size_t k) {
7 for (size_t i = 0; i*k < z.size(); i++)
8 if (z[i*k] < std::min(k, z.size()-i*k))
9 return false;
10 return true;
11}
12
13int main() {
14 std::string s;
15 std::cin >> s;
16 std::vector<size_t> z(s.size(), 0);
17 z[0] = s.size();
18 for (size_t i = 1, j = 0, k = 0; i < s.size(); i++) {
19 if (j < i || z[i-k] == j-i) {
20 for (j = std::max(i, j); j < s.size() && s[j] == s[j-i]; j++) ;
21 z[k=i] = j-i;
22 } else z[i] = std::min(z[i-k], j-i);
23 }
24
25 for (size_t i = 1; i <= s.size(); i++)
26 if (isp(z, i))
27 std::cout << i << " ";
28 std::cout << "\n";
29}
diff --git a/08_string_algorithms/string_matching_1753.cpp b/08_string_algorithms/string_matching_1753.cpp
new file mode 100644
index 0000000..148ed03
--- /dev/null
+++ b/08_string_algorithms/string_matching_1753.cpp
@@ -0,0 +1,32 @@
1#include <iostream>
2#include <string>
3#include <vector>
4
5struct S {
6 std::string w;
7 std::string t;
8
9 size_t size() const { return w.size() + 1 + t.size(); }
10
11 char operator[](size_t i) const {
12 if (i < w.size()) return w.at(i);
13 if (i > w.size()) return t.at(i-w.size()-1);
14 return '$';
15 }
16};
17
18int main() {
19 S s;
20 std::cin >> s.t >> s.w;
21 size_t c{0};
22 std::vector<size_t> z(s.size(), 0);
23 z[0] = s.w.size();
24 for (size_t i = 1, j = 0, k = 0; i < s.size(); i++) {
25 if (j < i || z[i-k] == j-i) {
26 for (j = std::max(i, j); j < s.size() && s[j] == s[j-i]; j++) ;
27 z[k=i] = j-i;
28 } else z[i] = std::min(z[i-k], j-i);
29 c += z[i] == s.w.size();
30 }
31 std::cout << c << "\n";
32}
diff --git a/08_string_algorithms/word_combinations_1731.cpp b/08_string_algorithms/word_combinations_1731.cpp
new file mode 100644
index 0000000..8a26b91
--- /dev/null
+++ b/08_string_algorithms/word_combinations_1731.cpp
@@ -0,0 +1,63 @@
1#include <iostream>
2#include <queue>
3#include <string>
4#include <string_view>
5#include <vector>
6
7struct TrieNode {
8 char c;
9 size_t d;
10 bool isend;
11 std::vector<TrieNode> next;
12
13 TrieNode(char x, size_t y) : c{x}, d{y}, isend{false}, next() {}
14};
15
16void push(std::string_view s, TrieNode& t) {
17 if (s.empty()) {
18 t.isend = true;
19 return;
20 }
21 for (auto& u : t.next) {
22 if (s[0] == u.c) {
23 push(s.substr(1), u);
24 return;
25 }
26 }
27 t.next.push_back(TrieNode(s[0], t.d+1));
28 push(s.substr(1), t.next.back());
29}
30
31const TrieNode* next(const TrieNode* w, char c) {
32 for (size_t i = 0; i < w->next.size(); i++)
33 if (w->next[i].c == c)
34 return &w->next[i];
35 return nullptr;
36}
37
38int f(std::vector<int>& t, std::string_view s, const TrieNode& d, size_t i) {
39 static constexpr long long mod = 1e9+7;
40
41 if (t[i] != -1) return t[i];
42
43 t[i] = 0;
44 for (const TrieNode* w = &d; w != nullptr; w = next(w, s[w->d]))
45 if (w->isend)
46 t[i] = (t[i] + f(t, s.substr(w->d), d, i+w->d)) % mod;
47 return t[i];
48}
49
50int main() {
51 std::string s, u;
52 size_t k;
53 std::cin >> s >> k;
54 TrieNode d('\0', 0);
55 for (size_t i = 0; i < k; i++) {
56 std::cin >> u;
57 push(u, d);
58 }
59
60 std::vector<int> t(s.size()+1, -1);
61 t[s.size()] = 1;
62 std::cout << f(t, s, d, 0) << "\n";
63}
diff --git a/09_geometry/a.out b/09_geometry/a.out
new file mode 100755
index 0000000..6e5df8b
--- /dev/null
+++ b/09_geometry/a.out
Binary files differ
diff --git a/09_geometry/line_segment_intersection_2190.cpp b/09_geometry/line_segment_intersection_2190.cpp
new file mode 100644
index 0000000..2f9aced
--- /dev/null
+++ b/09_geometry/line_segment_intersection_2190.cpp
@@ -0,0 +1,41 @@
1#include <algorithm>
2#include <iostream>
3
4bool inran(long long int a, long long int b, long long int m) {
5 return m >= std::min(a, b) && m <= std::max(a, b);
6}
7
8bool inseg(long long int d, long long int dt, long long int du) {
9 return dt >= 0 && dt <= d && du >= 0 && du <= d;
10}
11
12bool f(long long int x1, long long int y1, long long int x2, long long int y2,
13 long long int x3, long long int y3, long long int x4, long long int y4) {
14 long long int xt = x2-x1, yt = y2-y1;
15 long long int xu = x4-x3, yu = y4-y3;
16 long long int d = xt * (-yu) - yt * (-xu);
17 long long int dt = (x3-x1) * (-yu) - (y3-y1) * (-xu);
18 long long int du = (xt) * (y3-y1) - (yt) * (x3-x1);
19
20 if (d == 0) {
21 // Parallel on different lines
22 if (dt != 0 || du != 0) return false;
23
24 // Parallel, same line
25 return xt == 0 ?
26 inran(y1,y2,y3) || inran(y1,y2,y4) || inran(y3,y4,y1) :
27 inran(x1,x2,x3) || inran(x1,x2,x4) || inran(x3,x4,x1);
28 } else {
29 // Not parallel
30 long long int m = d > 0 ? 1 : -1;
31 return inseg(m*d, m*dt, m*du);
32 }
33}
34
35int main() {
36 long long int x1, y1, x2, y2, x3, y3, x4, y4;
37 int n;
38 std::cin >> n;
39 while (std::cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3 >> x4 >> y4)
40 std::cout << (f(x1,y1,x2,y2,x3,y3,x4,y4) ? "YES\n" : "NO\n");
41}
diff --git a/09_geometry/point_location_test_2189.cpp b/09_geometry/point_location_test_2189.cpp
new file mode 100644
index 0000000..998abb8
--- /dev/null
+++ b/09_geometry/point_location_test_2189.cpp
@@ -0,0 +1,21 @@
1#include <iostream>
2
3struct Point {
4 long long x;
5 long long y;
6 Point operator-(const Point& p) const { return Point{x-p.x, y-p.y}; }
7 long long operator*(const Point& v) { return x * v.y - y * v.x; }
8};
9
10int main() {
11 int t;
12 Point a, b, c;
13 std::cin >> t;
14 for (int i = 0; i < t; i++) {
15 std::cin >> a.x >> a.y >> b.x >> b.y >> c.x >> c.y;
16 auto v = (b-a)*(c-a);
17 if (v > 0) std::cout << "LEFT\n";
18 else if (v < 0) std::cout << "RIGHT\n";
19 else std::cout << "TOUCH\n";
20 }
21}
diff --git a/10_advanced_techniques/a.out b/10_advanced_techniques/a.out
new file mode 100755
index 0000000..54ec8d4
--- /dev/null
+++ b/10_advanced_techniques/a.out
Binary files differ
diff --git a/10_advanced_techniques/hamming_distance_2136.cpp b/10_advanced_techniques/hamming_distance_2136.cpp
new file mode 100644
index 0000000..a4b0b7d
--- /dev/null
+++ b/10_advanced_techniques/hamming_distance_2136.cpp
@@ -0,0 +1,22 @@
1#include <algorithm>
2#include <bit>
3#include <iostream>
4#include <vector>
5
6int main() {
7 unsigned n, k;
8 std::cin >> n >> k;
9 std::vector<unsigned> a(n);
10 for (unsigned i = 0; i < n; i++) {
11 for (unsigned j = 0, p = 1; j < k; j++, p <<= 1) {
12 char c;
13 std::cin >> c;
14 if (c == '1') a[i] += p;
15 }
16 }
17 int s = k+1;
18 for (unsigned i = 0; i < n; i++)
19 for (unsigned j = i+1; j < n; j++)
20 s = std::min(s, std::popcount(a[i] ^ a[j]));
21 std::cout << s << "\n";
22}
diff --git a/10_advanced_techniques/meet_in_the_middle_1628.cpp b/10_advanced_techniques/meet_in_the_middle_1628.cpp
new file mode 100644
index 0000000..a38c5d4
--- /dev/null
+++ b/10_advanced_techniques/meet_in_the_middle_1628.cpp
@@ -0,0 +1,42 @@
1#include <algorithm>
2#include <iostream>
3#include <numeric>
4#include <unordered_map>
5#include <vector>
6
7void add_to_map(size_t i, size_t e, long long s,
8 const std::vector<long long>& a,
9 std::unordered_map<long long, long long>& m) {
10 if (i == e) { m[s]++; return; }
11 add_to_map(i+1, e, s, a, m);
12 add_to_map(i+1, e, s+a[i], a, m);
13}
14
15long long f(size_t i, size_t e, long long t, long long s,
16 const std::vector<long long>& a,
17 const std::unordered_map<long long, long long>& m) {
18 if (t < 0 || t > s) return 0;
19 if (i == e) return m.find(t) == m.end() ? 0 : m.at(t);
20 return f(i+1, e, t, s-a[i], a, m) + f(i+1, e, t-a[i], s-a[i], a, m);
21}
22
23int main() {
24 size_t n, p;
25 long long x, s{0};
26 std::cin >> n >> x;
27 std::vector<long long> a(n);
28 for (size_t i = 0; i < n; i++)
29 std::cin >> a[i];
30
31 std::sort(a.begin(), a.end(), std::greater<long long>());
32 s = std::accumulate(a.begin(), a.end(), 0LL);
33 if (x > s) {
34 std::cout << "0\n";
35 return 0;
36 }
37
38 p = a.size()/2;
39 std::unordered_map<long long, long long> m;
40 add_to_map(p, a.size(), 0, a, m);
41 std::cout << f(0, p, x, s, a, m) << "\n";
42}
diff --git a/11_sliding_window_problems/a.out b/11_sliding_window_problems/a.out
new file mode 100755
index 0000000..8a06b5a
--- /dev/null
+++ b/11_sliding_window_problems/a.out
Binary files differ
diff --git a/11_sliding_window_problems/sliding_window_minimum_3221.cpp b/11_sliding_window_problems/sliding_window_minimum_3221.cpp
new file mode 100644
index 0000000..ef7485a
--- /dev/null
+++ b/11_sliding_window_problems/sliding_window_minimum_3221.cpp
@@ -0,0 +1,29 @@
1#include <algorithm>
2#include <deque>
3#include <iostream>
4#include <vector>
5
6int main() {
7 long long n, k, x, a, b, c;
8 std::cin >> n >> k >> x >> a >> b >> c;
9
10 std::vector<long long> v(k);
11 std::deque<long long> q;
12 for (long long i = 0; i < k; i++) {
13 v[i] = x;
14 while (!q.empty() && q.back() >= x) q.pop_back();
15 q.push_back(x);
16 x = (a*x + b) % c;
17 }
18
19 long long sol = q.front();
20 for (long long i = 0; i < n-k; i++) {
21 if (q.front() == v[i%k]) q.pop_front();
22 v[i%k] = (a*v[(i-1+k)%k] + b) % c;
23 while (!q.empty() && q.back() >= v[i%k]) q.pop_back();
24 q.push_back(v[i%k]);
25 sol ^= q.front();
26 }
27
28 std::cout << sol << "\n";
29}
diff --git a/11_sliding_window_problems/sliding_window_or_3405.cpp b/11_sliding_window_problems/sliding_window_or_3405.cpp
new file mode 100644
index 0000000..ba95e22
--- /dev/null
+++ b/11_sliding_window_problems/sliding_window_or_3405.cpp
@@ -0,0 +1,28 @@
1#include <iostream>
2#include <vector>
3
4// We pre-compute prefix and suffix or for non-overlapping windows of k
5// elements, and we compute the sliding window or from those.
6// https://codeforces.com/blog/entry/142846
7
8int main() {
9 size_t n, k;
10 long long a, b, c, sol{0};
11 std::cin >> n >> k;
12 std::vector<long long> v(n), pre(n), suf(n);
13 std::cin >> v[0] >> a >> b >> c;
14
15 for (size_t i = 1; i < n; i++)
16 v[i] = (a*v[i-1] + b) % c;
17
18 for (size_t i = 0; i < n; i++)
19 pre[i] = i % k == 0 ? v[i] : v[i] | pre[i-1];
20
21 for (size_t i = n; i > 0; i--)
22 suf[i-1] = i == n || (i-1) % k == 0 ? v[i-1] : v[i-1] | suf[i];
23
24 for (long long i = k-1; i < n; i++)
25 sol ^= pre[i] | suf[i-(k-1)];
26
27 std::cout << sol << "\n";
28}
diff --git a/11_sliding_window_problems/sliding_window_sum_3220.cpp b/11_sliding_window_problems/sliding_window_sum_3220.cpp
new file mode 100644
index 0000000..9096b75
--- /dev/null
+++ b/11_sliding_window_problems/sliding_window_sum_3220.cpp
@@ -0,0 +1,25 @@
1#include <iostream>
2#include <vector>
3
4int main() {
5 size_t n, k;
6 long long x, a, b, c, sum{0}, sol{0};
7 std::cin >> n >> k >> x >> a >> b >> c;
8
9 std::vector<long long> v(k);
10 for (size_t i = 0; i < k; i++) {
11 sum += x;
12 v[i] = x;
13 x = (a*x + b) % c;
14 }
15
16 sol = sum;
17 for (size_t i = 0; i < n-k; i++) {
18 sum -= v[i%k];
19 v[i%k] = (a*v[(i-1+k)%k] + b) % c;
20 sum += v[i%k];
21 sol ^= sum;
22 }
23
24 std::cout << sol << "\n";
25}
diff --git a/11_sliding_window_problems/sliding_window_xor_3426.cpp b/11_sliding_window_problems/sliding_window_xor_3426.cpp
new file mode 100644
index 0000000..0f21ce3
--- /dev/null
+++ b/11_sliding_window_problems/sliding_window_xor_3426.cpp
@@ -0,0 +1,26 @@
1#include <algorithm>
2#include <deque>
3#include <iostream>
4#include <vector>
5
6int main() {
7 long long n, k, x, a, b, c, m{0};
8 std::cin >> n >> k >> x >> a >> b >> c;
9
10 std::vector<long long> v(k);
11 for (long long i = 0; i < k; i++) {
12 v[i] = x;
13 m ^= x;
14 x = (a*x + b) % c;
15 }
16
17 long long sol{m};
18 for (long long i = 0; i < n-k; i++) {
19 m ^= v[i%k];
20 v[i%k] = (a*v[(i-1+k)%k] + b) % c;
21 m ^= v[i%k];
22 sol ^= m;
23 }
24
25 std::cout << sol << "\n";
26}
diff --git a/12_interactive_problems/a.out b/12_interactive_problems/a.out
new file mode 100755
index 0000000..c949b8e
--- /dev/null
+++ b/12_interactive_problems/a.out
Binary files differ
diff --git a/12_interactive_problems/hidden_integer_3112.cpp b/12_interactive_problems/hidden_integer_3112.cpp
new file mode 100644
index 0000000..66e5a09
--- /dev/null
+++ b/12_interactive_problems/hidden_integer_3112.cpp
@@ -0,0 +1,16 @@
1#include <iostream>
2#include <string>
3
4int main() {
5 int m, l{0}, r{1000000000};
6 std::string s;
7 while (l+1 != r) {
8 m = (l+r)/2;
9 std::cout << "? " << m << std::endl;
10 std::cin >> s;
11 if (s == "YES") l = m;
12 else r = m;
13 }
14
15 std::cout << "! " << r << std::endl;
16}
diff --git a/12_interactive_problems/hidden_permutation_3139.cpp b/12_interactive_problems/hidden_permutation_3139.cpp
new file mode 100644
index 0000000..fc01d53
--- /dev/null
+++ b/12_interactive_problems/hidden_permutation_3139.cpp
@@ -0,0 +1,45 @@
1#include <iostream>
2#include <iterator>
3#include <string>
4#include <vector>
5
6void print_sol(const std::vector<size_t>& v) {
7 std::cout << "! ";
8 for (size_t i = 0; i < v.size(); i++) {
9 for (size_t j = 0; j < v.size(); j++) {
10 if (v[j] == i) {
11 std::cout << (j+1) << " ";
12 break;
13 }
14 }
15 }
16 std::cout << std::endl;
17}
18
19bool cmp(size_t i, size_t j) {
20 std::cout << "? " << (i+1) << " " << (j+1) << std::endl;
21 std::string s;
22 std::cin >> s;
23 return s == "YES";
24}
25
26size_t binsearch(size_t i, const std::vector<size_t>& v, size_t l, size_t r) {
27 if (r == l) return l;
28 size_t m = (l+r)/2;
29 return cmp(i, v[m]) ? binsearch(i, v, l, m) : binsearch(i, v, m+1, r);
30}
31
32int main() {
33 size_t n;
34 std::vector<size_t> v;
35 std::cin >> n;
36 v.reserve(n);
37
38 v.push_back(0);
39 for (size_t i = 1; i < n; i++) {
40 size_t pos = binsearch(i, v, 0, v.size());
41 v.insert(std::next(v.begin(), pos), i);
42 }
43
44 print_sol(v);
45}
diff --git a/13_bitwise_operations/a.out b/13_bitwise_operations/a.out
new file mode 100755
index 0000000..a0ec133
--- /dev/null
+++ b/13_bitwise_operations/a.out
Binary files differ
diff --git a/13_bitwise_operations/counting_bits_1146.cpp b/13_bitwise_operations/counting_bits_1146.cpp
new file mode 100644
index 0000000..004dc13
--- /dev/null
+++ b/13_bitwise_operations/counting_bits_1146.cpp
@@ -0,0 +1,14 @@
1#include <iostream>
2
3int main() {
4 unsigned long long n, f, p, s{0};
5 std::cin >> n;
6
7 for (unsigned long long i = 1, m = n; i <= n; i <<= 1, m >>= 1) {
8 f = i * (m / 2);
9 p = (n % (2*i)) + 1;
10 p = p > i ? p - i : 0;
11 s += f + p;
12 }
13 std::cout << s << "\n";
14}
diff --git a/13_bitwise_operations/maximum_xor_subarray_1655.cpp b/13_bitwise_operations/maximum_xor_subarray_1655.cpp
new file mode 100644
index 0000000..9ae6564
--- /dev/null
+++ b/13_bitwise_operations/maximum_xor_subarray_1655.cpp
@@ -0,0 +1,53 @@
1#include <algorithm>
2#include <iostream>
3#include <unordered_set>
4#include <vector>
5
6// First we compute the array a of cumulative xor starting from the
7// first element (a[0] being set to 0 for convenience). Then we
8// work bit by bit from the highest bit, building at each point
9// an unordered set of the the available top-masked elements. We
10// always try to find a full-mask, but when a bit is not available
11// we store it in a the mask called "no". The reasoning is similar
12// to finding a pair of elements in an array with a specified sum.
13// The official solution uses a trie; it is more elegant and more
14// efficient, but the idea is not too different.
15
16unsigned bit(unsigned i) { return 1U << (i-1); }
17
18bool no_bit(const std::vector<unsigned>& a, unsigned b) {
19 return std::ranges::none_of(a, [b](unsigned x){ return x & b; });
20}
21
22bool pair_match(
23 const std::unordered_set<unsigned>& s, unsigned m, unsigned no) {
24 for (auto x : s)
25 if (s.contains(((~x)&m)^no))
26 return true;
27 return false;
28}
29
30int main() {
31 size_t n;
32 std::cin >> n;
33 std::vector<unsigned> a(n+1); // Cumulative xor
34 a[0] = 0;
35 for (size_t i = 1; i <= n; i++) {
36 std::cin >> a[i];
37 a[i] ^= a[i-1];
38 }
39 unsigned i{32}, no{0};
40 for ( ; i > 0 && no_bit(a, bit(i)); i--)
41 no |= bit(i);
42 i--;
43 std::unordered_set<unsigned> s;
44 for ( ; i > 0; i--) {
45 unsigned m = ~(bit(i) - 1);
46 s.clear();
47 for (auto x : a)
48 s.insert(x & m);
49 if (!pair_match(s, m, no))
50 no |= bit(i);
51 }
52 std::cout << ~no << "\n";
53}
diff --git a/14_construction_problems/a.out b/14_construction_problems/a.out
new file mode 100755
index 0000000..8f05df6
--- /dev/null
+++ b/14_construction_problems/a.out
Binary files differ
diff --git a/14_construction_problems/inverse_inversions_2214.cpp b/14_construction_problems/inverse_inversions_2214.cpp
new file mode 100644
index 0000000..7e7ae07
--- /dev/null
+++ b/14_construction_problems/inverse_inversions_2214.cpp
@@ -0,0 +1,22 @@
1#include <iostream>
2#include <utility>
3#include <vector>
4
5// Observation: putting 1 at the n-th position (1-based) generates n-1
6// inversions; then, putting 2 at n-2 generates another n-2 inversions;
7// and so on.
8// The first step in our algorithm counts how many times we can do this,
9// and leaves k pointing to the position where we should put the next
10// element. All other elements are in increasing order.
11
12int main() {
13 long long n, k, p, l, m, j, i{0};
14 std::cin >> n >> k;
15 std::vector<long long> a(n, 0);
16
17 for (j = 1, p = 0; p < n-1 && k >= n-j; p++, j++) k -= n-j;
18
19 for (m = p+1, l = p+2, i = 0; i < n; i++)
20 std::cout << ((n-i <= p || i == k) ? m-- : l++) << " ";
21 std::cout << "\n";
22}
diff --git a/15_advanced_graph_problems/a.out b/15_advanced_graph_problems/a.out
new file mode 100755
index 0000000..f333c41
--- /dev/null
+++ b/15_advanced_graph_problems/a.out
Binary files differ
diff --git a/15_advanced_graph_problems/nearest_shops_3303.cpp b/15_advanced_graph_problems/nearest_shops_3303.cpp
new file mode 100644
index 0000000..ce62098
--- /dev/null
+++ b/15_advanced_graph_problems/nearest_shops_3303.cpp
@@ -0,0 +1,55 @@
1#include <algorithm>
2#include <iostream>
3#include <queue>
4#include <tuple>
5#include <vector>
6
7// The difficult part is finding for every city with an anime shop the
8// closest other city with a shop. We do this via a "double BFS", where
9// we reach each node twice from two different sources.
10
11struct V { int v1; int s1; int v2; int s2; };
12
13int main() {
14 constexpr int max{99999999};
15 int n, m, k, x, y;
16 std::queue<std::tuple<int, int, int>> q;
17 std::cin >> n >> m >> k;
18 std::vector<V> v(n, {max, -1, max, -1});
19 for (int i = 0; i < k; i++) {
20 std::cin >> x;
21 v[x-1] = {0, x-1, max, -1};
22 q.push({x-1, 0, x-1});
23 }
24 std::vector<std::vector<int>> a(n);
25 for (int i = 0; i < m; i++) {
26 std::cin >> x >> y;
27 a[x-1].push_back(y-1);
28 a[y-1].push_back(x-1);
29 }
30
31 while (!q.empty()) {
32 auto [u, w, s] = q.front();
33 q.pop();
34 for (auto z : a[u]) {
35 if (z == s) continue;
36 auto& [v1, s1, v2, s2] = v[z];
37 if (v1 > w+1) {
38 v1 = w+1;
39 s1 = s;
40 q.push({z, w+1, s});
41 } else if (s1 != s && v2 > w+1) {
42 v2 = w+1;
43 s2 = s;
44 q.push({z, w+1, s});
45 }
46 }
47 }
48
49 for (int i = 0; i < n; i++) {
50 auto [x, s, y, _] = v[i];
51 auto w = s == i ? y : x;
52 std::cout << (w == max ? -1 : w) << " ";
53 }
54 std::cout << "\n";
55}
diff --git a/16_counting_problems/a.out b/16_counting_problems/a.out
new file mode 100755
index 0000000..fc90929
--- /dev/null
+++ b/16_counting_problems/a.out
Binary files differ
diff --git a/16_counting_problems/filled_subgrid_count_i_3413.cpp b/16_counting_problems/filled_subgrid_count_i_3413.cpp
new file mode 100644
index 0000000..77f7de1
--- /dev/null
+++ b/16_counting_problems/filled_subgrid_count_i_3413.cpp
@@ -0,0 +1,38 @@
1#include <algorithm>
2#include <iostream>
3#include <string>
4#include <vector>
5
6void fill(const std::vector<std::vector<char>>& a,
7 std::vector<std::vector<long long>>& t, int i, int j) {
8 if (a[i][j]==a[i][j+1] && a[i][j]==a[i+1][j] && a[i][j]==a[i+1][j+1])
9 t[i][j] = 1+std::min({t[i+1][j], t[i][j+1], t[i+1][j+1]});
10}
11
12int main() {
13 int n, k;
14 std::string s;
15 std::cin >> n >> k;
16 std::vector<std::vector<char>> a(n, std::vector<char>(n));
17 std::vector<std::vector<long long>> t(n, std::vector<long long>(n, 1));
18 for (int i = 0; i < n; i++) {
19 std::cin >> s;
20 for (int j = 0; j < n; j++)
21 a[i][j] = s[j];
22 }
23
24 for (int d = n-2; d >= 0; d--) {
25 for (int i = d; i >= 0; i--) {
26 fill(a, t, i, d);
27 fill(a, t, d, i);
28 }
29 }
30
31 std::vector<long long> sol(k, 0);
32 for (int i = 0; i < n; i++)
33 for (int j = 0; j < n; j++)
34 sol[a[i][j]-'A'] += t[i][j];
35
36 for (auto x : sol)
37 std::cout << x << "\n";
38}
diff --git a/17_additional_problems_i/a.out b/17_additional_problems_i/a.out
new file mode 100755
index 0000000..d08f6bf
--- /dev/null
+++ b/17_additional_problems_i/a.out
Binary files differ
diff --git a/17_additional_problems_i/shortest_subsequence_1087.cpp b/17_additional_problems_i/shortest_subsequence_1087.cpp
new file mode 100644
index 0000000..f3d7ba0
--- /dev/null
+++ b/17_additional_problems_i/shortest_subsequence_1087.cpp
@@ -0,0 +1,66 @@
1#include <algorithm>
2#include <array>
3#include <iostream>
4#include <ranges>
5#include <string>
6#include <vector>
7
8// Idea: keep an array a[n][4] where a[i][x] denotes the shortest
9// non-subsequence of s[:i] that ends with x. The recursive relation
10// is the following:
11// - For s[i] != x, a[i][x] = a[i-1][x] (easy to see).
12// - For s[i] == x, we have a[i][x] = 1+min(a[i-1][y] over y): if
13// the shortest non-subsequence ending with x becomes a subsequence,
14// then this is realized by adding x to the any of the current 4
15// non-subsequences (including the one already ending in x); otherwise,
16// the subsequence obtained by removing the x is still a valid
17// non-subsequence, and it must be one of the other 3, so we get back
18// the same (it can't end again in x, otherwise it would be a shorter
19// non-subsequence ending in x).
20// Then we have to backtrack to find an actual solution.
21
22size_t ind(char c) {
23 switch (c) {
24 case 'A': return 0;
25 case 'C': return 1;
26 case 'G': return 2;
27 case 'T': return 3;
28 default: return -1;
29 }
30}
31
32char dni(size_t i) {
33 static constexpr char a[] = {'A', 'C', 'G', 'T'};
34 return a[i];
35}
36
37size_t mi(const std::array<size_t, 4>& v) {
38 return *std::min_element(v.begin(), v.end());
39}
40
41int main() {
42 std::string s;
43 std::cin >> s;
44 std::vector<std::array<size_t, 4>> a(s.size(), {1, 1, 1, 1});
45
46 a[0][ind(s[0])] = 2;
47 for (size_t i = 1; i < s.size(); i++)
48 for (size_t j = 0; j < 4; j++)
49 a[i][j] = ind(s[i]) == j ? 1 + mi(a[i-1]) : a[i-1][j];
50
51 auto l = s.size()+2;
52 std::vector<char> sol;
53 for (size_t i = s.size(); i > 0; i--) {
54 auto m = mi(a[i-1]);
55 if (l != m) {
56 l = m;
57 auto in = std::distance(a[i-1].begin(),
58 std::min_element(a[i-1].begin(), a[i-1].end()));
59 sol.push_back(dni(in));
60 }
61 }
62
63 for (auto x : sol | std::views::reverse)
64 std::cout << x;
65 std::cout << "\n";
66}
diff --git a/18_additional_problems_ii/a.out b/18_additional_problems_ii/a.out
new file mode 100755
index 0000000..e040cd7
--- /dev/null
+++ b/18_additional_problems_ii/a.out
Binary files differ
diff --git a/18_additional_problems_ii/bouncing_ball_steps_3215.cpp b/18_additional_problems_ii/bouncing_ball_steps_3215.cpp
new file mode 100644
index 0000000..b09bba2
--- /dev/null
+++ b/18_additional_problems_ii/bouncing_ball_steps_3215.cpp
@@ -0,0 +1,24 @@
1#include <algorithm>
2#include <iostream>
3#include <numeric>
4#include <tuple>
5
6typedef long long ll;
7
8std::tuple<ll, ll, ll> f(ll n, ll m, ll k) {
9 n--; m--;
10 ll am{k % (2*n)}, ad{k / n}, bm{k % (2*m)}, bd{k / m};
11 if (am > n) am = n - (am-n);
12 if (bm > m) bm = m - (bm-m);
13 return {am, bm, ad+bd-k/std::lcm(n, m)};
14}
15
16int main() {
17 ll t, n, m, k;
18 std::cin >> t;
19 for (ll i = 0; i < t; i++) {
20 std::cin >> n >> m >> k;
21 auto [a, b, c] = f(n, m, k);
22 std::cout << a+1 << " " << b+1 << " " << c << "\n";
23 }
24}
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..0c471e4
--- /dev/null
+++ b/README.md
@@ -0,0 +1,6 @@
1# Solutions for cses.fi
2
3In 2026 I felt a bit nostalgic of my competitive programming days,
4and I wanted to play around with the same type of challenges. I found
5out about [cses.fi](https://cses.fi), a practice website aimed at IOI
6contestants, and I started doing some of the problems.
diff --git a/notes.txt b/notes.txt
new file mode 100644
index 0000000..ca75141
--- /dev/null
+++ b/notes.txt
@@ -0,0 +1,5 @@
1- Sparse tables: similar to range trees, but allows for O(1) queries for min.
2 t[i][j] = f([j, j+2^i))
3 https://cp-algorithms.com/data_structures/sparse-table.html
4
5- Decent implementation of Map APIs in 04_graph_algorithms/labyrinth_1193.cpp

Generated with cgit - Back to sebastiano.tronto.net