├── README.md ├── sem-1 ├── README.md ├── problems.pdf └── solutions │ ├── 1A.java │ ├── 1B.java │ ├── 1C.java │ ├── 1D.java │ ├── 1E.java │ ├── 1F.java │ ├── 1G.java │ ├── 1H.java │ ├── 2A.java │ ├── 2B.java │ ├── 3A.java │ ├── 3B.java │ ├── 3C.java │ ├── 3D.java │ ├── 3F.java │ ├── 3G.java │ ├── 3H.java │ ├── 4A.java │ ├── 4B.java │ ├── 4C.py │ ├── 4D.java │ ├── 4E.java │ ├── 4G.java │ ├── 4H.cpp │ ├── 4I.cpp │ ├── 5A.java │ ├── 5B.java │ ├── 5C.java │ ├── 5D.java │ ├── 5E.java │ ├── 5F.java │ ├── 5G.java │ ├── 5H.java │ ├── 7A.java │ ├── 7B.java │ ├── 7C.java │ ├── 8A.java │ ├── 8B.java │ ├── 8C.java │ ├── 8D.java │ └── 8E.java ├── sem-2 ├── README.md ├── problems.pdf └── solutions │ ├── 1A.java │ ├── 1B.java │ ├── 1C.java │ ├── 1D.java │ ├── 1E.java │ ├── 1F.java │ ├── 1G.java │ ├── 1H.cpp │ ├── 1I.java │ ├── 2A.java │ ├── 2B.java │ ├── 2C.cpp │ ├── 2D.cpp │ ├── 2E.java │ ├── 2F.java │ ├── 2G.java │ ├── 2H.java │ ├── 2I.cpp │ ├── 3A.cpp │ ├── 3B.cpp │ ├── 3C.cpp │ ├── 3D.cpp │ ├── 4A.cpp │ ├── 4B.cpp │ ├── 4D.java │ ├── 4E.cpp │ ├── 5A.cpp │ ├── 5B.cpp │ ├── 5C.cpp │ ├── 5D.cpp │ ├── 6A.java │ ├── 6B.cpp │ ├── 6C.java │ ├── 6D.cpp │ ├── 6E.java │ ├── 6F.java │ ├── 7A.java │ └── 7B.java ├── sem-3 ├── README.md ├── problems.pdf └── solutions │ ├── 1A.cpp │ ├── 1B.cpp │ ├── 1C.cpp │ ├── 1D.cpp │ ├── 1E.cpp │ ├── 1F.cpp │ ├── 1G.cpp │ ├── 1I.cpp │ ├── 1J.cpp │ ├── 1K.cpp │ ├── 1L.cpp │ ├── 2A.cpp │ ├── 2B.cpp │ ├── 2C.cpp │ ├── 2D.cpp │ ├── 2E.cpp │ ├── 2F.cpp │ ├── 2G.cpp │ ├── 2H.cpp │ ├── 3A.cpp │ ├── 3B.cpp │ ├── 3C.cpp │ ├── 3D.cpp │ ├── 3E.cpp │ ├── 3F.cpp │ ├── 4A.cpp │ ├── 4B.cpp │ ├── 4C.cpp │ ├── 4D.cpp │ ├── 5A.cpp │ ├── 5B.cpp │ ├── 5C.cpp │ ├── 5D.cpp │ ├── 5E.cpp │ ├── 6A.cpp │ ├── 6B.cpp │ ├── 6C.cpp │ ├── 6D.cpp │ ├── 6E.cpp │ ├── 6F.cpp │ ├── 6G.cpp │ ├── 6H.cpp │ ├── 6I.cpp │ ├── 7A.cpp │ ├── 7B.cpp │ ├── 7C.cpp │ ├── 7D.cpp │ ├── 7E.cpp │ ├── 7H.cpp │ ├── 7I.cpp │ ├── 8A.cpp │ ├── 8B.cpp │ ├── 8C.cpp │ ├── 8D.cpp │ ├── 8E.cpp │ ├── 8F.cpp │ ├── 9A.cpp │ ├── 9B.cpp │ └── 9C.cpp └── sem-4 ├── README.md ├── problems ├── 1A.pdf ├── 5A.pdf ├── 6C.pdf ├── 6D.pdf ├── 8D.pdf └── problems.pdf └── solutions ├── 1A.cpp ├── 1B.cpp ├── 1C.cpp ├── 1D.cpp ├── 1E.cpp ├── 1H.cpp ├── 1I.cpp ├── 2A.cpp ├── 3A.cpp ├── 3B.cpp ├── 3C.cpp ├── 3D.cpp ├── 3E.cpp ├── 3F.cpp ├── 3H.cpp ├── 4A.cpp ├── 4B.cpp ├── 4C.cpp ├── 4D.cpp ├── 4E.cpp ├── 5A.cpp ├── 5B.cpp ├── 5C.cpp ├── 5D.cpp ├── 5E.cpp ├── 5F.cpp ├── 5G.cpp ├── 5H.cpp ├── 5I.cpp ├── 5J.cpp ├── 5K.cpp ├── 5L.cpp ├── 5M.cpp ├── 6A.cpp ├── 6F.cpp ├── 7A.cpp ├── 7B.cpp ├── 7C.cpp ├── 7D.cpp ├── 7E.cpp ├── 7F.cpp └── 7G.cpp /README.md: -------------------------------------------------------------------------------- 1 |

Алгоритмы и структуры данных, 2022-2024

2 | 3 |

Первый семестр

4 | Время работы алгоритма. O-нотация. Квадратичные сортировки. Сортировка слиянием. Два указателя. Двоичная куча. Сортировка кучей. Бинарный и тернарный поиск. Стек. Очередь. Амортизационный анализ. Связные списки. Pointer Machine. Система непересекающихся множеств. Быстрая сортировка. K-я порядковая статистика. Динамическое программирование. Задача о рюкзаке. Наибольшая возрастающая/убывающая подпоследовательность. 5 | 6 |

Второй семестр

7 | Дерево отрезков. Дерево Фенвика. Sparse Table. Многомерные структуры данных. Хеш-таблицы. Двоичное дерево поиска. AVL-дерево. Декартово дерево. Splay дерево. LCA. HLD. Центроидная декомпозиция. 8 | 9 |

Третий семестр

10 | Обход в глубину. Компоненты сильной связности. Конденсация графа. 2-SAT. Мосты и точки сочленения. Двусвязность. Эйлеровость. Обход в ширину. Алгоритмы Дейкстры и Форда-Беллмана. Алгоритм Флойда. Минимальное остовное дерево. Строки. Префикс-функция и Z-функция. Бор. Ахо-Корасик. Цифровой бор. Суффиксный массив. Корневые оптимизации. 11 | 12 |

Четвёртый семестр

13 | Паросочетания в двудольных графах. Паросочетания в произвольных графах. Потоки. Задача о назначениях. Линейное программирование. Вычислительная геометрия. Теория чисел. Быстрое преобразование Фурье. 14 | -------------------------------------------------------------------------------- /sem-1/problems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryag/ct-itmo-algorithms/2019c7d4928bb04fc3e0b7c6fdd4453dbeb35f9a/sem-1/problems.pdf -------------------------------------------------------------------------------- /sem-1/solutions/1A.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | 3 | public class QuickSort { 4 | 5 | public static void quickSort(int[] a, int left, int right) { 6 | if (left >= right) 7 | return; 8 | int oporElement = a[(left + right) / 2]; 9 | int i = left; 10 | int j = right; 11 | while (i <= j) { 12 | while (a[i] < oporElement) { 13 | i++; 14 | } 15 | while (a[j] > oporElement) { 16 | j--; 17 | } 18 | if (i <= j) { 19 | int swap = a[i]; 20 | a[i] = a[j]; 21 | a[j] = swap; 22 | i++; 23 | j--; 24 | } 25 | } 26 | if (left < j) 27 | quickSort(a, left, j); 28 | if (i < right) 29 | quickSort(a, i, right); 30 | } 31 | 32 | public static void main(String[] args) throws IOException { 33 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 34 | int n = Integer.parseInt(reader.readLine()); 35 | int[] a = new int[n]; 36 | String[] strs = reader.readLine().split(" "); 37 | for (int i = 0; i < n; i++) { 38 | a[i] = Integer.parseInt(strs[i]); 39 | } 40 | quickSort(a, 0, n - 1); 41 | for (int i = 0; i < n; i++) { 42 | System.out.print(a[i] + " "); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /sem-1/solutions/1B.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | 3 | public class KStatistic { 4 | 5 | public static int split(int[] a, int l, int r) { 6 | int x = a[r]; 7 | int i = l; 8 | for (int j = l; j < r; j++) { 9 | if (a[j] <= x) { 10 | int swap = a[i]; 11 | a[i] = a[j]; 12 | a[j] = swap; 13 | i++; 14 | } 15 | } 16 | int swap = a[i]; 17 | a[i] = a[r]; 18 | a[r] = swap; 19 | return i; 20 | } 21 | 22 | public static int kStat(int[] a, int l, int r, int k) { 23 | int m = split(a, l, r); 24 | if (m - l == k - 1) { 25 | return a[m]; 26 | } 27 | if (m - l > k - 1) { 28 | return kStat(a, l, m - 1, k); 29 | } 30 | return kStat(a, m + 1, r, k - m + l - 1); 31 | } 32 | 33 | public static void main(String[] args) throws IOException { 34 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 35 | String[] strs = reader.readLine().split(" "); 36 | int n = Integer.parseInt(strs[0]); 37 | int[] a = new int[n]; 38 | a[0] = Integer.parseInt(strs[1]); 39 | int k = Integer.parseInt(strs[2]); 40 | for (int i = 1; i < n; i++) { 41 | a[i] = (int) ((1_103_515_245 * (long)(a[i - 1]) + 12345) % 2147483648L); 42 | } 43 | System.out.println(kStat(a, 0, n - 1, k + 1)); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /sem-1/solutions/1C.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | 3 | public class AntiQuickSort { 4 | public static void main(String[] args) throws IOException { 5 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 6 | int n = Integer.parseInt(reader.readLine()); 7 | int[] a = new int[n]; 8 | for (int i = 0; i < n; i++) { 9 | a[i] = i + 1; 10 | } 11 | for (int i = 2; i < n; i++) { 12 | int swap = a[i]; 13 | a[i] = a[i/2]; 14 | a[i/2] = swap; 15 | } 16 | System.out.print(a[0]); 17 | for (int i = 1; i < n; i++) { 18 | System.out.print(" " + a[i]); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sem-1/solutions/1D.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | 3 | public class CountInversions { 4 | private static long countInversions; 5 | 6 | public static int[] sort(int[] a) { 7 | countInversions = 0; 8 | return sort(a, 0, a.length - 1); 9 | } 10 | 11 | static int[] sort(int[] a, int left, int right) { 12 | if (left > right - 1) { 13 | return new int[]{a[left]}; 14 | } 15 | int mid = left + (right - left) / 2; 16 | return merge(sort(a, left, mid), sort(a, mid + 1, right)); 17 | } 18 | 19 | static int[] merge(int[] a, int[] b) { 20 | int[] m = new int[a.length + b.length]; 21 | int aPos = 0; 22 | int bPos = 0; 23 | int mPos = 0; 24 | while ((aPos < a.length) && (bPos < b.length)) { 25 | if (a[aPos] <= b[bPos]) { 26 | m[mPos++] = a[aPos++]; 27 | } else { 28 | m[mPos++] = b[bPos++]; 29 | countInversions += (a.length - aPos); 30 | } 31 | } 32 | while (aPos < a.length) { 33 | m[mPos++] = a[aPos++]; 34 | } 35 | while (bPos < b.length) { 36 | m[mPos++] = b[bPos++]; 37 | } 38 | return m; 39 | } 40 | 41 | public static void main(String[] args) throws IOException { 42 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 43 | int n = Integer.parseInt(reader.readLine()); 44 | int[] a = new int[n]; 45 | String[] strs = reader.readLine().split(" "); 46 | for (int i = 0; i < n; i++) { 47 | a[i] = Integer.parseInt(strs[i]); 48 | } 49 | sort(a); 50 | System.out.println(countInversions); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /sem-1/solutions/1G.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | 3 | public class Med { 4 | 5 | public static void quickSort(int[] a, int left, int right) { 6 | if (left >= right) { 7 | return; 8 | } 9 | int oporElement = a[(left + right) / 2]; 10 | int i = left; 11 | int j = right; 12 | while (i <= j) { 13 | while (a[i] < oporElement) { 14 | i++; 15 | } 16 | while (a[j] > oporElement) { 17 | j--; 18 | } 19 | if (i <= j) { 20 | int swap = a[i]; 21 | a[i] = a[j]; 22 | a[j] = swap; 23 | i++; 24 | j--; 25 | } 26 | } 27 | if (left < j){ 28 | quickSort(a, left, j); 29 | } 30 | if (i < right) { 31 | quickSort(a, i, right); 32 | } 33 | } 34 | 35 | public static void main(String[] args) throws IOException { 36 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 37 | String[] first = reader.readLine().split(" "); 38 | int n = Integer.parseInt(first[0]); 39 | int m = Integer.parseInt(first[1]); 40 | int p = Integer.parseInt(first[2]); 41 | int[] a = new int[n]; 42 | String[] second = reader.readLine().split(" "); 43 | long liters = 0; 44 | boolean mesto = true; 45 | int j = 0; 46 | for (int i = 0; i < n; i++) { 47 | int med = Integer.parseInt(second[i]); 48 | if (med >= p) { 49 | int r = Math.min(m, med / p); 50 | liters += p * r; 51 | m -= r; 52 | med -= p * r; 53 | if (med > 0) { 54 | a[j] = med; 55 | j++; 56 | } 57 | } else { 58 | a[j] = med; 59 | j++; 60 | } 61 | if (m == 0) { 62 | mesto = false; 63 | break; 64 | } 65 | } 66 | if (mesto) { 67 | quickSort(a, 0, j - 1); 68 | for (int q = j - 1; q >= 0; q--) { 69 | liters += a[q]; 70 | m--; 71 | if (m == 0) { 72 | break; 73 | } 74 | } 75 | System.out.println(liters); 76 | } else { 77 | System.out.println(liters); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /sem-1/solutions/1H.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | 3 | public class Wsort { 4 | public static void main(String[] args) throws IOException { 5 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 6 | String[] strs = reader.readLine().split(" "); 7 | int n = Integer.parseInt(strs[0]); 8 | int m = Integer.parseInt(strs[1]); 9 | int k = Integer.parseInt(strs[2]); 10 | String[] words = new String[n]; 11 | for (int i = 0; i < n; i++) { 12 | words[i] = reader.readLine(); 13 | } 14 | int alphabet = 26; 15 | int stop = 0; 16 | for (int i = m - 1; i >= 0; i--) { 17 | String[] wss = new String[n]; 18 | int[] chr = new int[alphabet]; 19 | for (int j = 0; j < n; j++) { 20 | int curChr = words[j].charAt(i) - 97; 21 | chr[curChr]++; 22 | } 23 | int count = 0; 24 | for (int j = 0; j < alphabet; j++) { 25 | int swap = chr[j]; 26 | chr[j] = count; 27 | count += swap; 28 | } 29 | for (int j = 0; j < n; j++) { 30 | int curChr = words[j].charAt(i) - 97; 31 | wss[chr[curChr]] = words[j]; 32 | chr[curChr]++; 33 | } 34 | words = wss; 35 | stop++; 36 | if (stop == k) { 37 | break; 38 | } 39 | } 40 | for (String word : words) { 41 | System.out.println(word); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /sem-1/solutions/2A.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | 3 | public class Sortset { 4 | public static void main(String[] args) throws IOException { 5 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 6 | String[] first = reader.readLine().split(" "); 7 | int n = Integer.parseInt(first[0]); 8 | int m = Integer.parseInt(first[1]); 9 | int k = Integer.parseInt(first[2]); 10 | String[] strs = new String[k]; 11 | for (int i = 0; i < k; i++) { 12 | strs[i] = reader.readLine(); 13 | } 14 | boolean flag = true; 15 | for (int i = 0; i < (1 << n); i++) { 16 | int[] a = new int[n]; 17 | for (int j = 0; j < n; j++) { 18 | a[j] = (i >> j) & 1; 19 | } 20 | for (int j = 0; j < k; j++) { 21 | String[] str = strs[j].split(" "); 22 | int r = Integer.parseInt(str[0]); 23 | for (int o = 0; o < r; o++) { 24 | int max = Math.max(a[Integer.parseInt(str[1 + 2 * o]) - 1], a[Integer.parseInt(str[2 + 2 * o]) - 1]); 25 | int min = Math.min(a[Integer.parseInt(str[1 + 2 * o]) - 1], a[Integer.parseInt(str[2 + 2 * o]) - 1]); 26 | a[Math.min(Integer.parseInt(str[1 + 2 * o]) - 1, Integer.parseInt(str[2 + 2 * o]) - 1)] = min; 27 | a[Math.max(Integer.parseInt(str[1 + 2 * o]) - 1, Integer.parseInt(str[2 + 2 * o]) - 1)] = max; 28 | } 29 | } 30 | for (int j = 0; j < a.length - 1; j++) { 31 | if (a[j] > a[j+1]) { 32 | flag = false; 33 | break; 34 | } 35 | } 36 | if (!flag) { 37 | break; 38 | } 39 | } 40 | if (flag) { 41 | System.out.println("Yes"); 42 | } else { 43 | System.out.println("No"); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /sem-1/solutions/3A.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | 3 | public class BinarySearch { 4 | public static void main(String[] args) throws IOException { 5 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 6 | String[] line1 = reader.readLine().split(" "); 7 | String[] line2 = reader.readLine().split(" "); 8 | String[] line3 = reader.readLine().split(" "); 9 | reader.close(); 10 | 11 | int n = Integer.parseInt(line1[0]); 12 | int k = Integer.parseInt(line1[1]); 13 | int[] a = new int[n]; 14 | for (int i = 0; i < n; i++) { 15 | a[i] = Integer.parseInt(line2[i]); 16 | } 17 | 18 | int t = 0; 19 | while (t < k) { 20 | int l = -1; 21 | int r = n; 22 | int findElement = Integer.parseInt(line3[t]); 23 | if (findElement < a[0] || findElement > a[n - 1]) { 24 | System.out.println("NO"); 25 | } else { 26 | while (r > l + 1) { 27 | int m = (r + l) / 2; 28 | if (a[m] <= findElement) { 29 | l = m; 30 | } else { 31 | r = m; 32 | } 33 | } 34 | if (a[l] == findElement) { 35 | System.out.println("YES"); 36 | } else { 37 | System.out.println("NO"); 38 | } 39 | } 40 | t++; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /sem-1/solutions/3B.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | 3 | public class LeftAndRightBinarySearch { 4 | public static void main(String[] args) throws IOException { 5 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 6 | String[] line1 = reader.readLine().split(" "); 7 | String[] line2 = reader.readLine().split(" "); 8 | String[] line3 = reader.readLine().split(" "); 9 | reader.close(); 10 | 11 | int n = Integer.parseInt(line1[0]); 12 | int m = Integer.parseInt(line1[1]); 13 | long[] a = new long[n]; 14 | for (int i = 0; i < n; i++) { 15 | a[i] = Integer.parseInt(line2[i]); 16 | } 17 | 18 | int t = 0; 19 | while (t < m) { 20 | int l = -1; 21 | int r = n; 22 | long findElement = Long.parseLong(line3[t]); 23 | while (r > l + 1) { 24 | int med = (l + r) / 2; 25 | if (a[med] < findElement) { 26 | l = med; 27 | } else { 28 | r = med; 29 | } 30 | } 31 | if (r == n || findElement < a[0] || a[r] != findElement) { 32 | System.out.println("0"); 33 | } else { 34 | int fOut = r + 1; 35 | l = -1; 36 | r = n; 37 | while (r > l + 1) { 38 | int med = (l + r) / 2; 39 | if (a[med] <= findElement) { 40 | l = med; 41 | } else { 42 | r = med; 43 | } 44 | } 45 | int sOut = l + 1; 46 | System.out.println(fOut + " " + sOut); 47 | } 48 | t++; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /sem-1/solutions/3C.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | 3 | public class Garland { 4 | public static int n; 5 | public static double[] a; 6 | 7 | public static boolean isCorrect(double h) { 8 | a[1] = h; 9 | for (int i = 2; i < n; i++) { 10 | a[i] = 2 * a[i - 1] - a[i - 2] + 2; 11 | } 12 | for (int i = 0; i < n; i++) { 13 | if (a[i] <= 0) { 14 | return false; 15 | } 16 | } 17 | return true; 18 | } 19 | 20 | public static void main(String[] args) throws IOException { 21 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 22 | String[] line = reader.readLine().split(" "); 23 | n = Integer.parseInt(line[0]); 24 | a = new double[n]; 25 | a[0] = Double.parseDouble(line[1]); 26 | 27 | double l = 0; 28 | double r = 2000; 29 | for (int i = 0; i < 1000; i++) { 30 | double mid = (l + r) / 2; 31 | if (isCorrect(mid)) { 32 | r = mid; 33 | } else { 34 | l = mid; 35 | } 36 | } 37 | isCorrect(r); 38 | System.out.printf("%.2f", a[n - 1]); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /sem-1/solutions/3F.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | 3 | public class Wires { 4 | public static int k; 5 | public static int n; 6 | public static int[] a; 7 | 8 | public static boolean isCorrect(int segmentLength) { 9 | int count = 0; 10 | for (int i = 0; i < n; i++) { 11 | count += a[i] / segmentLength; 12 | if (count >= k) { 13 | return true; 14 | } 15 | } 16 | return false; 17 | } 18 | 19 | public static void main(String[] args) throws IOException { 20 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 21 | String[] line1 = reader.readLine().split(" "); 22 | n = Integer.parseInt(line1[0]); 23 | k = Integer.parseInt(line1[1]); 24 | a = new int[n]; 25 | int max = 0; 26 | int min = 0; 27 | for (int i = 0; i < n; i++) { 28 | a[i] = Integer.parseInt(reader.readLine()); 29 | if (a[i] > max) { 30 | max = a[i]; 31 | } 32 | if (a[i] < min) { 33 | min = a[i]; 34 | } 35 | } 36 | reader.close(); 37 | 38 | int result = 0; 39 | int l = min; 40 | int r = max; 41 | while (r - l > 10) { 42 | int median = (l + r) / 2; 43 | if (isCorrect(median)) { 44 | l = median; 45 | result = l; 46 | } else { 47 | r = median; 48 | } 49 | } 50 | for (int i = Math.max(l, 1); i <= r; i++) { 51 | if (isCorrect(i)) { 52 | result = i; 53 | } 54 | } 55 | System.out.println(result); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /sem-1/solutions/3G.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | 3 | public class AmongThem { 4 | public static long n; 5 | public static long m; 6 | 7 | public static boolean winImpostors() { 8 | return ((n * n + n) / 2) >= m; 9 | } 10 | 11 | public static boolean possibleRounds(long count) { 12 | return (n * count - ((count * (count - 1)) / 2)) >= m; 13 | } 14 | 15 | public static void main(String[] args) throws IOException { 16 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 17 | int t = Integer.parseInt(reader.readLine()); 18 | for (int i = 0; i < t; i++) { 19 | String[] line = reader.readLine().split(" "); 20 | n = Long.parseLong(line[0]); 21 | m = Long.parseLong(line[1]); 22 | if (!winImpostors()) { 23 | System.out.println("Crewmates"); 24 | System.out.println(n); 25 | } else { 26 | long result = 0; 27 | long l = 1; 28 | long r = n; 29 | while (r - l > 100) { 30 | long med = (l + r) / 2; 31 | if (possibleRounds(med)) { 32 | result = med; 33 | r = med; 34 | } else { 35 | l = med; 36 | } 37 | } 38 | for (long j = l; j <= r; j++) { 39 | if (possibleRounds(j)) { 40 | result = j; 41 | break; 42 | } 43 | } 44 | System.out.println("Impostors"); 45 | System.out.println(result); 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /sem-1/solutions/3H.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | 3 | public class CricketField { 4 | public static int n; 5 | public static int w; 6 | public static int h; 7 | public static int[] xd; 8 | public static int[] yd; 9 | 10 | public static int[] possibleSquare(int length) { 11 | int score; 12 | for (int y = 0; y < h - length + 1; y++) { 13 | int x = 0; 14 | while (x < w - length + 1) { 15 | score = 0; 16 | for (int tree = 0; tree < n; tree++) { 17 | if (xd[tree] < x + length && xd[tree] > x && yd[tree] < y + length && yd[tree] > y) { 18 | x = xd[tree]; 19 | break; 20 | } 21 | score++; 22 | } 23 | if (score == n) { 24 | return new int[]{x, y}; 25 | } 26 | } 27 | } 28 | return new int[]{-1, -1}; 29 | } 30 | 31 | public static void main(String[] args) throws IOException { 32 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 33 | String[] line = reader.readLine().split(" "); 34 | n = Integer.parseInt(line[0]); 35 | w = Integer.parseInt(line[1]); 36 | h = Integer.parseInt(line[2]); 37 | xd = new int[n]; 38 | yd = new int[n]; 39 | for (int i = 0; i < n; i++) { 40 | String[] derevo = reader.readLine().split(" "); 41 | xd[i] = Integer.parseInt(derevo[0]); 42 | yd[i] = Integer.parseInt(derevo[1]); 43 | } 44 | int finallyX = 0; 45 | int finallyY = 0; 46 | int finallyLength = 0; 47 | int left = 0; 48 | int right = Math.min(w, h); 49 | while (right - left > 5) { 50 | int median = (left + right) / 2; 51 | int[] a = possibleSquare(median); 52 | if (a[0] != -1) { 53 | finallyX = a[0]; 54 | finallyY = a[1]; 55 | finallyLength = median; 56 | left = median; 57 | } else { 58 | right = median; 59 | } 60 | } 61 | for (int i = right; i >= left; i--) { 62 | int[] a = possibleSquare(i); 63 | if (a[0] != -1) { 64 | finallyX = a[0]; 65 | finallyY = a[1]; 66 | finallyLength = i; 67 | break; 68 | } 69 | } 70 | System.out.println(finallyX + " " + finallyY + " " + finallyLength); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /sem-1/solutions/4A.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | 3 | public class SimpleStack { 4 | public static int[] st; 5 | public static int size; 6 | 7 | public static String push(int n) { 8 | st[size] = n; 9 | size++; 10 | return "ok"; 11 | } 12 | 13 | public static int pop() { 14 | int result = st[size - 1]; 15 | size--; 16 | return result; 17 | } 18 | 19 | public static int back() { 20 | return st[size - 1]; 21 | } 22 | 23 | public static int size() { 24 | return size; 25 | } 26 | 27 | public static String clear() { 28 | size = 0; 29 | return "ok"; 30 | } 31 | 32 | public static String exit() { 33 | return "bye"; 34 | } 35 | 36 | public static void main(String[] args) throws IOException { 37 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 38 | st = new int[100]; 39 | size = 0; 40 | while (true) { 41 | String line = reader.readLine(); 42 | if (line == null) { 43 | return; 44 | } 45 | String[] lines = line.split(" "); 46 | if (lines[0].equals("push")) { 47 | System.out.println(push(Integer.parseInt(lines[1]))); 48 | } 49 | if (lines[0].equals("pop")) { 50 | System.out.println(pop()); 51 | } 52 | if (lines[0].equals("back")) { 53 | System.out.println(back()); 54 | } 55 | if (lines[0].equals("size")) { 56 | System.out.println(size()); 57 | } 58 | if (lines[0].equals("clear")) { 59 | System.out.println(clear()); 60 | } 61 | if (lines[0].equals("exit")) { 62 | System.out.println(exit()); 63 | } 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /sem-1/solutions/4B.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | 3 | public class SimpleQueue { 4 | public static int[] q; 5 | public static int size; 6 | public static int head; 7 | public static int tail; 8 | 9 | public static String push(int n) { 10 | q[tail % 100] = n; 11 | tail = (tail + 1) % 100; 12 | size++; 13 | return "ok"; 14 | } 15 | 16 | public static int pop() { 17 | int result = q[head % 100]; 18 | head = (head + 1) % 100; 19 | size--; 20 | return result; 21 | } 22 | 23 | public static int front() { 24 | return q[head % 100]; 25 | } 26 | 27 | public static int size() { 28 | return size; 29 | } 30 | 31 | public static String clear() { 32 | size = 0; 33 | head = 0; 34 | tail = 0; 35 | return "ok"; 36 | } 37 | 38 | public static String exit() { 39 | return "bye"; 40 | } 41 | 42 | public static void main(String[] args) throws IOException { 43 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 44 | q = new int[100]; 45 | size = 0; 46 | head = 0; 47 | tail = 0; 48 | while (true) { 49 | String line = reader.readLine(); 50 | if (line == null) { 51 | return; 52 | } 53 | String[] lines = line.split(" "); 54 | if (lines[0].equals("push")) { 55 | System.out.println(push(Integer.parseInt(lines[1]))); 56 | } 57 | if (lines[0].equals("pop")) { 58 | System.out.println(pop()); 59 | } 60 | if (lines[0].equals("front")) { 61 | System.out.println(front()); 62 | } 63 | if (lines[0].equals("size")) { 64 | System.out.println(size()); 65 | } 66 | if (lines[0].equals("clear")) { 67 | System.out.println(clear()); 68 | } 69 | if (lines[0].equals("exit")) { 70 | System.out.println(exit()); 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /sem-1/solutions/4C.py: -------------------------------------------------------------------------------- 1 | s = input() 2 | try: 3 | result = eval(s) 4 | print(result) 5 | except SyntaxError: 6 | print("WRONG") 7 | except NameError: 8 | print("WRONG") -------------------------------------------------------------------------------- /sem-1/solutions/4D.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.util.*; 3 | 4 | public class Histogramm { 5 | public static void main(String[] args) throws IOException { 6 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 7 | String[] line = reader.readLine().split(" "); 8 | int n = Integer.parseInt(line[0]); 9 | int[] a = new int[n]; 10 | for (int i = 0; i < n; i++) { 11 | a[i] = Integer.parseInt(line[i + 1]); 12 | } 13 | int[] len = new int[n]; 14 | long curProd; 15 | long maxProd = 0; 16 | Stack value = new Stack<>(); 17 | Stack ind = new Stack<>(); 18 | int size = 0; 19 | int temp = 0; 20 | for (int i = 0; i < n; i++) { 21 | while (size != 0 && a[i] <= value.peek()) { 22 | value.pop(); 23 | ind.pop(); 24 | size--; 25 | } 26 | if (size > 0) { 27 | temp = ind.peek(); 28 | } 29 | value.push(a[i]); 30 | ind.push(i); 31 | size++; 32 | if (size == 1) { 33 | len[i] = i; 34 | } else { 35 | len[i] = i - temp - 1; 36 | } 37 | } 38 | value.clear(); 39 | ind.clear(); 40 | size = 0; 41 | for (int i = n - 1; i >= 0; i--) { 42 | while (size != 0 && a[i] <= value.peek()) { 43 | value.pop(); 44 | ind.pop(); 45 | size--; 46 | } 47 | if (size > 0) { 48 | temp = ind.peek(); 49 | } 50 | value.push(a[i]); 51 | ind.push(i); 52 | size++; 53 | if (size == 1) { 54 | len[i] = len[i] + n - i; 55 | } else { 56 | len[i] = len[i] + temp - i; 57 | } 58 | } 59 | for (int i = 0; i < n; i++) { 60 | curProd = (long) a[i] * len[i]; 61 | maxProd = Math.max(maxProd, curProd); 62 | } 63 | System.out.println(maxProd); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /sem-1/solutions/4E.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.util.Stack; 3 | 4 | public class Colonizators2 { 5 | 6 | public static void f(int[] a, int[] first, boolean[] firstFlag, Stack stValue, Stack stIndex, int i) { 7 | while (!stValue.empty() && a[i] >= stValue.peek()) { 8 | stValue.pop(); 9 | stIndex.pop(); 10 | } 11 | if (stValue.empty()) { 12 | first[i] = 0; 13 | } else { 14 | if (a[i] > 0) { 15 | first[stIndex.peek()]++; 16 | firstFlag[i] = true; 17 | } 18 | } 19 | if (a[i] > 0) { 20 | stValue.push(a[i]); 21 | stIndex.push(i); 22 | } 23 | } 24 | 25 | public static void main(String[] args) throws IOException { 26 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 27 | int n = Integer.parseInt(reader.readLine()); 28 | int[] a = new int[n]; 29 | String[] line = reader.readLine().split(" "); 30 | for (int i = 0; i < n; i++) { 31 | a[i] = Integer.parseInt(line[i]); 32 | } 33 | int[] first = new int[n]; 34 | boolean[] firstFlag = new boolean[n]; 35 | Stack stValue = new Stack<>(); 36 | Stack stIndex = new Stack<>(); 37 | for (int i = n - 1; i >= 0; i--) { 38 | f(a, first, firstFlag, stValue, stIndex, i); 39 | } 40 | for (int i = 0; i < n; i++) { 41 | if (firstFlag[i]) { 42 | a[i]--; 43 | } 44 | a[i] += first[i]; 45 | } 46 | stValue.clear(); 47 | stIndex.clear(); 48 | int[] second = new int[n]; 49 | boolean[] secondFlag = new boolean[n]; 50 | for (int i = 0; i < n; i++) { 51 | f(a, second, secondFlag, stValue, stIndex, i); 52 | } 53 | int maxCards = 0; 54 | for (int i = 0; i < n; i++) { 55 | if (secondFlag[i]) { 56 | a[i]--; 57 | } 58 | a[i] += second[i]; 59 | if (a[i] > maxCards) { 60 | maxCards = a[i]; 61 | } 62 | } 63 | System.out.println(maxCards); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /sem-1/solutions/4G.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.util.*; 3 | 4 | public class Pianiwa { 5 | public static void main(String[] args) throws IOException { 6 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 7 | ArrayDeque player1 = new ArrayDeque<>(); 8 | int countCards1 = 5; 9 | ArrayDeque player2 = new ArrayDeque<>(); 10 | int countCards2 = 5; 11 | String[] line1 = reader.readLine().split(" "); 12 | String[] line2 = reader.readLine().split(" "); 13 | for (int i = 0; i < line1.length; i++) { 14 | player1.addLast(Integer.parseInt(line1[i])); 15 | player2.addLast(Integer.parseInt(line2[i])); 16 | } 17 | int countRound = 0; 18 | int temp1; 19 | int temp2; 20 | while (true) { 21 | temp1 = player1.pollFirst(); 22 | countCards1--; 23 | temp2 = player2.pollFirst(); 24 | countCards2--; 25 | if ((temp1 == 0 && temp2 == 9) || (temp1 > temp2 && !(temp2 == 0 && temp1 == 9))) { 26 | player1.addLast(temp1); 27 | player1.addLast(temp2); 28 | countCards1 += 2; 29 | } else { 30 | player2.addLast(temp1); 31 | player2.addLast(temp2); 32 | countCards2 += 2; 33 | } 34 | countRound++; 35 | if (countCards1 == 0) { 36 | System.out.println("second" + " " + countRound); 37 | return; 38 | } 39 | if (countCards2 == 0) { 40 | System.out.println("first" + " " + countRound); 41 | return; 42 | } 43 | if (countRound == 1_000_000) { 44 | System.out.println("botva"); 45 | return; 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /sem-1/solutions/4H.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int main() { 8 | int n; 9 | cin >> n; 10 | int k; 11 | cin >> k; 12 | vector a(n); 13 | for (int i = 0; i < n; i++) { 14 | int x; 15 | cin >> x; 16 | a[i] = x; 17 | } 18 | deque value; 19 | deque ind; 20 | int size = 0; 21 | for (int i = 0; i < k; i++) { 22 | while (size != 0 && a[i] < value.back()) { 23 | value.pop_back(); 24 | ind.pop_back(); 25 | size--; 26 | } 27 | value.push_back(a[i]); 28 | ind.push_back(i); 29 | size++; 30 | } 31 | cout << value.front() << '\n'; 32 | for (int i = k; i < n; i++) { 33 | while (size != 0 && a[i] < value.back()) { 34 | value.pop_back(); 35 | ind.pop_back(); 36 | size--; 37 | } 38 | value.push_back(a[i]); 39 | ind.push_back(i); 40 | size++; 41 | if (ind.front() < i - k + 1) { 42 | value.pop_front(); 43 | ind.pop_front(); 44 | size--; 45 | } 46 | cout << value.front() << '\n'; 47 | } 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /sem-1/solutions/4I.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | vector a(300000); 6 | long long value = 0; 7 | int head = 0; 8 | int tail = 0; 9 | int mod = 300000; 10 | 11 | void add(long long x) { 12 | a[tail % mod] = x - value; 13 | tail = (tail + 1) % mod; 14 | } 15 | 16 | void blame(long long x, long long y) { 17 | a[head % mod] = a[head % mod] + x - y; 18 | value += y; 19 | } 20 | 21 | long long out() { 22 | long long result = a[head % mod] + value; 23 | head = (head + 1) % mod; 24 | return result; 25 | } 26 | 27 | int main() { 28 | int n; 29 | cin >> n; 30 | int f; 31 | long long s; 32 | long long t; 33 | for (int i = 0; i < n; i++) { 34 | cin >> f; 35 | if (f == 1) { 36 | cin >> s; 37 | add(s); 38 | } 39 | if (f == 2) { 40 | cin >> s; 41 | cin >> t; 42 | blame(s, t); 43 | } 44 | if (f == 3) { 45 | long long ans = out(); 46 | cout << ans << '\n'; 47 | } 48 | } 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /sem-1/solutions/5A.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.IOException; 3 | import java.io.InputStreamReader; 4 | 5 | public class Zaichik { 6 | public static void main(String[] args) throws IOException { 7 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 8 | int n = Integer.parseInt(reader.readLine()); 9 | String s = reader.readLine(); 10 | int[] dp = new int[n]; 11 | dp[0] = 0; 12 | for (int i = 1; i < n; i++) { 13 | if (s.charAt(i) == 'w') { 14 | dp[i] = -1; 15 | } else { 16 | int max = -1; 17 | if (i - 5 >= 0 && dp[i - 5] != -1) { 18 | max = Math.max(max, dp[i - 5]); 19 | } 20 | if (i - 3 >= 0 && dp[i - 3] != -1) { 21 | max = Math.max(max, dp[i - 3]); 22 | } 23 | if (dp[i - 1] != -1) { 24 | max = Math.max(max, dp[i - 1]); 25 | } 26 | if (max == -1) { 27 | dp[i] = -1; 28 | } else { 29 | if (s.charAt(i) == '"') { 30 | dp[i] = max + 1; 31 | } 32 | if (s.charAt(i) == '.') { 33 | dp[i] = max; 34 | } 35 | } 36 | } 37 | } 38 | System.out.println(dp[n - 1]); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /sem-1/solutions/5B.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.IOException; 3 | import java.io.InputStreamReader; 4 | 5 | public class TurtleAndCoins { 6 | public static void main(String[] args) throws IOException { 7 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 8 | String[] line = reader.readLine().split(" "); 9 | int n = Integer.parseInt(line[0]); 10 | int m = Integer.parseInt(line[1]); 11 | int[][] cell = new int[n][m]; 12 | for (int i = 0; i < n; i++) { 13 | line = reader.readLine().split(" "); 14 | for (int j = 0; j < m; j++) { 15 | cell[i][j] = Integer.parseInt(line[j]); 16 | } 17 | } 18 | int[][] dp = new int[n][m]; 19 | dp[0][0] = cell[0][0]; 20 | for (int j = 1; j < m; j++) { 21 | dp[0][j] = cell[0][j] + dp[0][j - 1]; 22 | } 23 | for (int i = 1; i < n; i++) { 24 | dp[i][0] = cell[i][0] + dp[i - 1][0]; 25 | } 26 | for (int i = 1; i < n; i++) { 27 | for (int j = 1; j < m; j++) { 28 | if (dp[i - 1][j] >= dp[i][j - 1]) { 29 | dp[i][j] = cell[i][j] + dp[i - 1][j]; 30 | } else { 31 | dp[i][j] = cell[i][j] + dp[i][j - 1]; 32 | } 33 | } 34 | } 35 | System.out.println(dp[n - 1][m - 1]); 36 | int i = n - 1; 37 | int j = m - 1; 38 | StringBuilder result = new StringBuilder(); 39 | while (i != 0 || j != 0) { 40 | if (i - 1 >= 0 && dp[i][j] - cell[i][j] == dp[i - 1][j]) { 41 | i--; 42 | result.append('D'); 43 | } else { 44 | j--; 45 | result.append('R'); 46 | } 47 | } 48 | System.out.println(result.reverse()); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /sem-1/solutions/5C.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.IOException; 3 | import java.io.InputStreamReader; 4 | 5 | public class LIS { 6 | public static void main(String[] args) throws IOException { 7 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 8 | int n = Integer.parseInt(reader.readLine()); 9 | int[] a = new int[n]; 10 | String[] line = reader.readLine().split(" "); 11 | for (int i = 0; i < n; i++) { 12 | a[i] = Integer.parseInt(line[i]); 13 | } 14 | int[] dp = new int[n]; 15 | int[] prev = new int[n]; 16 | dp[0] = 1; 17 | prev[0] = -1; 18 | int max; 19 | int ind; 20 | for (int i = 1; i < n; i++) { 21 | max = 0; 22 | ind = -1; 23 | for (int j = 0; j < i; j++) { 24 | if (a[j] < a[i] && dp[j] > max) { 25 | max = dp[j]; 26 | ind = j; 27 | } 28 | } 29 | dp[i] = max + 1; 30 | prev[i] = ind; 31 | } 32 | max = 0; 33 | ind = 0; 34 | for (int i = 0; i < n; i++) { 35 | if (dp[i] > max) { 36 | max = dp[i]; 37 | ind = i; 38 | } 39 | } 40 | StringBuilder result = new StringBuilder(); 41 | result.insert(0, a[ind]); 42 | result.insert(0, " "); 43 | ind = prev[ind]; 44 | while (ind != -1) { 45 | result.insert(0, a[ind]); 46 | result.insert(0, " "); 47 | ind = prev[ind]; 48 | } 49 | System.out.println(max); 50 | result.delete(0, 1); 51 | System.out.println(result); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /sem-1/solutions/5D.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.IOException; 3 | import java.io.InputStreamReader; 4 | 5 | public class LCS { 6 | public static void main(String[] args) throws IOException { 7 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 8 | int n = Integer.parseInt(reader.readLine()); 9 | int[] a = new int[n]; 10 | String[] line = reader.readLine().split(" "); 11 | for (int i = 0; i < n; i++) { 12 | a[i] = Integer.parseInt(line[i]); 13 | } 14 | int m = Integer.parseInt(reader.readLine()); 15 | int[] b = new int[m]; 16 | line = reader.readLine().split(" "); 17 | for (int i = 0; i < m; i++) { 18 | b[i] = Integer.parseInt(line[i]); 19 | } 20 | int[][] dp = new int[n][m]; 21 | for (int i = 0; i < n; i++) { 22 | for (int j = 0; j < m; j++) { 23 | if (a[i] == b[j]) { 24 | dp[i][j] = ((i - 1 >= 0 && j - 1 >= 0) ? dp[i - 1][j - 1] : 0) + 1; 25 | } else { 26 | if (i - 1 >= 0) { 27 | if (j - 1 >= 0) { 28 | dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]); 29 | } else { 30 | dp[i][j] = dp[i - 1][j]; 31 | } 32 | } else { 33 | if (j - 1 >= 0) { 34 | dp[i][j] = dp[i][j - 1]; 35 | } else { 36 | dp[i][j] = 0; 37 | } 38 | } 39 | } 40 | } 41 | } 42 | int i = n - 1; 43 | int j = m - 1; 44 | StringBuilder result = new StringBuilder(); 45 | while (i >= 0 || j >= 0) { 46 | if (i >= 0 && j >= 0 && a[i] == b[j]) { 47 | result.insert(0, a[i]); 48 | result.insert(0, " "); 49 | i--; 50 | j--; 51 | } else { 52 | if (i - 1 >= 0) { 53 | if (j - 1 >= 0) { 54 | if (dp[i - 1][j] >= dp[i][j - 1]) { 55 | i--; 56 | } else { 57 | j--; 58 | } 59 | } else { 60 | i--; 61 | } 62 | } else { 63 | if (j - 1 >= 0) { 64 | j--; 65 | } else { 66 | break; 67 | } 68 | } 69 | } 70 | } 71 | System.out.println(dp[n - 1][m - 1]); 72 | result.delete(0, 1); 73 | System.out.println(result); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /sem-1/solutions/5E.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.IOException; 3 | import java.io.InputStreamReader; 4 | 5 | public class Levenshtain { 6 | public static void main(String[] args) throws IOException { 7 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 8 | String a = reader.readLine(); 9 | String b = reader.readLine(); 10 | int n = a.length(); 11 | int m = b.length(); 12 | int[][] dp = new int[n + 1][m + 1]; 13 | for (int i = 0; i <= n; i++) { 14 | for (int j = 0; j <= m; j++) { 15 | if (i == 0 || j == 0) { 16 | dp[i][j] = (i == 0) ? j : i; 17 | } else { 18 | if (a.charAt(i - 1) == b.charAt(j - 1)) { 19 | dp[i][j] = dp[i - 1][j - 1]; 20 | } else { 21 | dp[i][j] = Math.min(dp[i - 1][j - 1] + 1, dp[i - 1][j] + 1); 22 | dp[i][j] = Math.min(dp[i][j], dp[i][j - 1] + 1); 23 | } 24 | } 25 | } 26 | } 27 | System.out.println(dp[n][m]); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /sem-1/solutions/5G.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.IOException; 3 | import java.io.InputStreamReader; 4 | 5 | public class kriper2004 { 6 | public static void main(String[] args) throws IOException { 7 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 8 | String s = reader.readLine(); 9 | int n = Integer.parseInt(reader.readLine()); 10 | boolean flag = true; 11 | for (int i = 0; i < s.length() - 1; i++) { 12 | if ((int) s.charAt(i) + 1 == (int) s.charAt(i + 1)) { 13 | System.out.println(0); 14 | flag = false; 15 | break; 16 | } 17 | } 18 | if (flag) { 19 | if (s.length() == n) { 20 | System.out.println(1); 21 | } else { 22 | int[][] dp = new int[n][26]; 23 | dp[s.length() - 1][s.charAt(s.length() - 1) - 97] = 1; 24 | for (int i = s.length(); i < n; i++) { 25 | for (int j = 0; j < 26; j++) { 26 | for (int q = 0; q < 26; q++) { 27 | if (q + 1 != j) { 28 | dp[i][j] = (dp[i][j] + dp[i - 1][q]) % 998244353; 29 | } 30 | } 31 | } 32 | } 33 | int result = 0; 34 | for (int i = 0; i < 26; i++) { 35 | result += dp[n - 1][i]; 36 | result %= 998244353; 37 | } 38 | System.out.println(result); 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /sem-1/solutions/7A.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.IOException; 3 | import java.io.InputStreamReader; 4 | import java.util.ArrayList; 5 | import java.util.HashSet; 6 | import java.util.List; 7 | import java.util.Set; 8 | 9 | public class CollectExp { 10 | public static List> ls = new ArrayList<>(); 11 | public static int[] exp; 12 | public static int[] newExp; 13 | public static int[] p; 14 | public static int n; 15 | 16 | public static int find(int x) { 17 | if (p[x] != x) { 18 | p[x] = find(p[x]); 19 | } 20 | return p[x]; 21 | } 22 | 23 | public static void join(int x, int y) { 24 | x = find(x); 25 | y = find(y); 26 | for (Integer i : ls.get(x)) { 27 | exp[i] += newExp[x] - newExp[y]; 28 | } 29 | p[x] = y; 30 | ls.get(y).addAll(ls.get(x)); 31 | } 32 | 33 | public static void add(int x, int v) { 34 | x = find(x); 35 | newExp[x] += v; 36 | } 37 | 38 | public static void get(int x) { 39 | System.out.println(exp[x] + newExp[find(x)]); 40 | } 41 | 42 | public static void joinLess(int x, int y) { 43 | x = find(x); 44 | y = find(y); 45 | if (ls.get(x).size() <= ls.get(y).size()) { 46 | join(x, y); 47 | } else { 48 | join(y, x); 49 | } 50 | } 51 | 52 | public static void main(String[] args) throws IOException { 53 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 54 | String[] line = reader.readLine().split(" "); 55 | n = Integer.parseInt(line[0]); 56 | int m = Integer.parseInt(line[1]); 57 | exp = new int[n]; 58 | newExp = new int[n]; 59 | p = new int[n]; 60 | for (int i = 0; i < n; i++) { 61 | Set temp = new HashSet<>(); 62 | temp.add(i); 63 | ls.add(temp); 64 | p[i] = i; 65 | } 66 | for (int i = 0; i < m; i++) { 67 | line = reader.readLine().split(" "); 68 | if (line[0].equals("join")) { 69 | joinLess(Integer.parseInt(line[1]) - 1, Integer.parseInt(line[2]) - 1); 70 | } else if (line[0].equals("add")) { 71 | add(Integer.parseInt(line[1]) - 1, Integer.parseInt(line[2])); 72 | } else { 73 | get(Integer.parseInt(line[1]) - 1); 74 | } 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /sem-1/solutions/7B.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.IOException; 3 | import java.io.InputStreamReader; 4 | 5 | public class CuttingGraph { 6 | public static int[] p; 7 | 8 | public static int find(int x) { 9 | if (p[x] != x) { 10 | p[x] = find(p[x]); 11 | } 12 | return p[x]; 13 | } 14 | 15 | public static void join(int x, int y) { 16 | x = find(x); 17 | y = find(y); 18 | p[x] = y; 19 | } 20 | 21 | public static boolean ask(int x, int y) { 22 | return find(x) == find(y); 23 | } 24 | 25 | public static void main(String[] args) throws IOException { 26 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 27 | String[] line = reader.readLine().split(" "); 28 | int n = Integer.parseInt(line[0]); 29 | int m = Integer.parseInt(line[1]); 30 | int k = Integer.parseInt(line[2]); 31 | p = new int[n]; 32 | for (int i = 0; i < n; i++) { 33 | p[i] = i; 34 | } 35 | String[] answers = new String[k - m]; 36 | for (int i = 0; i < m; i++) { 37 | reader.readLine(); 38 | } 39 | String[] action = new String[k]; 40 | for (int i = 0; i < k; i++) { 41 | action[k - i - 1] = reader.readLine(); 42 | } 43 | int count = 0; 44 | for (int i = 0; i < k; i++) { 45 | String[] s = action[i].split(" "); 46 | if (s[0].equals("ask")) { 47 | if (ask(Integer.parseInt(s[1]) - 1, Integer.parseInt(s[2]) - 1)) { 48 | answers[k - m - count - 1] = "YES"; 49 | } else { 50 | answers[k - m - count - 1] = "NO"; 51 | } 52 | count++; 53 | } else { 54 | join(Integer.parseInt(s[1]) - 1, Integer.parseInt(s[2]) - 1); 55 | } 56 | } 57 | for (String s : answers) { 58 | System.out.println(s); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /sem-1/solutions/7C.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.IOException; 3 | import java.io.InputStreamReader; 4 | 5 | public class Company { 6 | public static int[] p; 7 | public static int[] r; 8 | 9 | public static int find(int x) { 10 | if (p[x] != x) { 11 | p[x] = find(p[x]); 12 | } 13 | return p[x]; 14 | } 15 | 16 | public static void team(int x, int y) { 17 | x = find(x); 18 | y = find(y); 19 | p[x] = y; 20 | } 21 | 22 | public static boolean ask(int x, int y) { 23 | return find(x) == find(y); 24 | } 25 | 26 | public static void main(String[] args) throws IOException { 27 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 28 | String[] line = reader.readLine().split(" "); 29 | int n = Integer.parseInt(line[0]); 30 | int q = Integer.parseInt(line[1]); 31 | p = new int[n]; 32 | r = new int[n]; 33 | for (int i = 0; i < n; i++) { 34 | p[i] = i; 35 | r[i] = i + 1; 36 | } 37 | r[n - 1] = Integer.MAX_VALUE; 38 | for (int i = 0; i < q; i++) { 39 | line = reader.readLine().split(" "); 40 | int type = Integer.parseInt(line[0]); 41 | if (type == 1) { 42 | team(Integer.parseInt(line[1]) - 1, Integer.parseInt(line[2]) - 1); 43 | } else { 44 | if (type == 2) { 45 | int prev = Integer.parseInt(line[1]) - 1; 46 | int cur = prev + 1; 47 | while (cur <= Integer.parseInt(line[2]) - 1) { 48 | int parentPrev = p[prev]; 49 | int parentCur = p[cur]; 50 | if (parentPrev == parentCur) { 51 | int tempCur = cur; 52 | cur = r[cur]; 53 | r[tempCur] = r[Integer.parseInt(line[2]) - 1]; 54 | continue; 55 | } 56 | int tempCur = cur; 57 | team(parentPrev, parentCur); 58 | prev = cur; 59 | cur = r[cur]; 60 | r[tempCur] = r[Integer.parseInt(line[2]) - 1]; 61 | } 62 | } else { 63 | if (ask(Integer.parseInt(line[1]) - 1, Integer.parseInt(line[2]) - 1)) { 64 | System.out.println("YES"); 65 | } else { 66 | System.out.println("NO"); 67 | } 68 | } 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /sem-1/solutions/8A.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.IOException; 3 | import java.io.InputStreamReader; 4 | 5 | public class Backpack01 { 6 | public static void main(String[] args) throws IOException { 7 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 8 | String[] line = reader.readLine().split(" "); 9 | int n = Integer.parseInt(line[0]); 10 | int m = Integer.parseInt(line[1]); 11 | int[] a = new int[n + 1]; 12 | line = reader.readLine().split(" "); 13 | for (int i = 0; i < n; i++) { 14 | a[i + 1] = Integer.parseInt(line[i]); 15 | } 16 | int[][] dp = new int[n + 1][m + 1]; 17 | dp[0][0] = 1; 18 | for (int i = 1; i < n + 1; i++) { 19 | for (int j = 0; j < m + 1; j++) { 20 | dp[i][j] = dp[i - 1][j]; 21 | if (j - a[i] >= 0 && dp[i][j] == 0) { 22 | dp[i][j] = dp[i - 1][j - a[i]]; 23 | } 24 | } 25 | } 26 | for (int i = m; i >= 0; i--) { 27 | if (dp[n][i] == 1) { 28 | System.out.println(i); 29 | break; 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /sem-1/solutions/8B.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.IOException; 3 | import java.io.InputStreamReader; 4 | 5 | public class Backpack { 6 | public static void main(String[] args) throws IOException { 7 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 8 | String[] line = reader.readLine().split(" "); 9 | int n = Integer.parseInt(line[0]); 10 | int m = Integer.parseInt(line[1]); 11 | int[] w = new int[n + 1]; 12 | line = reader.readLine().split(" "); 13 | for (int i = 0; i < n; i++) { 14 | w[i + 1] = Integer.parseInt(line[i]); 15 | } 16 | int[] c = new int[n + 1]; 17 | line = reader.readLine().split(" "); 18 | for (int i = 0; i < n; i++) { 19 | c[i + 1] = Integer.parseInt(line[i]); 20 | } 21 | int[][] dp = new int[n + 1][m + 1]; 22 | dp[0][0] = 0; 23 | for (int i = 1; i < m + 1; i++) { 24 | dp[0][i] = Integer.MIN_VALUE; 25 | } 26 | for (int i = 1; i < n + 1; i++) { 27 | for (int j = 0; j < m + 1; j++) { 28 | dp[i][j] = dp[i - 1][j]; 29 | if (j - w[i] >= 0 && dp[i - 1][j - w[i]] != Integer.MIN_VALUE) { 30 | dp[i][j] = Math.max(dp[i - 1][j - w[i]] + c[i], dp[i][j]); 31 | } 32 | } 33 | } 34 | int result = Integer.MIN_VALUE; 35 | int ind = 0; 36 | for (int i = 0; i < m + 1; i++) { 37 | if (dp[n][i] > result) { 38 | result = dp[n][i]; 39 | ind = i; 40 | } 41 | } 42 | int count = 0; 43 | int i = n; 44 | StringBuilder sb = new StringBuilder(); 45 | do { 46 | if (ind - w[i] >= 0 && dp[i - 1][ind] <= dp[i - 1][ind - w[i]] + c[i]) { 47 | count++; 48 | sb.insert(0, i); 49 | sb.insert(0, " "); 50 | ind -= w[i]; 51 | } 52 | i--; 53 | } while (i != 0); 54 | System.out.println(count); 55 | System.out.println(sb.delete(0, 1)); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /sem-1/solutions/8C.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.IOException; 3 | import java.io.InputStreamReader; 4 | 5 | public class Bankomat { 6 | public static void main(String[] args) throws IOException { 7 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 8 | int n = Integer.parseInt(reader.readLine()); 9 | int[] w = new int[n + 1]; 10 | String[] line = reader.readLine().split(" "); 11 | for (int i = 0; i < n; i++) { 12 | w[i] = Integer.parseInt(line[i]); 13 | } 14 | int s = Integer.parseInt(reader.readLine()); 15 | int[] dp = new int[s + 1]; 16 | for (int i = 0; i < s + 1; i++) { 17 | dp[i] = s + 1; 18 | } 19 | dp[0] = 0; 20 | for (int i = 1; i < s + 1; i++) { 21 | for (int j = 0; j < n; j++) { 22 | if (w[j] <= i) { 23 | dp[i] = Math.min(dp[i], dp[i - w[j]] + 1); 24 | } 25 | } 26 | } 27 | if (dp[s] > s) { 28 | System.out.println(-1); 29 | } else { 30 | System.out.println(dp[s]); 31 | StringBuilder sb = new StringBuilder(); 32 | int i = s; 33 | while (i != 0) { 34 | int minValue = s + 1; 35 | int minIndex = -1; 36 | for (int j = 0; j < n; j++) { 37 | if (w[j] <= i) { 38 | if (dp[i - w[j]] < minValue && dp[i - w[j]] != s + 1) { 39 | minIndex = j; 40 | minValue = dp[i - w[j]]; 41 | } 42 | } 43 | } 44 | sb.append(w[minIndex]).append(" "); 45 | i -= w[minIndex]; 46 | } 47 | sb.setLength(sb.length() - 1); 48 | System.out.println(sb); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /sem-1/solutions/8D.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.IOException; 3 | import java.io.InputStreamReader; 4 | import java.util.*; 5 | 6 | public class Giri2 { 7 | public static void main(String[] args) throws IOException { 8 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 9 | int n = Integer.parseInt(reader.readLine()); 10 | String[] line = reader.readLine().split(" "); 11 | int[] a = new int[n + 1]; 12 | int sum = 0; 13 | for (int i = 0; i < n; i++) { 14 | a[i + 1] = Integer.parseInt(line[i]); 15 | sum += a[i + 1]; 16 | } 17 | if (n % 2 == 1 || sum % 2 == 1) { 18 | System.out.println(-1); 19 | return; 20 | } 21 | List>> dp = new ArrayList<>(sum / 2 + 1); 22 | for (int i = 0; i < sum / 2 + 1; i++) { 23 | List> temp = new ArrayList<>(); 24 | for (int j = 0; j < n / 2 + 1; j++) { 25 | Set temp2 = new HashSet<>(); 26 | temp.add(temp2); 27 | } 28 | dp.add(temp); 29 | } 30 | for (int i = 1; i < n + 1; i++) { 31 | if (a[i] <= sum / 2 && dp.get(a[i]).get(1).isEmpty()) { 32 | dp.get(a[i]).get(1).add(i); 33 | } 34 | } 35 | for (int i = 2; i < n / 2 + 1; i++) { 36 | for (int j = 1; j < sum / 2 + 1; j++) { 37 | for (int p = 1; p < n + 1; p++) { 38 | if (j - a[p] > 0 && !dp.get(j - a[p]).get(i - 1).isEmpty()) { 39 | if (!dp.get(j - a[p]).get(i - 1).contains(p)) { 40 | Set temp = new HashSet<>(dp.get(j - a[p]).get(i - 1)); 41 | temp.add(p); 42 | List> temp2 = new ArrayList<>(dp.get(j)); 43 | temp2.set(i, temp); 44 | dp.set(j, temp2); 45 | break; 46 | } 47 | } 48 | } 49 | } 50 | } 51 | if (dp.get(sum / 2).get(n / 2).isEmpty()) { 52 | System.out.println(-1); 53 | return; 54 | } 55 | StringBuilder first = new StringBuilder(); 56 | StringBuilder second = new StringBuilder(); 57 | for (int i = 1; i < n + 1; i++) { 58 | if (dp.get(sum / 2).get(n / 2).contains(i)) { 59 | first.append(i).append(" "); 60 | } else { 61 | second.append(i).append(" "); 62 | } 63 | } 64 | first.setLength(first.length() - 1); 65 | second.setLength(second.length() - 1); 66 | System.out.println(first); 67 | System.out.println(second); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /sem-2/problems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryag/ct-itmo-algorithms/2019c7d4928bb04fc3e0b7c6fdd4453dbeb35f9a/sem-2/problems.pdf -------------------------------------------------------------------------------- /sem-2/solutions/1A.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.IOException; 3 | import java.io.InputStreamReader; 4 | 5 | public class RMQ { 6 | public static int[] tree; 7 | public static int[] index; 8 | public static String[] a; 9 | public static int n; 10 | public static int q; 11 | 12 | public static int[] get(int v, int l, int r, int ql, int qr) { 13 | if (qr <= l || ql >= r) { 14 | return new int[]{Integer.MIN_VALUE, -1}; 15 | } 16 | if (ql <= l && r <= qr) { 17 | return new int[]{tree[v], index[v]}; 18 | } 19 | int m = (l + r) / 2; 20 | int[] maxLeftChild = get(2 * v + 1, l, m, ql, qr); 21 | int[] maxRightChild = get(2 * v + 2, m, r, ql, qr); 22 | if (maxLeftChild[0] >= maxRightChild[0]) { 23 | return maxLeftChild; 24 | } 25 | return maxRightChild; 26 | } 27 | 28 | public static void build(int v, int l, int r) { 29 | if (l + 1 == r) { 30 | tree[v] = (l < a.length ? Integer.parseInt(a[l]) : Integer.MIN_VALUE); 31 | index[v] = l; 32 | return; 33 | } 34 | int m = (l + r) / 2; 35 | build(2 * v + 1, l, m); 36 | build(2 * v + 2, m, r); 37 | if (tree[2 * v + 1] >= tree[2 * v + 2]) { 38 | tree[v] = tree[2 * v + 1]; 39 | index[v] = index[2 * v + 1]; 40 | } else { 41 | tree[v] = tree[2 * v + 2]; 42 | index[v] = index[2 * v + 2]; 43 | } 44 | } 45 | 46 | public static void main(String[] args) throws IOException { 47 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 48 | n = Integer.parseInt(reader.readLine()); 49 | a = reader.readLine().split(" "); 50 | if (!is2k(n)) { 51 | n = (int) Math.pow(2, q); 52 | } 53 | tree = new int[2 * n - 1]; 54 | index = new int[2 * n - 1]; 55 | build(0, 0, n); 56 | int countQuery = Integer.parseInt(reader.readLine()); 57 | for (int i = 0; i < countQuery; i++) { 58 | String[] line = reader.readLine().split(" "); 59 | int[] ans = get(0, 0, n, Integer.parseInt(line[0]) - 1, Integer.parseInt(line[1])); 60 | System.out.println(ans[0] + " " + (ans[1] + 1)); 61 | } 62 | } 63 | 64 | public static boolean is2k(int x) { 65 | int a = 1; 66 | q = 0; 67 | while (true) { 68 | if (a == x) { 69 | return true; 70 | } 71 | if (a > x) { 72 | return false; 73 | } 74 | a *= 2; 75 | q++; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /sem-2/solutions/1H.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct vertex { 5 | int open; 6 | int close; 7 | int pair; 8 | 9 | void initialization() { 10 | open = 0; 11 | close = 0; 12 | pair = 0; 13 | } 14 | }; 15 | 16 | int n; 17 | std::vector tree; 18 | 19 | vertex merge(const vertex &left, const vertex &right){ 20 | vertex parent{}; 21 | parent.open = left.open + right.open; 22 | parent.close = left.close + right.close; 23 | int leftDist = std::max(left.open - left.pair / 2, 0); 24 | int rightDist = std::max(right.close - right.pair / 2, 0); 25 | parent.pair = left.pair + right.pair + 2 * (std::min(leftDist, rightDist)); 26 | return parent; 27 | } 28 | 29 | void set(int v, int l, int r, int i, vertex value) { 30 | if (l + 1 == r) { 31 | tree[v] = value; 32 | return; 33 | } 34 | int m = l + (r - l) / 2; 35 | if (i < m) { 36 | set(2 * v + 1, l, m, i, value); 37 | } else { 38 | set(2 * v + 2, m, r, i, value); 39 | } 40 | tree[v] = merge(tree[2 * v + 1], tree[2 * v + 2]); 41 | } 42 | 43 | vertex getAnswer(int v, int l, int r, int ql, int qr) { 44 | if (qr <= l || r <= ql) { 45 | vertex tmp{}; 46 | tmp.initialization(); 47 | return tmp; 48 | } 49 | if (ql <= l && r <= qr) { 50 | return tree[v]; 51 | } 52 | int m = l + (r - l) / 2; 53 | vertex left = getAnswer(2 * v + 1, l, m, ql, qr); 54 | vertex right = getAnswer(2 * v + 2, m, r, ql, qr); 55 | return merge(left, right); 56 | } 57 | 58 | int main() { 59 | std::ios_base::sync_with_stdio(false); 60 | std::string line; 61 | std::cin >> line; 62 | n = 1; 63 | while (n < line.length()) { 64 | n *= 2; 65 | } 66 | vertex zero{}; 67 | zero.initialization(); 68 | tree.assign(2 * n - 1, zero); 69 | for (int i = 0; i < line.length(); i++) { 70 | vertex temp{}; 71 | temp.open = (line[i] == '(') ? 1 : 0; 72 | temp.close = (line[i] == ')') ? 1 : 0; 73 | temp.pair = 0; 74 | set(0, 0, n, i, temp); 75 | } 76 | int m; 77 | std::cin >> m; 78 | while (m > 0) { 79 | int ql, qr; 80 | std::cin >> ql >> qr; 81 | vertex answer = getAnswer(0, 0, n, ql - 1, qr); 82 | std::cout << answer.pair << '\n'; 83 | m--; 84 | } 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /sem-2/solutions/2D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | std::vector alf[26]; 6 | 7 | int set(int q, int ql, int qr, int delta) { 8 | if (alf[q].empty()) { 9 | return delta; 10 | } 11 | int left = std::lower_bound(alf[q].data(), alf[q].data() + alf[q].size(), ql) - alf[q].data(); 12 | int right = std::upper_bound(alf[q].data(), alf[q].data() + alf[q].size(), qr) - alf[q].data(); 13 | for (int i = left; i < right; i++) { 14 | alf[q][i] = delta; 15 | delta++; 16 | } 17 | return delta; 18 | } 19 | 20 | int main() { 21 | int n, q; 22 | std::cin >> n >> q; 23 | std::string s; 24 | std::cin >> s; 25 | for (int i = 0; i < s.length(); i++) { 26 | int c = s[i] - 'a'; 27 | alf[c].push_back(i); 28 | } 29 | for (int i = 0; i < q; i++) { 30 | int ql, qr, k; 31 | std::cin >> ql >> qr >> k; 32 | ql--; 33 | qr--; 34 | int delta = ql; 35 | if (k == 1) { 36 | for (int no = 0; no < 26; no++) { 37 | delta = set(no, ql, qr, delta); 38 | } 39 | } else { 40 | for (int no = 25; no >= 0; no--) { 41 | delta = set(no, ql, qr, delta); 42 | } 43 | } 44 | } 45 | for (int i = 0; i < 26; i++) { 46 | for (int j = 0; j < alf[i].size(); j++) { 47 | s[alf[i][j]] = 'a' + i; 48 | } 49 | } 50 | std::cout << s; 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /sem-2/solutions/2H.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.IOException; 3 | import java.io.InputStreamReader; 4 | import java.util.Arrays; 5 | 6 | public class Pictures { 7 | public static final int MOD = 10_007; 8 | public static int[][] tree; 9 | public static int[] col; 10 | public static int[] bw; 11 | public static int n; 12 | public static int c; 13 | 14 | public static void update(int v) { 15 | for (int i = 0; i <= c; i++) { 16 | tree[v][i] = 0; 17 | } 18 | for (int i = 0; i <= c; i++) { 19 | for (int j = 0; j <= c; j++) { 20 | int tmp = Math.min(i + j, c); 21 | tree[v][tmp] += (tree[v * 2][i] * tree[v * 2 + 1][j]) % MOD; 22 | } 23 | } 24 | for (int i = 0; i <= c; i++) { 25 | tree[v][i] %= MOD; 26 | } 27 | } 28 | 29 | public static void set(int v) { 30 | v += n; 31 | Arrays.fill(tree[v], 0); 32 | tree[v][0] = bw[v - n] % MOD; 33 | tree[v][1] = col[v - n] % MOD; 34 | v /= 2; 35 | for (int i = v; i > 0; i /= 2) { 36 | update(i); 37 | } 38 | } 39 | 40 | public static void main(String[] args) throws IOException { 41 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 42 | String[] line = reader.readLine().split(" "); 43 | n = Integer.parseInt(line[0]); 44 | c = Integer.parseInt(line[1]); 45 | col = new int[n]; 46 | bw = new int[n]; 47 | tree = new int[2 * n][c + 1]; 48 | 49 | line = reader.readLine().split(" "); 50 | for (int i = 0; i < n; i++) { 51 | col[i] = Integer.parseInt(line[i]); 52 | } 53 | 54 | line = reader.readLine().split(" "); 55 | for (int i = 0; i < n; i++) { 56 | bw[i] = Integer.parseInt(line[i]); 57 | } 58 | 59 | for (int i = 0; i < n; i++) { 60 | tree[n + i][0] = bw[i] % MOD; 61 | tree[n + i][1] = col[i] % MOD; 62 | } 63 | for (int i = n - 1; i >= 1; i--) { 64 | update(i); 65 | } 66 | 67 | int q = Integer.parseInt(reader.readLine()); 68 | while (q-- > 0) { 69 | line = reader.readLine().split(" "); 70 | int change = Integer.parseInt(line[0]) - 1; 71 | col[change] = Integer.parseInt(line[1]); 72 | bw[change] = Integer.parseInt(line[2]); 73 | set(change); 74 | System.out.println(tree[1][c]); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /sem-2/solutions/3A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | const int SIZE = 100'001; 6 | std::vector a(SIZE); 7 | int table[SIZE][18]; 8 | 9 | void create(int n) { 10 | for (int i = 1; i < n + 1; ++i) { 11 | table[i][0] = a[i]; 12 | } 13 | for (int i = 1; (1 << i) < n + 1; ++i) { 14 | for (int j = 1; 1 << i < n + 2 - j; ++j) { 15 | table[j][i] = std::min(table[j][i - 1], table[j + (1 << (i - 1))][i - 1]); 16 | } 17 | } 18 | } 19 | 20 | int find(int lq, int rq) { 21 | int noLayer = 31 - __builtin_clz(rq - lq); 22 | return std::min(table[lq][noLayer], table[rq - (1 << noLayer) + 1][noLayer]); 23 | } 24 | 25 | int main() { 26 | std::ios_base::sync_with_stdio(false); 27 | std::cin.tie(nullptr); 28 | int n, m, u, v; 29 | a[0] = 0; 30 | std::cin >> n >> m >> a[1]; 31 | for (int i = 2; i < n + 1; i++) { 32 | a[i] = (23 * a[i - 1] + 21563) % 16714589; 33 | } 34 | create(n); 35 | std::cin >> u >> v; 36 | int result = find(u, v); 37 | for (int i = 2; i < m + 1; i++) { 38 | u = ((17 * u + 751 + result + 2 * (i - 1)) % n) + 1; 39 | v = ((13 * v + 593 + result + 5 * (i - 1)) % n) + 1; 40 | result = (u <= v) ? find(u, v) : find(v, u); 41 | } 42 | std::cout << u << " " << v << " " << result; 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /sem-2/solutions/3B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int fenwick[129][129][129] = {0}; 4 | int n; 5 | 6 | int dec(int x) { 7 | x -= x & (-x); 8 | return x; 9 | } 10 | 11 | int query(int xq, int yq, int zq) { 12 | int x, y, z; 13 | int answer = 0; 14 | x = xq; 15 | while (x > 0) { 16 | y = yq; 17 | while (y > 0) { 18 | z = zq; 19 | while (z > 0) { 20 | answer += fenwick[x][y][z]; 21 | z = dec(z); 22 | } 23 | y = dec(y); 24 | } 25 | x = dec(x); 26 | } 27 | return answer; 28 | } 29 | 30 | int inc(int x) { 31 | x += x & (-x); 32 | return x; 33 | } 34 | 35 | void update(int xq, int yq, int zq, int value) { 36 | int x, y, z; 37 | x = xq + 1; 38 | while (x < n + 1) { 39 | y = yq + 1; 40 | while (y < n + 1) { 41 | z = zq + 1; 42 | while (z < n + 1) { 43 | fenwick[x][y][z] += value; 44 | z = inc(z); 45 | } 46 | y = inc(y); 47 | } 48 | x = inc(x); 49 | } 50 | } 51 | 52 | int main() { 53 | std::ios_base::sync_with_stdio(false); 54 | std::cin.tie(nullptr); 55 | int c[7], ans[8], m = 0, result; 56 | std::cin >> n; 57 | while (true) { 58 | std::cin >> m; 59 | if (m == 1) { 60 | std::cin >> c[0] >> c[2] >> c[4] >> c[6]; 61 | update(c[0], c[2], c[4], c[6]); 62 | } else if (m == 2) { 63 | std::cin >> c[0] >> c[2] >> c[4] >> c[1] >> c[3] >> c[5]; 64 | ans[0] = query(c[1] + 1, c[3] + 1, c[5] + 1); 65 | ans[1] = query(c[0], c[2], c[4]); 66 | ans[2] = query(c[0], c[2], c[5] + 1); 67 | ans[3] = query(c[1] + 1, c[3] + 1, c[4]); 68 | ans[4] = query(c[0], c[3] + 1, c[4]); 69 | ans[5] = query(c[1] + 1, c[2], c[5] + 1); 70 | ans[6] = query(c[1] + 1, c[2], c[4]); 71 | ans[7] = query(c[0], c[3] + 1, c[5] + 1); 72 | result = 0; 73 | for (int i = 0; i < 8; ++i) { 74 | result += (i % 2 == 0) ? ans[i] : -ans[i]; 75 | } 76 | std::cout << result << '\n'; 77 | } else { 78 | return 0; 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /sem-2/solutions/3C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | const int N = 200'010; 5 | const int countLayers = 19; 6 | 7 | int S[N], a[countLayers][N], b[countLayers][N], n; 8 | 9 | void build() { 10 | for (int i = 1; i <= S[n]; ++i) { 11 | for (int j = 1; j <= n - (1 << i) + 1; ++j) { 12 | a[i][j] = std::max(a[i - 1][j], a[i - 1][j + (1 << (i - 1))]); 13 | b[i][j] = std::min(b[i - 1][j], b[i - 1][j + (1 << (i - 1))]); 14 | } 15 | } 16 | } 17 | 18 | int getA(int l, int r) { 19 | return std::max(a[S[r - l + 1]][l], a[S[r - l + 1]][r - (1 << S[r - l + 1]) + 1]); 20 | } 21 | 22 | int getB(int l, int r) { 23 | return std::min(b[S[r - l + 1]][l], b[S[r - l + 1]][r - (1 << S[r - l + 1]) + 1]); 24 | } 25 | 26 | int binarySearchRight(int border) { 27 | int l = 0, r = border + 1; 28 | while (l < r - 1) { 29 | int mid = (l + r) >> 1; 30 | if (getA(mid, border) < getB(mid, border)) { 31 | r = mid; 32 | } else { 33 | l = mid; 34 | } 35 | } 36 | return r; 37 | } 38 | 39 | int binarySearchLeft(int border) { 40 | int l = 0, r = border + 1; 41 | while (l < r - 1) { 42 | int mid = (l + r) >> 1; 43 | if (getA(mid, border) > getB(mid, border)) { 44 | l = mid; 45 | } else { 46 | r = mid; 47 | } 48 | } 49 | return r; 50 | } 51 | 52 | int main() { 53 | std::ios_base::sync_with_stdio(false); 54 | std::cin.tie(nullptr); 55 | std::cin >> n; 56 | S[1] = 0; 57 | for (int i = 2; i <= n; ++i) { 58 | S[i] = 1 + S[i >> 1]; 59 | } 60 | for (int i = 1; i <= n; ++i) { 61 | std::cin >> a[0][i]; 62 | } 63 | for (int i = 1; i <= n; ++i) { 64 | std::cin >> b[0][i]; 65 | } 66 | long long ans = 0; 67 | build(); 68 | for (int i = 1; i <= n; ++i) { 69 | ans += (binarySearchRight(i) - binarySearchLeft(i)); 70 | } 71 | std::cout << ans << '\n'; 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /sem-2/solutions/3D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | const int N = 200005, LOG = 20; 4 | int lg[N]; 5 | long long n, sp[LOG][N], a[N]; 6 | std::map map; 7 | 8 | void build() { 9 | lg[1] = 0; 10 | for (int i = 2; i <= n; ++i) { 11 | lg[i] = lg[i / 2] + 1; 12 | } 13 | for (int i = 1; i <= n; ++i) { 14 | sp[0][i] = a[i]; 15 | } 16 | for (int i = 1; (1 << i) <= n; ++i) { 17 | for (int j = 1; j + (1 << i) - 1 <= n; ++j) { 18 | sp[i][j] = (sp[i - 1][j] | sp[i - 1][j + (1 << (i - 1))]); 19 | } 20 | } 21 | } 22 | 23 | long long get(int l, int r) { 24 | int temp = lg[r - l + 1]; 25 | return (sp[temp][l] | sp[temp][r - (1 << temp) + 1]); 26 | } 27 | 28 | long long binarySearchRight(int l, int r, int index) { 29 | while (l < r) { 30 | int m = r - (r - l) / 2; 31 | if (get(index, m) == a[index]) { 32 | l = m; 33 | } else { 34 | r = m - 1; 35 | } 36 | } 37 | return r; 38 | } 39 | 40 | long long binarySearchLeft(int l, int r, int index) { 41 | while (l < r) { 42 | int m = (l + r) / 2; 43 | if (get(m, index) == a[index]) { 44 | r = m; 45 | } else { 46 | l = m + 1; 47 | } 48 | } 49 | return l; 50 | } 51 | 52 | long long eliminate(int index) { 53 | int tmp = 0; 54 | if (map.count(a[index])) { 55 | tmp = map[a[index]]; 56 | } 57 | long long d1 = index - binarySearchLeft(tmp + 1, index, index) + 1; 58 | long long d2 = binarySearchRight(index, n, index) - index + 1; 59 | return d1 * d2 - 1; 60 | } 61 | 62 | int main() { 63 | std::ios_base::sync_with_stdio(false); 64 | std::cin.tie(nullptr); 65 | std::cin >> n; 66 | for (int i = 1; i <= n; ++i) { 67 | std::cin >> a[i]; 68 | } 69 | build(); 70 | long long answer = n * (n - 1) / 2; 71 | for (int i = 1; i <= n; i++) { 72 | answer -= eliminate(i); 73 | map[a[i]] = i; 74 | } 75 | std::cout << answer << '\n'; 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /sem-2/solutions/4A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | const int SIZE = 2'540'313; 6 | 7 | struct Cell { 8 | std::vector v; 9 | 10 | bool exists(int x) { 11 | return std::find(v.begin(), v.end(), x) != v.end(); 12 | } 13 | 14 | void insert(int x) { 15 | if (!exists(x)) { 16 | v.push_back(x); 17 | } 18 | } 19 | 20 | void remove(int x) { 21 | auto it = std::find(v.begin(), v.end(), x); 22 | if (it != v.end()) { 23 | v.erase(it); 24 | } 25 | } 26 | }; 27 | 28 | int h(int x) { 29 | return std::abs(x) % SIZE; 30 | } 31 | 32 | int main() { 33 | std::ios_base::sync_with_stdio(false); 34 | std::cin.tie(nullptr); 35 | std::vector a(SIZE); 36 | for (int i = 1; i <= SIZE; i++) { 37 | a.emplace_back(); 38 | } 39 | std::string command; 40 | int value; 41 | while (std::cin >> command >> value) { 42 | if (command == "insert") { 43 | a[h(value)].insert(value); 44 | } else if (command == "delete") { 45 | a[h(value)].remove(value); 46 | } else { 47 | bool ans = a[h(value)].exists(value); 48 | if (ans) { 49 | std::cout << "true" << '\n'; 50 | } else { 51 | std::cout << "false" << '\n'; 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /sem-2/solutions/4D.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.IOException; 3 | import java.io.InputStreamReader; 4 | import java.util.HashSet; 5 | import java.util.Set; 6 | 7 | public class HashCode { 8 | public static void main(String[] args) throws IOException { 9 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 10 | int k = Integer.parseInt(reader.readLine()); 11 | StringBuilder first = new StringBuilder("a".repeat(k)); 12 | Set words = new HashSet<>(Set.of(first.toString())); 13 | for (int i = 0; i <= k - 2; i++) { 14 | StringBuilder sb = new StringBuilder(first); 15 | sb.setCharAt(i, 'b'); 16 | sb.setCharAt(i + 1, 'B'); 17 | words.add(sb.toString()); 18 | } 19 | for (String s : words) { 20 | System.out.println(s); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /sem-2/solutions/4E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int p, q; 7 | std::random_device rd; 8 | std::mt19937 gen(rd()); 9 | 10 | char random_char() { 11 | std::uniform_int_distribution<> dist(97, 122); 12 | return (char) dist(gen); 13 | } 14 | 15 | long long get_hash(const std::string &s, int cur) { 16 | if (cur == -1) { 17 | return 0; 18 | } 19 | return (get_hash(s, cur - 1) * p + s[cur]) % q; 20 | } 21 | 22 | int main() { 23 | std::ios_base::sync_with_stdio(false); 24 | std::cin.tie(nullptr); 25 | std::cout.tie(nullptr); 26 | std::cin >> p >> q; 27 | std::unordered_set set; 28 | std::vector> v; 29 | while (true) { 30 | std::string s; 31 | for (int i = 0; i < 100; i++) { 32 | s.push_back(random_char()); 33 | } 34 | int cur_hash = get_hash(s, s.length() - 1); 35 | if (set.count(cur_hash) == 0) { 36 | set.insert(cur_hash); 37 | v.emplace_back(cur_hash, s); 38 | } else { 39 | bool flag = false; 40 | for (auto &i: v) { 41 | if (i.first == cur_hash && i.second != s) { 42 | std::cout << s << '\n' << i.second; 43 | flag = true; 44 | break; 45 | } 46 | } 47 | if (flag) { 48 | break; 49 | } 50 | } 51 | } 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /sem-3/problems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryag/ct-itmo-algorithms/2019c7d4928bb04fc3e0b7c6fdd4453dbeb35f9a/sem-3/problems.pdf -------------------------------------------------------------------------------- /sem-3/solutions/1A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct node { 5 | int n; 6 | std::vector edges; 7 | 8 | explicit node(int n) { 9 | this->n = n; 10 | } 11 | }; 12 | 13 | std::vector graph; 14 | std::vector mark; 15 | 16 | void dfs(int u) { 17 | mark[u] = true; 18 | for (int v: graph[u].edges) { 19 | if (!mark[v]) { 20 | std::cout << (u + 1) << " " << (v + 1) << '\n'; 21 | dfs(v); 22 | } 23 | } 24 | } 25 | 26 | int main() { 27 | int n, m, u, v; 28 | std::cin >> n >> m; 29 | for (int i = 0; i < n; ++i) { 30 | graph.emplace_back(i); 31 | mark.emplace_back(); 32 | } 33 | for (int i = 0; i < m; ++i) { 34 | std::cin >> u >> v; 35 | graph[u - 1].edges.emplace_back(v - 1); 36 | graph[v - 1].edges.emplace_back(u - 1); 37 | } 38 | dfs(0); 39 | } 40 | -------------------------------------------------------------------------------- /sem-3/solutions/1B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct node { 5 | int n; 6 | std::vector edges; 7 | 8 | explicit node(int n) { 9 | this->n = n; 10 | } 11 | }; 12 | 13 | struct component { 14 | int size{}; 15 | std::vector nodes; 16 | }; 17 | 18 | std::vector graph; 19 | std::vector components; 20 | std::vector mark; 21 | 22 | void dfs(int u) { 23 | mark[u] = true; 24 | ++components.back().size; 25 | components.back().nodes.emplace_back(u); 26 | for (int v: graph[u].edges) { 27 | if (!mark[v]) { 28 | dfs(v); 29 | } 30 | } 31 | } 32 | 33 | int main() { 34 | std::ios_base::sync_with_stdio(false); 35 | std::cin.tie(nullptr); 36 | std::cout.tie(nullptr); 37 | int n, m; 38 | std::cin >> n >> m; 39 | for (int i = 0; i < n; ++i) { 40 | graph.emplace_back(i); 41 | mark.emplace_back(); 42 | } 43 | int u, v; 44 | for (int i = 0; i < m; ++i) { 45 | std::cin >> u >> v; 46 | graph[u - 1].edges.emplace_back(v - 1); 47 | graph[v - 1].edges.emplace_back(u - 1); 48 | } 49 | for (int i = 0; i < n; ++i) { 50 | if (!mark[i]) { 51 | components.emplace_back(); 52 | dfs(i); 53 | } 54 | } 55 | std::cout << components.size() << '\n'; 56 | for (component const& c : components) { 57 | std::cout << c.size << '\n'; 58 | for (int i : c.nodes) { 59 | std::cout << (i + 1) << " "; 60 | } 61 | std::cout << '\n'; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /sem-3/solutions/1C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct node { 5 | int n; 6 | std::vector edges; 7 | 8 | explicit node(int n) { 9 | this->n = n; 10 | } 11 | }; 12 | 13 | std::vector graph; 14 | std::vector main_nodes; 15 | std::vector mark; 16 | 17 | void dfs(int u) { 18 | mark[u] = true; 19 | main_nodes.back() = u; 20 | for (int v: graph[u].edges) { 21 | if (!mark[v]) { 22 | dfs(v); 23 | } 24 | } 25 | } 26 | 27 | int main() { 28 | std::ios_base::sync_with_stdio(false); 29 | std::cin.tie(nullptr); 30 | std::cout.tie(nullptr); 31 | int n, m; 32 | std::cin >> n >> m; 33 | for (int i = 0; i < n; ++i) { 34 | graph.emplace_back(i); 35 | mark.emplace_back(); 36 | } 37 | int u, v; 38 | for (int i = 0; i < m; ++i) { 39 | std::cin >> u >> v; 40 | graph[u - 1].edges.emplace_back(v - 1); 41 | graph[v - 1].edges.emplace_back(u - 1); 42 | } 43 | for (int i = 0; i < n; ++i) { 44 | if (!mark[i]) { 45 | main_nodes.emplace_back(); 46 | dfs(i); 47 | } 48 | } 49 | std::cout << main_nodes.size() - 1 << '\n'; 50 | for (int i = 0; i < main_nodes.size() - 1; ++i) { 51 | std::cout << main_nodes[i] + 1 << " " << main_nodes[i + 1] + 1 << '\n'; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /sem-3/solutions/1D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | std::vector> edges; 6 | std::vector from; 7 | std::vector mark; 8 | 9 | void dfs(int u, int p) { 10 | mark[u] = true; 11 | from[u] = p; 12 | for (int v: edges[u]) { 13 | if (mark[v] == 0) { 14 | dfs(v, u); 15 | } else if (mark[v] == 1) { 16 | std::vector res; 17 | int count = 0; 18 | while (u != v) { 19 | res.emplace_back(u); 20 | ++count; 21 | u = from[u]; 22 | } 23 | res.emplace_back(v); 24 | ++count; 25 | std::cout << count << '\n'; 26 | for (auto i = res.rbegin(); i != res.rend(); ++i) { 27 | std::cout << *i + 1 << " "; 28 | } 29 | exit(0); 30 | } 31 | } 32 | mark[u] = 2; 33 | } 34 | 35 | int main() { 36 | std::ios_base::sync_with_stdio(false); 37 | std::cin.tie(nullptr); 38 | std::cout.tie(nullptr); 39 | int n, m, i; 40 | std::cin >> n >> m; 41 | for (i = 0; i < n; ++i) { 42 | edges.emplace_back(); 43 | from.emplace_back(-1); 44 | mark.emplace_back(); 45 | } 46 | int u, v; 47 | for (i = 0; i < m; ++i) { 48 | std::cin >> u >> v; 49 | edges[u - 1].emplace_back(v - 1); 50 | } 51 | for (i = 0; i < n; ++i) { 52 | if (mark[i] == 0) { 53 | dfs(i, -1); 54 | } 55 | } 56 | std::cout << -1; 57 | } 58 | -------------------------------------------------------------------------------- /sem-3/solutions/1E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct node { 5 | int color{}; 6 | std::vector edges; 7 | }; 8 | 9 | std::vector graph; 10 | std::vector mark; 11 | 12 | void dfs(int u, int color) { 13 | mark[u] = true; 14 | graph[u].color = color; 15 | for (int v: graph[u].edges) { 16 | if (!mark[v]) { 17 | dfs(v, color == 1 ? 2 : 1); 18 | } else if (graph[v].color == color) { 19 | std::cout << -1; 20 | exit(0); 21 | } 22 | } 23 | } 24 | 25 | int main() { 26 | std::ios_base::sync_with_stdio(false); 27 | std::cin.tie(nullptr); 28 | std::cout.tie(nullptr); 29 | int n, m; 30 | std::cin >> n >> m; 31 | for (int i = 0; i < n; ++i) { 32 | graph.emplace_back(); 33 | mark.emplace_back(); 34 | } 35 | int u, v; 36 | for (int i = 0; i < m; ++i) { 37 | std::cin >> u >> v; 38 | graph[u - 1].edges.emplace_back(v - 1); 39 | graph[v - 1].edges.emplace_back(u - 1); 40 | } 41 | for (int i = 0; i < n; ++i) { 42 | if (!mark[i]) { 43 | dfs(i, 1); 44 | } 45 | } 46 | for (int i = 0; i < n; ++i) { 47 | std::cout << graph[i].color << " "; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /sem-3/solutions/1F.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct node { 6 | int deg{}; 7 | std::vector edges; 8 | }; 9 | 10 | std::vector graph; 11 | std::vector mark; 12 | 13 | void dfs(int u) { 14 | mark[u] = 1; 15 | for (int v: graph[u].edges) { 16 | if (mark[v] == 0) { 17 | dfs(v); 18 | } else if (mark[v] == 1) { 19 | std::cout << -1; 20 | exit(0); 21 | } 22 | } 23 | mark[u] = 2; 24 | } 25 | 26 | int main() { 27 | std::ios_base::sync_with_stdio(false); 28 | std::cin.tie(nullptr); 29 | std::cout.tie(nullptr); 30 | int n, m; 31 | std::cin >> n >> m; 32 | for (int i = 0; i < n; ++i) { 33 | graph.emplace_back(); 34 | mark.emplace_back(); 35 | } 36 | int u, v; 37 | for (int i = 0; i < m; ++i) { 38 | std::cin >> u >> v; 39 | graph[u - 1].edges.emplace_back(v - 1); 40 | ++graph[v - 1].deg; 41 | } 42 | for (int i = 0; i < n; ++i) { 43 | if (mark[i] == 0) { 44 | dfs(i); 45 | } 46 | } 47 | std::queue q; 48 | for (int i = 0; i < n; ++i) { 49 | if (!graph[i].deg) { 50 | q.push(i); 51 | } 52 | } 53 | while (!q.empty()) { 54 | v = q.front(); 55 | std::cout << v + 1 << " "; 56 | q.pop(); 57 | for (int i: graph[v].edges) { 58 | if (!--graph[i].deg) { 59 | q.push(i); 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /sem-3/solutions/1G.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | std::vector> edges; 5 | std::vector mark; 6 | 7 | void dfs(int u) { 8 | mark[u] = 1; 9 | for (int v: edges[u]) { 10 | if (mark[v] == 0) { 11 | dfs(v); 12 | } else if (mark[v] == 1) { 13 | std::cout << "NO"; 14 | exit(0); 15 | } 16 | } 17 | mark[u] = 2; 18 | } 19 | 20 | int main() { 21 | std::ios_base::sync_with_stdio(false); 22 | std::cin.tie(nullptr); 23 | std::cout.tie(nullptr); 24 | int n; 25 | std::cin >> n; 26 | for (int i = 0; i < n; ++i) { 27 | edges.emplace_back(); 28 | mark.emplace_back(); 29 | } 30 | int u, v; 31 | for (int i = 1; i < n; ++i) { 32 | for (int j = 0; j < n - i; ++j) { 33 | char c; 34 | std::cin >> c; 35 | if (c == 'R') { 36 | edges[i + j].emplace_back(i - 1); 37 | } else { 38 | edges[i - 1].emplace_back(i + j); 39 | } 40 | } 41 | } 42 | for (int i = 0; i < n; ++i) { 43 | if (mark[i] == 0) { 44 | dfs(i); 45 | } 46 | } 47 | std::cout << "YES"; 48 | } 49 | -------------------------------------------------------------------------------- /sem-3/solutions/1I.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | struct node { 7 | int min_value = INT32_MAX, deg = 0; 8 | std::vector> edges; 9 | }; 10 | 11 | int main() { 12 | std::ios_base::sync_with_stdio(false); 13 | std::cin.tie(nullptr); 14 | std::cout.tie(nullptr); 15 | int n, m, s, t; 16 | std::cin >> n >> m >> s >> t; 17 | std::vector graph(n); 18 | --s; 19 | --t; 20 | int u, v, w; 21 | for (int i = 0; i < m; ++i) { 22 | std::cin >> u >> v >> w; 23 | graph[u - 1].edges.emplace_back(v - 1, w); 24 | ++graph[v - 1].deg; 25 | } 26 | std::queue q; 27 | std::vector top_sort; 28 | for (int i = 0; i < n; ++i) { 29 | if (!graph[i].deg) { 30 | q.push(i); 31 | } 32 | } 33 | while (!q.empty()) { 34 | v = q.front(); 35 | top_sort.emplace_back(v); 36 | q.pop(); 37 | for (auto const& e: graph[v].edges) { 38 | if (!--graph[e.first].deg) { 39 | q.push(e.first); 40 | } 41 | } 42 | } 43 | auto start = std::find(top_sort.begin(), top_sort.end(), s); 44 | auto end = std::find(top_sort.begin(), top_sort.end(), t); 45 | graph[*start].min_value = 0; 46 | for (; start < end; ++start) { 47 | if (graph[*start].min_value == INT32_MAX) continue; 48 | for (auto const& e: graph[*start].edges) { 49 | graph[e.first].min_value = std::min(graph[e.first].min_value, graph[*start].min_value + e.second); 50 | } 51 | } 52 | if (graph[*end].min_value == INT32_MAX) { 53 | std::cout << "Unreachable"; 54 | return 0; 55 | } 56 | std::cout << graph[*end].min_value; 57 | } 58 | -------------------------------------------------------------------------------- /sem-3/solutions/1J.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct node { 5 | int time; 6 | std::vector edges; 7 | 8 | explicit node(int time) { 9 | this->time = time; 10 | } 11 | }; 12 | 13 | std::vector graph; 14 | std::vector mark; 15 | std::vector result; 16 | long long T; 17 | 18 | void dfs(int u) { 19 | mark[u] = true; 20 | for (int v: graph[u].edges) { 21 | if (!mark[v]) { 22 | dfs(v); 23 | } 24 | } 25 | T += graph[u].time; 26 | result.emplace_back(u); 27 | } 28 | 29 | int main() { 30 | int n, t, count; 31 | std::cin >> n; 32 | for (int i = 0; i < n; ++i) { 33 | std::cin >> t; 34 | graph.emplace_back(t); 35 | mark.emplace_back(); 36 | } 37 | for (int i = 0; i < n; ++i) { 38 | std::cin >> count; 39 | while (count--) { 40 | std::cin >> t; 41 | graph[i].edges.emplace_back(t - 1); 42 | } 43 | } 44 | dfs(0); 45 | std::cout << T << " " << result.size() << '\n'; 46 | for (int v: result) { 47 | std::cout << v + 1 << " "; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /sem-3/solutions/1K.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct node { 6 | int deg{}; 7 | std::vector edges; 8 | }; 9 | 10 | int main() { 11 | std::ios_base::sync_with_stdio(false); 12 | std::cin.tie(nullptr); 13 | std::cout.tie(nullptr); 14 | int n, m; 15 | std::cin >> n >> m; 16 | std::vector graph(n); 17 | int u, v; 18 | for (int i = 0; i < m; ++i) { 19 | std::cin >> u >> v; 20 | graph[u - 1].edges.emplace_back(v - 1); 21 | ++graph[v - 1].deg; 22 | } 23 | for (int i = 0; i < n; ++i) { 24 | std::cin >> u; 25 | --u; 26 | if (graph[u].deg != 0) { 27 | std::cout << "NO"; 28 | return 0; 29 | } 30 | for (int e: graph[u].edges) { 31 | --graph[e].deg; 32 | } 33 | } 34 | std::cout << "YES"; 35 | } 36 | -------------------------------------------------------------------------------- /sem-3/solutions/1L.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct node { 6 | int deg{}; 7 | std::vector edges; 8 | }; 9 | 10 | int main() { 11 | std::ios_base::sync_with_stdio(false); 12 | std::cin.tie(nullptr); 13 | std::cout.tie(nullptr); 14 | int n, count, v; 15 | std::cin >> n; 16 | std::vector graph(n); 17 | for (int i = 0; i < n; ++i) { 18 | std::cin >> count; 19 | while (count--) { 20 | std::cin >> v; 21 | graph[i].edges.emplace_back(v - 1); 22 | ++graph[v - 1].deg; 23 | } 24 | } 25 | std::priority_queue q; 26 | std::vector top_sort; 27 | for (int i = 0; i < n; ++i) { 28 | if (!graph[i].deg) { 29 | q.push(i); 30 | } 31 | } 32 | while (!q.empty()) { 33 | v = q.top(); 34 | top_sort.emplace_back(v); 35 | q.pop(); 36 | for (int i: graph[v].edges) { 37 | if (!--graph[i].deg) { 38 | q.push(i); 39 | } 40 | } 41 | } 42 | for (auto i = top_sort.rbegin(); i != top_sort.rend(); ++i) { 43 | std::cout << *i + 1 << " "; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /sem-3/solutions/2A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct node { 6 | int comp{}; 7 | std::vector edges; 8 | std::vector reverse_edges; 9 | }; 10 | 11 | std::vector graph; 12 | std::vector order; 13 | std::vector mark; 14 | 15 | void dfs(int u) { 16 | mark[u] = true; 17 | for (int v: graph[u].edges) { 18 | if (!mark[v]) { 19 | dfs(v); 20 | } 21 | } 22 | order.emplace_back(u); 23 | } 24 | 25 | void reverse_dfs(int u, int comp) { 26 | mark[u] = true; 27 | graph[u].comp = comp; 28 | for (int v: graph[u].reverse_edges) { 29 | if (!mark[v]) { 30 | reverse_dfs(v, comp); 31 | } 32 | } 33 | } 34 | 35 | int main() { 36 | std::ios_base::sync_with_stdio(false); 37 | std::cin.tie(nullptr); 38 | std::cout.tie(nullptr); 39 | 40 | int n, m, u, v; 41 | std::cin >> n >> m; 42 | for (int i = 0; i < n; ++i) { 43 | graph.emplace_back(); 44 | mark.emplace_back(); 45 | } 46 | for (int i = 0; i < m; ++i) { 47 | std::cin >> u >> v; 48 | --u; --v; 49 | graph[u].edges.emplace_back(v); 50 | graph[v].reverse_edges.emplace_back(u); 51 | } 52 | 53 | for (int i = 0; i < n; ++i) { 54 | if (!mark[i]) { 55 | dfs(i); 56 | } 57 | } 58 | 59 | std::reverse(order.begin(), order.end()); 60 | std::fill(mark.begin(), mark.end(), false); 61 | 62 | int comp = 0; 63 | for (int i: order) { 64 | if (!mark[i]) { 65 | ++comp; 66 | reverse_dfs(i, comp); 67 | } 68 | } 69 | 70 | std::cout << comp << '\n'; 71 | for (int i = 0; i < n; ++i) { 72 | std::cout << graph[i].comp << " "; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /sem-3/solutions/2B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct node { 6 | std::vector edges; 7 | std::vector reverse_edges; 8 | }; 9 | 10 | std::vector graph; 11 | std::vector order; 12 | std::vector mark; 13 | int count; 14 | 15 | void dfs(int u) { 16 | mark[u] = true; 17 | for (int v: graph[u].edges) { 18 | if (!mark[v]) { 19 | dfs(v); 20 | } 21 | } 22 | order.emplace_back(u); 23 | } 24 | 25 | void reverse_dfs(int u) { 26 | mark[u] = true; 27 | ++count; 28 | for (int v: graph[u].reverse_edges) { 29 | if (!mark[v]) { 30 | reverse_dfs(v); 31 | } 32 | } 33 | } 34 | 35 | int main() { 36 | std::ios_base::sync_with_stdio(false); 37 | std::cin.tie(nullptr); 38 | std::cout.tie(nullptr); 39 | 40 | int n, m, u, v; 41 | std::cin >> n >> m; 42 | for (int i = 0; i < n; ++i) { 43 | graph.emplace_back(); 44 | mark.emplace_back(); 45 | } 46 | for (int i = 0; i < m; ++i) { 47 | std::cin >> u >> v; 48 | if (u == v) continue; 49 | --u; --v; 50 | graph[v].edges.emplace_back(u); 51 | graph[u].reverse_edges.emplace_back(v); 52 | } 53 | 54 | for (int i = 0; i < n; ++i) { 55 | if (!mark[i]) { 56 | dfs(i); 57 | } 58 | } 59 | 60 | std::reverse(order.begin(), order.end()); 61 | std::fill(mark.begin(), mark.end(), false); 62 | 63 | int res = 0; 64 | for (int i: order) { 65 | if (!mark[i]) { 66 | ++res; 67 | count = 0; 68 | reverse_dfs(i); 69 | res += count > 1; 70 | } 71 | } 72 | 73 | std::cout << res << '\n'; 74 | } 75 | -------------------------------------------------------------------------------- /sem-3/solutions/2C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | const int UNINITIALIZED = -1, CYCLE = -2; 6 | 7 | struct node { 8 | int a{}; 9 | long long dp{}; 10 | std::vector edges; 11 | }; 12 | 13 | std::vector graph; 14 | bool has_cycle; 15 | 16 | long long dfs(int u, int cur_max) { 17 | if (graph[u].a > cur_max) { 18 | return 0; 19 | } 20 | if (graph[u].dp == CYCLE) { 21 | has_cycle = true; 22 | return 0; 23 | } 24 | if (graph[u].dp != UNINITIALIZED) { 25 | return graph[u].dp; 26 | } 27 | graph[u].dp = CYCLE; 28 | long long max_len = 0; 29 | for (int v: graph[u].edges) { 30 | max_len = std::max(max_len, dfs(v, cur_max)); 31 | } 32 | graph[u].dp = max_len + 1; 33 | return graph[u].dp; 34 | } 35 | 36 | int main() { 37 | std::ios_base::sync_with_stdio(false); 38 | std::cin.tie(nullptr); 39 | std::cout.tie(nullptr); 40 | 41 | long long n, m, k; 42 | int a, max_a, u, v; 43 | std::cin >> n >> m >> k; 44 | graph.resize(n); 45 | for (int i = 0; i < n; ++i) { 46 | std::cin >> a; 47 | graph[i].a = a; 48 | max_a = std::max(max_a, a); 49 | } 50 | for (int i = 0; i < m; ++i) { 51 | std::cin >> u >> v; 52 | graph[u - 1].edges.emplace_back(v - 1); 53 | } 54 | 55 | int left = 1, right = max_a; 56 | 57 | label: 58 | while (left <= right) { 59 | int mid = (left + right) / 2; 60 | for (int i = 0; i < n; ++i) { 61 | graph[i].dp = UNINITIALIZED; 62 | } 63 | has_cycle = false; 64 | for (int i = 0; i < n; ++i) { 65 | if (dfs(i, mid) >= k || has_cycle) { 66 | right = mid - 1; 67 | goto label; 68 | } 69 | } 70 | left = mid + 1; 71 | } 72 | 73 | std::cout << (right == max_a ? -1 : right + 1); 74 | } 75 | -------------------------------------------------------------------------------- /sem-3/solutions/2D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct node { 6 | int comp{}; 7 | std::vector> edges; 8 | std::vector> reverse_edges; 9 | }; 10 | 11 | std::vector graph; 12 | std::vector order; 13 | std::vector reachable; 14 | std::vector mark; 15 | 16 | void dfs1(int u) { 17 | reachable[u] = true; 18 | for (auto const& v: graph[u].edges) { 19 | if (!reachable[v.first]) { 20 | dfs1(v.first); 21 | } 22 | } 23 | } 24 | 25 | void dfs2(int u) { 26 | mark[u] = true; 27 | for (auto const& v: graph[u].edges) { 28 | if (!v.second) continue; 29 | if (!mark[v.first]) { 30 | dfs2(v.first); 31 | } 32 | } 33 | order.emplace_back(u); 34 | } 35 | 36 | void reverse_dfs(int u, int comp) { 37 | mark[u] = true; 38 | graph[u].comp = comp; 39 | for (auto const& v: graph[u].reverse_edges) { 40 | if (!v.second) continue; 41 | if (!mark[v.first]) { 42 | reverse_dfs(v.first, comp); 43 | } 44 | } 45 | } 46 | 47 | int main() { 48 | std::ios_base::sync_with_stdio(false); 49 | std::cin.tie(nullptr); 50 | std::cout.tie(nullptr); 51 | 52 | int n, m, u, v, t; 53 | std::cin >> n >> m; 54 | 55 | graph.resize(n); 56 | mark.resize(n); 57 | reachable.resize(n); 58 | 59 | for (int i = 0; i < m; ++i) { 60 | std::cin >> u >> v >> t; 61 | --u; --v, --t; 62 | graph[u].edges.emplace_back(v, t); 63 | graph[v].reverse_edges.emplace_back(u, t); 64 | } 65 | 66 | dfs1(0); 67 | for (int i = 0; i < n; ++i) { 68 | if (reachable[i] && !mark[i]) { 69 | dfs2(i); 70 | } 71 | } 72 | 73 | std::reverse(order.begin(), order.end()); 74 | std::fill(mark.begin(), mark.end(), false); 75 | 76 | int comp = 0; 77 | for (int i: order) { 78 | if (!mark[i]) { 79 | ++comp; 80 | reverse_dfs(i, comp); 81 | } 82 | } 83 | 84 | for (int i: order) { 85 | for (auto const& j: graph[i].edges) { 86 | if (graph[i].comp == graph[j.first].comp) continue; 87 | if (j.second) { 88 | std::cout << "YES"; 89 | return 0; 90 | } 91 | } 92 | } 93 | std::cout << "NO"; 94 | } 95 | -------------------------------------------------------------------------------- /sem-3/solutions/2F.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | typedef pair edge; 8 | 9 | struct node { 10 | int c{}; 11 | vector edges; 12 | }; 13 | 14 | vector graph; 15 | map orientation; // 0 = ->, 1 = <- 16 | 17 | void add_orientation(int a, int b, bool orient) { 18 | orientation[{a, b}] = orient; 19 | orientation[{b, a}] = !orient; 20 | } 21 | 22 | void dfs_cycle(int v, int start) { 23 | if (v == start) return; 24 | for (int u: graph[v].edges) { 25 | if (!orientation.count({u, v}) && graph[u].c == graph[v].c) { 26 | add_orientation(v, u, false); 27 | dfs_cycle(u, start); 28 | } 29 | } 30 | } 31 | 32 | void dfs(int v) { 33 | for (int u: graph[v].edges) { 34 | if (!orientation.count({u, v})) { 35 | if (graph[v].c >= graph[u].c) { 36 | add_orientation(v, u, false); 37 | } else { 38 | add_orientation(v, u, true); 39 | } 40 | if (graph[v].c == graph[u].c) { 41 | dfs_cycle(u, v); 42 | } 43 | dfs(u); 44 | } 45 | } 46 | } 47 | 48 | int main() { 49 | std::ios_base::sync_with_stdio(false); 50 | std::cin.tie(nullptr); 51 | std::cout.tie(nullptr); 52 | 53 | int n, m; 54 | cin >> n >> m; 55 | graph.resize(n); 56 | 57 | vector q_edges; 58 | for (int i = 0; i < m; i++) { 59 | int u, v; 60 | cin >> u >> v; 61 | u--, v--; 62 | q_edges.emplace_back(u, v); 63 | graph[u].edges.push_back(v); 64 | graph[v].edges.push_back(u); 65 | } 66 | for (int i = 0; i < n; i++) { 67 | cin >> graph[i].c; 68 | } 69 | 70 | for (int i = 0; i < n; i++) { 71 | dfs(i); 72 | } 73 | 74 | for (auto const& e: q_edges) { 75 | cout << (orientation[e] ? "<-" : "->") << '\n'; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /sem-3/solutions/2G.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct node { 6 | int i, SCC; 7 | std::vector edges; 8 | std::vector reverse_edges; 9 | 10 | explicit node(int i) { 11 | this->i = i; 12 | SCC = 0; 13 | } 14 | 15 | void add_edge(node& to) { 16 | edges.emplace_back(to.i); 17 | to.reverse_edges.emplace_back(i); 18 | } 19 | }; 20 | 21 | int n, SCC; 22 | std::vector graph; 23 | std::vector order; 24 | std::vector mark; 25 | 26 | void dfs(int u) { 27 | mark[u] = true; 28 | for (int v: graph[u].edges) { 29 | if (!mark[v]) { 30 | dfs(v); 31 | } 32 | } 33 | order.emplace_back(u); 34 | } 35 | 36 | void reverse_dfs(int u) { 37 | mark[u] = true; 38 | graph[u].SCC = SCC; 39 | for (int v: graph[u].reverse_edges) { 40 | if (!mark[v]) { 41 | reverse_dfs(v); 42 | } 43 | } 44 | } 45 | 46 | void SCC_top_sort() { 47 | for (int i = 0; i < 2 * n; ++i) { 48 | mark.emplace_back(); 49 | } 50 | 51 | for (int i = 0; i < 2 * n; ++i) { 52 | if (!mark[i]) { 53 | dfs(i); 54 | } 55 | } 56 | 57 | std::reverse(order.begin(), order.end()); 58 | std::fill(mark.begin(), mark.end(), false); 59 | 60 | SCC = 0; 61 | for (int i: order) { 62 | if (!mark[i]) { 63 | ++SCC; 64 | reverse_dfs(i); 65 | } 66 | } 67 | } 68 | 69 | void clear() { 70 | graph.clear(); 71 | mark.clear(); 72 | order.clear(); 73 | } 74 | 75 | int main() { 76 | std::ios_base::sync_with_stdio(false); 77 | std::cin.tie(nullptr); 78 | std::cout.tie(nullptr); 79 | 80 | int m, i1, i2; 81 | bool e1, e2; 82 | 83 | while (std::cin >> n >> m) { 84 | clear(); 85 | for (int i = 0; i < 2; ++i) { 86 | for (int j = 0; j < n; ++j) { 87 | graph.emplace_back(j + i * n); 88 | } 89 | } 90 | while (m--) { 91 | std::cin >> i1 >> e1 >> i2 >> e2; 92 | graph[i1 + (e1 ? n : 0)].add_edge(graph[i2 + (e2 ? 0 : n)]); 93 | graph[i2 + (e2 ? n : 0)].add_edge(graph[i1 + (e1 ? 0 : n)]); 94 | } 95 | 96 | SCC_top_sort(); 97 | for (int i = 0; i < n; ++i) { 98 | std::cout << (graph[i].SCC > graph[i + n].SCC); 99 | } 100 | std::cout << '\n'; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /sem-3/solutions/3A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct node { 6 | int depth{}, up{}; 7 | std::vector edges; 8 | }; 9 | 10 | std::vector graph; 11 | std::vector mark; 12 | std::set> bridges; 13 | 14 | void dfs(int v, int p = -1, int depth = 0) { 15 | graph[v].depth = depth; 16 | graph[v].up = depth; 17 | mark[v] = true; 18 | bool flag = false; 19 | for (int u: graph[v].edges) { 20 | if (u == p && !flag) { 21 | flag = true; 22 | continue; 23 | } 24 | if (!mark[u]) { 25 | dfs(u, v, depth + 1); 26 | graph[v].up = std::min(graph[v].up, graph[u].up); 27 | } else { 28 | graph[v].up = std::min(graph[v].up, graph[u].depth); 29 | } 30 | } 31 | if (graph[v].up == graph[v].depth && p != -1) { 32 | bridges.insert(std::make_pair(p, v)); 33 | } 34 | } 35 | 36 | int main() { 37 | std::ios_base::sync_with_stdio(false); 38 | std::cin.tie(nullptr); 39 | std::cout.tie(nullptr); 40 | 41 | std::vector> edges; 42 | int n, m, v, u; 43 | std::cin >> n >> m; 44 | 45 | for (int i = 0; i < n; ++i) { 46 | graph.emplace_back(); 47 | mark.emplace_back(); 48 | } 49 | for (int i = 0; i < m; ++i) { 50 | std::cin >> v >> u; 51 | --v; --u; 52 | graph[v].edges.emplace_back(u); 53 | graph[u].edges.emplace_back(v); 54 | edges.emplace_back(v, u); 55 | } 56 | 57 | for (int i = 0; i < n; ++i) { 58 | if (!mark[i]) { 59 | dfs(i); 60 | } 61 | } 62 | 63 | std::cout << bridges.size() << '\n'; 64 | for (int i = 0; i < edges.size(); ++i) { 65 | if (bridges.count(edges[i]) || bridges.count(std::make_pair(edges[i].second, edges[i].first))) { 66 | std::cout << i + 1 << " "; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /sem-3/solutions/3B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct node { 6 | int depth{}, up{}; 7 | std::vector edges; 8 | }; 9 | 10 | std::vector graph; 11 | std::vector mark; 12 | std::set ans; 13 | 14 | void dfs(int v, int p = -1, int depth = 0) { 15 | graph[v].depth = graph[v].up = depth; 16 | mark[v] = true; 17 | int count_children = 0; 18 | for (int u: graph[v].edges) { 19 | if (u == p) continue; 20 | if (!mark[u]) { 21 | dfs(u, v, depth + 1); 22 | graph[v].up = std::min(graph[v].up, graph[u].up); 23 | if (graph[u].up >= graph[v].depth && p != -1) { 24 | ans.insert(v); 25 | } 26 | ++count_children; 27 | } else { 28 | graph[v].up = std::min(graph[v].up, graph[u].depth); 29 | } 30 | } 31 | if (count_children > 1 && p == -1) { 32 | ans.insert(v); 33 | } 34 | } 35 | 36 | int main() { 37 | std::ios_base::sync_with_stdio(false); 38 | std::cin.tie(nullptr); 39 | std::cout.tie(nullptr); 40 | 41 | int n, m, v, u; 42 | std::cin >> n >> m; 43 | 44 | for (int i = 0; i < n; ++i) { 45 | graph.emplace_back(); 46 | mark.emplace_back(); 47 | } 48 | for (int i = 0; i < m; ++i) { 49 | std::cin >> v >> u; 50 | --v; --u; 51 | graph[v].edges.emplace_back(u); 52 | graph[u].edges.emplace_back(v); 53 | } 54 | 55 | for (int i = 0; i < n; ++i) { 56 | if (!mark[i]) { 57 | dfs(i); 58 | } 59 | } 60 | 61 | std::cout << ans.size() << '\n'; 62 | for (int p: ans) { 63 | std::cout << p + 1 << " "; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /sem-3/solutions/3C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct node { 6 | int depth{}, up{}; 7 | std::vector edges; 8 | }; 9 | 10 | std::vector graph; 11 | std::vector mark; 12 | std::set ans; 13 | int n; 14 | 15 | void dfs(int v, int p = -1, int depth = 0) { 16 | graph[v].depth = graph[v].up = depth; 17 | mark[v] = true; 18 | int count_children = 0; 19 | for (int u: graph[v].edges) { 20 | if (u == p) continue; 21 | if (!mark[u]) { 22 | dfs(u, v, depth + 1); 23 | graph[v].up = std::min(graph[v].up, graph[u].up); 24 | if (graph[u].up >= graph[v].depth && p != -1 && v >= n) { 25 | ans.insert(v); 26 | } 27 | ++count_children; 28 | } else { 29 | graph[v].up = std::min(graph[v].up, graph[u].depth); 30 | } 31 | } 32 | if (count_children > 1 && p == -1 && v >= n) { 33 | ans.insert(v); 34 | } 35 | } 36 | 37 | int main() { 38 | std::ios_base::sync_with_stdio(false); 39 | std::cin.tie(nullptr); 40 | std::cout.tie(nullptr); 41 | 42 | int m, v[3]; 43 | std::cin >> n >> m; 44 | 45 | graph.resize(n + m); 46 | mark.resize(n + m); 47 | for (int i = 0; i < m; ++i) { 48 | for (int &j: v) { 49 | std::cin >> j; 50 | --j; 51 | graph[n + i].edges.emplace_back(j); 52 | graph[j].edges.emplace_back(n + i); 53 | } 54 | } 55 | 56 | for (int i = 0; i < n; ++i) { 57 | if (!mark[i]) { 58 | dfs(i); 59 | } 60 | } 61 | 62 | std::cout << ans.size() << '\n'; 63 | for (int a: ans) { 64 | std::cout << a + 1 - n << " "; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /sem-3/solutions/3E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | struct node { 7 | int depth{}, up{}, cmp{}; 8 | std::vector edges; 9 | }; 10 | 11 | std::vector graph; 12 | std::vector mark; 13 | std::stack st; 14 | int cur_cmp = 1; 15 | 16 | void dfs(int v, int p = -1, int depth = 0) { 17 | st.push(v); 18 | graph[v].depth = depth; 19 | graph[v].up = depth; 20 | mark[v] = true; 21 | bool flag = false; 22 | for (int u: graph[v].edges) { 23 | if (u == p && !flag) { 24 | flag = true; 25 | continue; 26 | } 27 | if (!mark[u]) { 28 | dfs(u, v, depth + 1); 29 | st.push(v); 30 | graph[v].up = std::min(graph[v].up, graph[u].up); 31 | } else { 32 | graph[v].up = std::min(graph[v].up, graph[u].depth); 33 | } 34 | } 35 | if (graph[v].up == graph[v].depth && p != -1) { 36 | while (st.top() != p) { 37 | int u = st.top(); 38 | st.pop(); 39 | graph[u].cmp = cur_cmp; 40 | } 41 | ++cur_cmp; 42 | } 43 | } 44 | 45 | int main() { 46 | std::ios_base::sync_with_stdio(false); 47 | std::cin.tie(nullptr); 48 | std::cout.tie(nullptr); 49 | 50 | int n, m, v, u; 51 | std::cin >> n >> m; 52 | 53 | for (int i = 0; i < n; ++i) { 54 | graph.emplace_back(); 55 | mark.emplace_back(); 56 | } 57 | for (int i = 0; i < m; ++i) { 58 | std::cin >> v >> u; 59 | --v; --u; 60 | graph[v].edges.emplace_back(u); 61 | graph[u].edges.emplace_back(v); 62 | } 63 | 64 | for (int i = 0; i < n; ++i) { 65 | if (!mark[i]) { 66 | dfs(i); 67 | while (!st.empty()) { 68 | u = st.top(); 69 | st.pop(); 70 | graph[u].cmp = cur_cmp; 71 | } 72 | ++cur_cmp; 73 | } 74 | } 75 | 76 | std::cout << cur_cmp - 1 << '\n'; 77 | std::unordered_map index_cmp; // старое -> новое 78 | cur_cmp = 1; 79 | 80 | for (auto const& vertex: graph) { 81 | if (index_cmp.count(vertex.cmp)) { 82 | std::cout << index_cmp[vertex.cmp] << " "; 83 | } else { 84 | index_cmp[vertex.cmp] = cur_cmp; 85 | std::cout << cur_cmp++ << " "; 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /sem-3/solutions/4A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct edge { 5 | int from, to, id; 6 | bool is_fake; 7 | 8 | edge(int from, int to, int id, bool is_fake) { 9 | this->from = from; 10 | this->to = to; 11 | this->id = id; 12 | this->is_fake = is_fake; 13 | } 14 | }; 15 | 16 | struct node { 17 | int deg{}; 18 | std::vector edges; 19 | }; 20 | 21 | std::vector graph; 22 | std::vector mark; 23 | std::vector euler_cycle; 24 | 25 | void add_edge(edge const& e) { 26 | graph[e.from].edges.emplace_back(e); 27 | ++graph[e.from].deg; 28 | graph[e.to].edges.emplace_back(e.to, e.from, e.id, e.is_fake); 29 | ++graph[e.to].deg; 30 | } 31 | 32 | void euler(int v, int p = -1, bool is_fake = false) { 33 | while (!graph[v].edges.empty()) { 34 | auto const e = graph[v].edges.back(); 35 | graph[v].edges.pop_back(); 36 | if (mark[e.id]) continue; 37 | mark[e.id] = true; 38 | euler(e.to, v, e.is_fake); 39 | } 40 | if (p != -1) { 41 | euler_cycle.emplace_back(v, p, 0, is_fake); 42 | } 43 | } 44 | 45 | int main() { 46 | std::ios_base::sync_with_stdio(false); 47 | std::cin.tie(nullptr); 48 | std::cout.tie(nullptr); 49 | 50 | int n, m, v, u; 51 | std::cin >> n >> m; 52 | graph.resize(n); 53 | 54 | for (int i = 0; i < m; ++i) { 55 | std::cin >> v >> u; 56 | --v; --u; 57 | add_edge({v, u, i, false}); 58 | } 59 | 60 | int count_simple_path = 0, prev = -1, id = m; 61 | for (int i = 0; i < n; ++i) { 62 | if (graph[i].deg % 2 == 1) { 63 | if (++count_simple_path % 2 == 1) { 64 | prev = i; 65 | } else { 66 | add_edge({prev, i, id++, true}); 67 | } 68 | } 69 | } 70 | 71 | mark.resize(id); 72 | euler(0); 73 | 74 | count_simple_path /= 2; 75 | std::cout << std::max(count_simple_path, 1) << '\n'; 76 | 77 | if (!count_simple_path) { 78 | std::cout << euler_cycle[0].from + 1 << " "; 79 | for (edge const& e: euler_cycle) { 80 | std::cout << e.to + 1 << " "; 81 | } 82 | return 0; 83 | } 84 | 85 | std::vector> paths(count_simple_path + 1); 86 | int count = 0; 87 | for (edge const& e: euler_cycle) { 88 | paths[count].emplace_back(e.from); 89 | if (e.is_fake) ++count; 90 | } 91 | for (int i: paths.back()) { 92 | std::cout << i + 1 << " "; 93 | } 94 | for (int i = 0; i < paths.size() - 1; ++i) { 95 | for (int j: paths[i]) { 96 | std::cout << j + 1 << " "; 97 | } 98 | std::cout << '\n'; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /sem-3/solutions/4B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | const int MAX_N = 100010, CONSTANT = 256; 6 | 7 | struct node { 8 | int deg_in{}, deg_out{}; 9 | std::vector edges; 10 | }; 11 | 12 | std::vector graph(MAX_N); 13 | std::vector path; 14 | 15 | void dfs(int u) { 16 | while (graph[u].deg_out) { 17 | dfs(graph[u].edges[graph[u].deg_out-- - 1]); 18 | } 19 | path.push_back(u); 20 | } 21 | 22 | void say_NO() { 23 | std::cout << "NO"; 24 | exit(0); 25 | } 26 | 27 | int main() { 28 | std::ios_base::sync_with_stdio(false); 29 | std::cin.tie(nullptr); 30 | std::cout.tie(nullptr); 31 | 32 | int n, start; 33 | std::string s; 34 | std::cin >> n; 35 | 36 | for (int i = 0; i < n; i++) { 37 | std::cin >> s; 38 | start = s[0] * CONSTANT + s[1]; 39 | int end = s[1] * CONSTANT + s[2]; 40 | graph[start].edges.emplace_back(end); 41 | ++graph[end].deg_in; 42 | ++graph[start].deg_out; 43 | } 44 | 45 | int count_start = 0, count_end = 0, count_bad = 0; 46 | for (int i = 0; i < MAX_N; ++i) { 47 | if (graph[i].deg_in == graph[i].deg_out) continue; 48 | if (graph[i].deg_out - graph[i].deg_in == 1) { 49 | start = i; 50 | ++count_start; 51 | } else if (graph[i].deg_in - graph[i].deg_out == 1) { 52 | ++count_end; 53 | } else { 54 | ++count_bad; 55 | } 56 | } 57 | if (count_bad > 0 || count_start != count_end || count_start > 1 || count_end > 1) { 58 | say_NO(); 59 | } 60 | 61 | dfs(start); 62 | if (path.size() != n + 1) { 63 | say_NO(); 64 | } 65 | 66 | reverse(path.begin(), path.end()); 67 | std::string ans; 68 | ans += path[0] / CONSTANT; 69 | for (int p: path) { 70 | ans += p % CONSTANT; 71 | } 72 | 73 | std::cout << "YES" << '\n'; 74 | std::cout << ans; 75 | } 76 | -------------------------------------------------------------------------------- /sem-3/solutions/4C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct edge { 5 | int from, to, id; 6 | bool is_fake; 7 | 8 | edge(int from, int to, int id, bool is_fake) { 9 | this->from = from; 10 | this->to = to; 11 | this->id = id; 12 | this->is_fake = is_fake; 13 | } 14 | }; 15 | 16 | struct node { 17 | int deg{}; 18 | std::vector edges; 19 | }; 20 | 21 | std::vector graph; 22 | std::vector mark; 23 | std::vector euler_cycle; 24 | 25 | void add_edge(edge const& e) { 26 | graph[e.from].edges.emplace_back(e); 27 | ++graph[e.from].deg; 28 | graph[e.to].edges.emplace_back(e.to, e.from, e.id, e.is_fake); 29 | ++graph[e.to].deg; 30 | } 31 | 32 | void euler(int v, int p = -1, bool is_fake = false) { 33 | while (!graph[v].edges.empty()) { 34 | auto const e = graph[v].edges.back(); 35 | graph[v].edges.pop_back(); 36 | if (mark[e.id]) continue; 37 | mark[e.id] = true; 38 | euler(e.to, v, e.is_fake); 39 | } 40 | if (p != -1) { 41 | euler_cycle.emplace_back(v, p, 0, is_fake); 42 | } 43 | } 44 | 45 | int main() { 46 | std::ios_base::sync_with_stdio(false); 47 | std::cin.tie(nullptr); 48 | std::cout.tie(nullptr); 49 | 50 | int n, m, v, u; 51 | std::cin >> n >> m; 52 | graph.resize(n); 53 | 54 | for (int i = 0; i < m; ++i) { 55 | std::cin >> v >> u; 56 | --v; --u; 57 | add_edge({v, u, i, false}); 58 | } 59 | 60 | int count_simple_path = 0, prev = -1, id = m; 61 | for (int i = 0; i < n; ++i) { 62 | if (graph[i].deg % 2 == 1) { 63 | if (++count_simple_path % 2 == 1) { 64 | prev = i; 65 | } else { 66 | add_edge({prev, i, id++, true}); 67 | } 68 | } 69 | } 70 | 71 | mark.resize(id); 72 | euler(0); 73 | 74 | count_simple_path /= 2; 75 | std::cout << std::max(count_simple_path, 1) << '\n'; 76 | 77 | if (!count_simple_path) { 78 | std::cout << euler_cycle[0].from + 1 << " "; 79 | for (edge const& e: euler_cycle) { 80 | std::cout << e.to + 1 << " "; 81 | } 82 | return 0; 83 | } 84 | 85 | std::vector> paths(count_simple_path + 1); 86 | int count = 0; 87 | for (edge const& e: euler_cycle) { 88 | paths[count].emplace_back(e.from); 89 | if (e.is_fake) ++count; 90 | } 91 | for (int i: paths.back()) { 92 | std::cout << i + 1 << " "; 93 | } 94 | for (int i = 0; i < paths.size() - 1; ++i) { 95 | for (int j: paths[i]) { 96 | std::cout << j + 1 << " "; 97 | } 98 | std::cout << '\n'; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /sem-3/solutions/4D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct edge { 6 | int from, to, id; 7 | 8 | edge(int from, int to, int id) { 9 | this->from = from; 10 | this->to = to; 11 | this->id = id; 12 | } 13 | }; 14 | 15 | struct node { 16 | int deg{}; 17 | std::vector edges; 18 | }; 19 | 20 | std::vector graph; 21 | std::vector mark; 22 | std::vector euler_cycle; 23 | 24 | void euler(int v, int p = -1) { 25 | while (!graph[v].edges.empty()) { 26 | auto const e = graph[v].edges.back(); 27 | graph[v].edges.pop_back(); 28 | if (mark[e.id]) continue; 29 | mark[e.id] = true; 30 | euler(e.to, v); 31 | } 32 | if (p != -1) { 33 | euler_cycle.emplace_back(v, p, 0); 34 | } 35 | } 36 | 37 | int main() { 38 | std::ios_base::sync_with_stdio(false); 39 | std::cin.tie(nullptr); 40 | std::cout.tie(nullptr); 41 | 42 | int n; 43 | std::cin >> n; 44 | graph.resize(n); 45 | 46 | int m, to, len, edge_id = 0; 47 | for (int i = 0; i < n; ++i) { 48 | std::cin >> m; 49 | for (int j = 0; j < m; ++j) { 50 | std::cin >> to >> len; 51 | --to; 52 | if (to < i) continue; 53 | graph[i].edges.emplace_back(i, to, edge_id); 54 | graph[to].edges.emplace_back(to, i, edge_id++); 55 | ++graph[i].deg; 56 | ++graph[to].deg; 57 | } 58 | } 59 | 60 | int start = 0; 61 | for (int i = 0; i < n; ++i) { 62 | if (graph[i].deg % 2 == 1) { 63 | start = i; 64 | } 65 | } 66 | 67 | mark.resize(edge_id); 68 | euler(start); 69 | 70 | std::cout << euler_cycle.size() << '\n'; 71 | std::cout << euler_cycle[0].from + 1 << " "; 72 | for (edge const& e: euler_cycle) { 73 | std::cout << e.to + 1 << " "; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /sem-3/solutions/5A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | const int INFINITY = INT32_MAX; 8 | 9 | struct Node { 10 | vector edges; 11 | }; 12 | 13 | pair> bfs(vector& graph, int from, int to) { 14 | vector dist(graph.size(), INFINITY); 15 | dist[from] = 0; 16 | vector p(graph.size(), -1); 17 | queue q; 18 | q.push(from); 19 | while (!q.empty()) { 20 | int u = q.front(); 21 | q.pop(); 22 | for (int v: graph[u].edges) { 23 | if (dist[v] == INFINITY) { 24 | dist[v] = dist[u] + 1; 25 | p[v] = u; 26 | q.push(v); 27 | } 28 | } 29 | } 30 | vector path; 31 | int cur = to; 32 | while (p[cur] != -1 && cur != from) { 33 | path.push_back(cur); 34 | cur = p[cur]; 35 | } 36 | path.push_back(from); 37 | return {dist[to], path}; 38 | } 39 | 40 | int main() { 41 | ios_base::sync_with_stdio(false); 42 | cin.tie(nullptr); 43 | cout.tie(nullptr); 44 | 45 | int n, m; 46 | cin >> n >> m; 47 | vector graph(n); 48 | 49 | for (int i = 0; i < m; i++) { 50 | int from, to; 51 | cin >> from >> to; 52 | graph[from - 1].edges.push_back(to - 1); 53 | } 54 | 55 | int s, t; 56 | cin >> s >> t; 57 | auto ans = bfs(graph, s - 1, t - 1); 58 | if (ans.first == INFINITY) { 59 | cout << "-1" << '\n'; 60 | return 0; 61 | } 62 | cout << ans.first << '\n'; 63 | for (auto i = ans.second.rbegin(); i != ans.second.rend(); i++) { 64 | cout << *i + 1 << " "; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /sem-3/solutions/5C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | const int INFINITY = INT32_MAX; 8 | 9 | struct Edge { 10 | int to, cost; 11 | 12 | Edge(int to, int cost) : to(to), cost(cost) {} 13 | }; 14 | 15 | struct Node { 16 | vector edges; 17 | }; 18 | 19 | int bfs(vector& graph, int from, int to) { 20 | vector cost(graph.size(), INFINITY); 21 | cost[from] = 0; 22 | 23 | deque dq; 24 | dq.push_back(from); 25 | while (!dq.empty()) { 26 | int u = dq.front(); 27 | dq.pop_front(); 28 | for (auto const& v: graph[u].edges) { 29 | if (cost[v.to] > cost[u] + v.cost) { 30 | cost[v.to] = cost[u] + v.cost; 31 | if (v.cost) { 32 | dq.push_back(v.to); 33 | } else { 34 | dq.push_front(v.to); 35 | } 36 | } 37 | } 38 | } 39 | 40 | return cost[to] == INFINITY ? -1 : cost[to]; 41 | } 42 | 43 | int main() { 44 | ios_base::sync_with_stdio(false); 45 | cin.tie(nullptr); 46 | cout.tie(nullptr); 47 | 48 | int n, m; 49 | cin >> n >> m; 50 | vector graph(n); 51 | 52 | for (int i = 0; i < m; i++) { 53 | int from, to; 54 | cin >> from >> to; 55 | from--, to--; 56 | graph[from].edges.emplace_back(to, 0); 57 | graph[to].edges.emplace_back(from, 1); 58 | } 59 | 60 | int k; 61 | cin >> k; 62 | for (int i = 0; i < k; i++) { 63 | int s, t; 64 | cin >> s >> t; 65 | cout << bfs(graph, s - 1, t - 1) << '\n'; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /sem-3/solutions/5D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | const int N = 10'000; 8 | const int INFINITY = INT32_MAX; 9 | 10 | struct Node { 11 | vector edges; 12 | }; 13 | 14 | vector bfs(vector& graph, int from, int to) { 15 | vector dist(graph.size(), INFINITY); 16 | dist[from] = 0; 17 | vector p(graph.size(), -1); 18 | 19 | queue q; 20 | q.push(from); 21 | while (!q.empty()) { 22 | int u = q.front(); 23 | q.pop(); 24 | for (int v: graph[u].edges) { 25 | if (dist[v] == INFINITY) { 26 | dist[v] = dist[u] + 1; 27 | p[v] = u; 28 | q.push(v); 29 | } 30 | } 31 | } 32 | 33 | vector path; 34 | while (p[to] != -1 && to != from) { 35 | path.push_back(to); 36 | to = p[to]; 37 | } 38 | path.push_back(from); 39 | 40 | return path; 41 | } 42 | 43 | int main() { 44 | ios_base::sync_with_stdio(false); 45 | cin.tie(nullptr); 46 | cout.tie(nullptr); 47 | 48 | vector graph(N); 49 | for (int i = 1111; i < N; i++) { 50 | if (i % 1000 != 9) { 51 | graph[i].edges.push_back(i + 1000); 52 | } 53 | if (i % 10 != 1) { 54 | graph[i].edges.push_back(i - 1); 55 | } 56 | graph[i].edges.push_back((i % 1000) * 10 + (i / 1000)); 57 | graph[i].edges.push_back((i % 10) * 1000 + (i / 10)); 58 | } 59 | 60 | int from, to; 61 | cin >> from >> to; 62 | 63 | vector ans = bfs(graph, from, to); 64 | for (auto i = ans.rbegin(); i != ans.rend(); i++) { 65 | cout << *i << '\n'; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /sem-3/solutions/5E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | const int INFINITY = INT32_MAX; 9 | 10 | struct Edge { 11 | int to, type; 12 | 13 | Edge(int to, int type) : to(to), type(type) {} 14 | }; 15 | 16 | struct Node { 17 | vector edges; 18 | }; 19 | 20 | vector bfs(vector& graph, int start) { 21 | int n = (int) graph.size(); 22 | 23 | vector> dist(2, std::vector(n, INFINITY)); 24 | dist[0][start] = 0; 25 | dist[1][start] = 0; 26 | 27 | queue> q; 28 | q.emplace(start, 0); 29 | q.emplace(start, 1); 30 | while (!q.empty()) { 31 | auto [from, prev_type] = q.front(); 32 | q.pop(); 33 | for (auto const& [to, type]: graph[from].edges) { 34 | if ((prev_type + type == 1) && dist[type][to] > dist[prev_type][from] + 1) { 35 | dist[type][to] = dist[prev_type][from] + 1; 36 | q.emplace(to, type); 37 | } 38 | } 39 | } 40 | 41 | vector ans(n - 1); 42 | for (int i = 0; i != start && i < n; i++) { 43 | ans[i] = min(dist[0][i], dist[1][i]); 44 | if (ans[i] == INFINITY) { 45 | ans[i] = -1; 46 | } 47 | } 48 | 49 | return ans; 50 | } 51 | 52 | template 53 | void print_vector(vector const& v) { 54 | for (auto const& x: v) { 55 | cout << x << " "; 56 | } 57 | cout << '\n'; 58 | } 59 | 60 | int main() { 61 | ios_base::sync_with_stdio(false); 62 | cin.tie(nullptr); 63 | cout.tie(nullptr); 64 | 65 | int n, m; 66 | cin >> n >> m; 67 | vector graph(n); 68 | 69 | for (int i = 0; i < m; i++) { 70 | int from, to, type; 71 | cin >> from >> to >> type; 72 | graph[to - 1].edges.emplace_back(from - 1, type - 1); 73 | } 74 | 75 | print_vector(bfs(graph, n - 1)); 76 | } 77 | -------------------------------------------------------------------------------- /sem-3/solutions/6A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | typedef pair point; 8 | 9 | const int INFINITY = INT32_MAX; 10 | 11 | int get_distance(point const& a, point const& b) { 12 | int x_diff = a.first - b.first; 13 | int y_diff = a.second - b.second; 14 | return x_diff * x_diff + y_diff * y_diff; 15 | } 16 | 17 | int Dijkstra(vector& graph, int s, int t) { 18 | vector mark(graph.size()); 19 | vector dist(graph.size(), INFINITY); 20 | dist[s] = 0; 21 | 22 | while (true) { 23 | int v = -1; 24 | for (int i = 0; i < graph.size(); i++) { 25 | if (!mark[i] && (v == -1 || dist[i] < dist[v])) { 26 | v = i; 27 | } 28 | } 29 | if (v == -1) { 30 | break; 31 | } 32 | mark[v] = true; 33 | for (int i = 0; i < graph.size(); i++) { 34 | dist[i] = min(dist[i], dist[v] + get_distance(graph[v], graph[i])); 35 | } 36 | } 37 | 38 | return dist[t]; 39 | } 40 | 41 | int main() { 42 | ios_base::sync_with_stdio(false); 43 | cin.tie(nullptr); 44 | cout.tie(nullptr); 45 | 46 | int n; 47 | cin >> n; 48 | vector graph(n); 49 | 50 | for (int i = 0; i < n; i++) { 51 | cin >> graph[i].first >> graph[i].second; 52 | } 53 | 54 | int s, t; 55 | cin >> s >> t; 56 | 57 | cout << Dijkstra(graph, s - 1, t - 1) << '\n'; 58 | } 59 | -------------------------------------------------------------------------------- /sem-3/solutions/6B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | const int INFINITY = 1'000'000; 8 | const int NO_PATH = 30'000; 9 | 10 | int main() { 11 | ios_base::sync_with_stdio(false); 12 | cin.tie(nullptr); 13 | cout.tie(nullptr); 14 | 15 | int n, m; 16 | cin >> n >> m; 17 | 18 | vector> d(n, vector(n, INFINITY)); 19 | for (int i = 0; i < n; i++) { 20 | d[i][i] = 0; 21 | } 22 | 23 | for (int i = 0; i < m; i++) { 24 | int from, to, weight; 25 | cin >> from >> to >> weight; 26 | from--, to--; 27 | d[from][to] = min(d[from][to], weight); 28 | } 29 | 30 | for (int k = 0; k < n; k++) { 31 | for (int i = 0; i < n; i++) { 32 | for (int j = 0; j < n; j++) { 33 | d[i][j] = min(d[i][j], d[i][k] + d[k][j]); 34 | } 35 | } 36 | } 37 | 38 | for (int i = 0; i < n; i++) { 39 | for (int j = 0; j < n; j++) { 40 | if (d[i][j] > INFINITY / 2) { 41 | cout << NO_PATH << " "; 42 | } else { 43 | cout << d[i][j] << " "; 44 | } 45 | } 46 | cout << '\n'; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /sem-3/solutions/6C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | typedef pair edge; 7 | 8 | const int INFINITY = INT32_MAX; 9 | const int NO_PATH = 30'000; 10 | 11 | struct Node { 12 | vector edges; 13 | }; 14 | 15 | vector Bellman_Ford(vector& graph, int s) { 16 | int n = (int) graph.size(); 17 | vector d(n, INFINITY); 18 | d[s] = 0; 19 | for (int k = 1; k < n; k++) { 20 | for (int v = 0; v < n; v++) { 21 | if (d[v] == INFINITY) continue; 22 | for (auto const& e: graph[v].edges) { 23 | d[e.first] = min(d[e.first], d[v] + e.second); 24 | } 25 | } 26 | } 27 | return d; 28 | } 29 | 30 | int main() { 31 | ios_base::sync_with_stdio(false); 32 | cin.tie(nullptr); 33 | cout.tie(nullptr); 34 | 35 | int n, m; 36 | cin >> n >> m; 37 | vector graph(n); 38 | 39 | for (int i = 0; i < m; i++) { 40 | int from, to, weight; 41 | cin >> from >> to >> weight; 42 | graph[from - 1].edges.emplace_back(to - 1, weight); 43 | } 44 | 45 | vector d = Bellman_Ford(graph, 0); 46 | for (int x: d) { 47 | cout << (x == INFINITY ? NO_PATH : x) << " "; 48 | } 49 | cout << '\n'; 50 | } 51 | -------------------------------------------------------------------------------- /sem-3/solutions/6D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | typedef pair edge; 8 | 9 | const int INFINITY = INT32_MAX; 10 | 11 | struct Node { 12 | vector edges; 13 | }; 14 | 15 | vector Dijkstra(vector& graph, int s) { 16 | vector d(graph.size(), INFINITY); 17 | d[s] = 0; 18 | 19 | set> set; 20 | set.emplace(0, 0); 21 | 22 | while (!set.empty()) { 23 | auto first = set.begin(); 24 | int v = (*first).second; 25 | set.erase(first); 26 | for (auto const& e: graph[v].edges) { 27 | if (d[v] + e.second < d[e.first]) { 28 | set.erase({d[e.first], e.first}); 29 | d[e.first] = d[v] + e.second; 30 | set.insert({d[e.first], e.first}); 31 | } 32 | } 33 | } 34 | 35 | return d; 36 | } 37 | 38 | template 39 | void print_vector(vector const& v) { 40 | for (T const& x: v) { 41 | cout << x << " "; 42 | } 43 | cout << '\n'; 44 | } 45 | 46 | int main() { 47 | ios_base::sync_with_stdio(false); 48 | cin.tie(nullptr); 49 | cout.tie(nullptr); 50 | 51 | int n, m; 52 | cin >> n >> m; 53 | vector graph(n); 54 | 55 | for (int i = 0; i < m; i++) { 56 | int from, to, weight; 57 | cin >> from >> to >> weight; 58 | graph[from - 1].edges.emplace_back(to - 1, weight); 59 | graph[to - 1].edges.emplace_back(from - 1, weight); 60 | } 61 | 62 | print_vector(Dijkstra(graph, 0)); 63 | } 64 | -------------------------------------------------------------------------------- /sem-3/solutions/6E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | const int INFINITY = 1'000'000'000; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | cout.tie(nullptr); 13 | 14 | int n; 15 | cin >> n; 16 | 17 | vector> d(n, vector(n, INFINITY)); 18 | for (int i = 0; i < n; i++) { 19 | d[i][i] = 0; 20 | } 21 | 22 | for (int i = 0; i < n; i++) { 23 | for (int j = 0; j < n; j++) { 24 | int val; 25 | cin >> val; 26 | if (val) { 27 | d[i][j] = min(d[i][j], val); 28 | } 29 | } 30 | } 31 | 32 | for (int k = 0; k < n; k++) { 33 | for (int i = 0; i < n; i++) { 34 | for (int j = 0; j < n; j++) { 35 | d[i][j] = min(d[i][j], d[i][k] + d[k][j]); 36 | } 37 | } 38 | } 39 | 40 | for (int i = 0; i < n; i++) { 41 | for (int j = 0; j < n; j++) { 42 | cout << (d[i][j] < INFINITY / 2) << " "; 43 | } 44 | cout << '\n'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /sem-3/solutions/6F.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | const int INFINITY = INT32_MAX; 8 | const int NO_EDGE = 100'000; 9 | 10 | int main() { 11 | ios_base::sync_with_stdio(false); 12 | cin.tie(nullptr); 13 | cout.tie(nullptr); 14 | 15 | int n, m; 16 | cin >> n; 17 | 18 | vector> d(n, vector(n, INFINITY)); 19 | for (int i = 0; i < n; i++) { 20 | d[i][i] = 0; 21 | } 22 | 23 | for (int i = 0; i < n; i++) { 24 | for (int j = 0; j < n; j++) { 25 | int weight; 26 | cin >> weight; 27 | if (weight == NO_EDGE) { 28 | continue; 29 | } 30 | d[i][j] = min(d[i][j], weight); 31 | } 32 | } 33 | 34 | for (int k = 0; k < n; k++) { 35 | for (int i = 0; i < n; i++) { 36 | for (int j = 0; j < n; j++) { 37 | if (d[i][k] != INFINITY && d[k][j] != INFINITY) { 38 | d[i][j] = min(d[i][j], d[i][k] + d[k][j]); 39 | } 40 | } 41 | } 42 | } 43 | 44 | for (int i = 0; i < n; i++) { 45 | if (d[i][i] < 0) { 46 | cout << "YES" << '\n'; 47 | return 0; 48 | } 49 | } 50 | cout << "NO" << '\n'; 51 | } 52 | -------------------------------------------------------------------------------- /sem-3/solutions/6G.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | typedef pair edge; 7 | 8 | const int INFINITY = INT32_MAX; 9 | 10 | struct Node { 11 | vector edges; 12 | }; 13 | 14 | vector Bellman_Ford(vector& graph, int s, int k) { 15 | int n = (int) graph.size(); 16 | 17 | vector> d(k + 1, vector(n, INFINITY)); 18 | d[0][s] = 0; 19 | 20 | for (int i = 1; i < k + 1; i++) { 21 | for (int v = 0; v < n; v++) { 22 | if (d[i - 1][v] == INFINITY) continue; 23 | for (auto const& [to, weight]: graph[v].edges) { 24 | if (d[i][to] > d[i - 1][v] + weight) { 25 | d[i][to] = d[i - 1][v] + weight; 26 | } 27 | } 28 | } 29 | } 30 | 31 | vector ans(n, INFINITY); 32 | for (int i = 0; i < n; i++) { 33 | ans[i] = d[k][i] == INFINITY ? -1 : d[k][i]; 34 | } 35 | 36 | return ans; 37 | } 38 | 39 | template 40 | void print_vector(vector const& v) { 41 | for (auto const& x: v) { 42 | cout << x << '\n'; 43 | } 44 | } 45 | 46 | int main() { 47 | ios_base::sync_with_stdio(false); 48 | cin.tie(nullptr); 49 | cout.tie(nullptr); 50 | 51 | int n, m, k, s; 52 | cin >> n >> m >> k >> s; 53 | vector graph(n); 54 | 55 | for (int i = 0; i < m; i++) { 56 | int from, to, weight; 57 | cin >> from >> to >> weight; 58 | graph[from - 1].edges.emplace_back(to - 1, weight); 59 | } 60 | 61 | print_vector(Bellman_Ford(graph, s - 1, k)); 62 | } 63 | -------------------------------------------------------------------------------- /sem-3/solutions/6H.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | typedef pair edge; 8 | 9 | const int INFINITY = INT32_MAX; 10 | const int NO_EDGE = 100'000; 11 | 12 | struct Node { 13 | vector edges; 14 | }; 15 | 16 | vector Bellman_Ford(vector& graph, int s) { 17 | int n = (int) graph.size(); 18 | 19 | vector d(n, INFINITY); 20 | vector p(n); 21 | for (int i = 0; i < n; i++) { 22 | p[i] = i; 23 | } 24 | d[s] = 0; 25 | 26 | for (int i = 1; i < n; i++) { 27 | for (int v = 0; v < n; v++) { 28 | if (d[v] == INFINITY) continue; 29 | for (auto const& [to, weight]: graph[v].edges) { 30 | if (d[to] > d[v] + weight) { 31 | d[to] = d[v] + weight; 32 | p[to] = v; 33 | } 34 | } 35 | } 36 | } 37 | 38 | vector cycle; 39 | for (int v = 0; v < n; v++) { 40 | if (d[v] == INFINITY) continue; 41 | for (auto [to, weight]: graph[v].edges) { 42 | if (d[to] > d[v] + weight) { 43 | for (int i = 0; i < n; i++) { 44 | to = p[to]; 45 | } 46 | int u = to; 47 | while (true) { 48 | if (u == to && !cycle.empty()) { 49 | break; 50 | } 51 | cycle.push_back(u); 52 | u = p[u]; 53 | } 54 | reverse(cycle.begin(), cycle.end()); 55 | return cycle; 56 | } 57 | } 58 | } 59 | 60 | return cycle; 61 | } 62 | 63 | template 64 | void print_vector(vector const& v) { 65 | for (auto const& x: v) { 66 | cout << x + 1 << " "; 67 | } 68 | cout << '\n'; 69 | } 70 | 71 | int main() { 72 | ios_base::sync_with_stdio(false); 73 | cin.tie(nullptr); 74 | cout.tie(nullptr); 75 | 76 | int n; 77 | cin >> n; 78 | vector graph(n); 79 | 80 | for (int i = 0; i < n; i++) { 81 | for (int j = 0; j < n; j++) { 82 | int weight; 83 | cin >> weight; 84 | if (weight != NO_EDGE) { 85 | graph[i].edges.emplace_back(j, weight); 86 | } 87 | } 88 | } 89 | 90 | for (int i = 0; i < n; i++) { 91 | auto v = Bellman_Ford(graph, i); 92 | if (!v.empty()) { 93 | cout << "YES" << '\n'; 94 | cout << v.size() << '\n'; 95 | print_vector(v); 96 | return 0; 97 | } 98 | } 99 | cout << "NO" << '\n'; 100 | } 101 | -------------------------------------------------------------------------------- /sem-3/solutions/6I.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | const int INFINITY = INT32_MAX; 8 | 9 | vector> Floyd(vector>& d, int k) { 10 | int n = (int) d.size(); 11 | 12 | for (int i = 0; i < n; i++) { 13 | for (int j = 0; j < n; j++) { 14 | d[i][j] = min(d[i][j], d[i][k] + d[k][j]); 15 | } 16 | } 17 | 18 | return d; 19 | } 20 | 21 | template 22 | void print_vector(vector const& v) { 23 | for (auto const& x: v) { 24 | cout << x << " "; 25 | } 26 | cout << '\n'; 27 | } 28 | 29 | int main() { 30 | ios_base::sync_with_stdio(false); 31 | cin.tie(nullptr); 32 | cout.tie(nullptr); 33 | 34 | int n; 35 | cin >> n; 36 | 37 | vector> d(n, vector(n)); 38 | for (int i = 0; i < n; i++) { 39 | for (int j = 0; j < n; j++) { 40 | cin >> d[i][j]; 41 | } 42 | } 43 | 44 | vector remove_nodes(n); 45 | for (int i = 0; i < n; i++) { 46 | cin >> remove_nodes[i]; 47 | remove_nodes[i]--; 48 | } 49 | 50 | vector result(n); 51 | vector mark(n); 52 | for (int x = n - 1; x >= 0; x--) { 53 | int rm = remove_nodes[x]; 54 | mark[rm] = true; 55 | Floyd(d, rm); 56 | for (int i = 0; i < n; i++) { 57 | for (int j = 0; j < n; j++) { 58 | if (mark[i] && mark[j]) { 59 | result[x] += d[i][j]; 60 | } 61 | } 62 | } 63 | } 64 | 65 | print_vector(result); 66 | } 67 | -------------------------------------------------------------------------------- /sem-3/solutions/7A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | typedef pair point; 9 | 10 | double get_distance(point const& a, point const& b) { 11 | return sqrt(pow(a.first - b.first, 2) + pow(a.second - b.second, 2)); 12 | } 13 | 14 | double Prim(vector const& graph) { 15 | int n = (int) graph.size(); 16 | 17 | vector mark(n); 18 | vector min_edge(n, DBL_MAX); 19 | min_edge[0] = DBL_MIN; 20 | 21 | double MST_weight = 0; 22 | while (true) { 23 | int v = -1; 24 | for (int i = 0; i < n; i++) { 25 | if (!mark[i] && (v == -1 || min_edge[i] < min_edge[v])) { 26 | v = i; 27 | } 28 | } 29 | if (v == -1) { 30 | break; 31 | } 32 | mark[v] = true; 33 | MST_weight += min_edge[v]; 34 | for (int i = 0; i < n; i++) { 35 | if (!mark[i]) { 36 | double d = get_distance(graph[v], graph[i]); 37 | if (min_edge[i] > d) { 38 | min_edge[i] = d; 39 | } 40 | } 41 | } 42 | } 43 | 44 | return MST_weight; 45 | } 46 | 47 | int main() { 48 | ios_base::sync_with_stdio(false); 49 | cin.tie(nullptr); 50 | cout.tie(nullptr); 51 | 52 | int n; 53 | cin >> n; 54 | vector graph(n); 55 | 56 | for (int i = 0; i < n; i++) { 57 | cin >> graph[i].first >> graph[i].second; 58 | } 59 | 60 | printf("%.10f\n", Prim(graph)); 61 | } 62 | -------------------------------------------------------------------------------- /sem-3/solutions/7B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | struct DSU { 8 | vector parent; 9 | vector rank; 10 | 11 | explicit DSU(int size) { 12 | parent.resize(size); 13 | rank.resize(size); 14 | for (int i = 0; i < size; i++) { 15 | parent[i] = i; 16 | rank[i] = 0; 17 | } 18 | } 19 | 20 | int find(int i) { 21 | if (i == parent[i]) { 22 | return i; 23 | } 24 | return parent[i] = find(parent[i]); 25 | } 26 | 27 | void connect(int x, int y) { 28 | x = find(x); 29 | y = find(y); 30 | if (x != y) { 31 | if (rank[x] < rank[y]) { 32 | swap(x, y); 33 | } 34 | parent[y] = x; 35 | if (rank[x] == rank[y]) { 36 | rank[x]++; 37 | } 38 | } 39 | } 40 | 41 | bool is_connected(int x, int y) { 42 | return find(x) == find(y); 43 | } 44 | }; 45 | 46 | struct Edge { 47 | int from, to, weight; 48 | 49 | Edge(int from, int to, int weight) : from(from), to(to), weight(weight) {} 50 | }; 51 | 52 | long long Kruskal(vector& edges, int n) { 53 | sort(edges.begin(), edges.end(), [](Edge const& a, Edge const& b) { 54 | return a.weight < b.weight; 55 | }); 56 | DSU dsu(n); 57 | long long MST_weight = 0; 58 | int count_nodes = 0; 59 | for (auto const& e: edges) { 60 | if (!dsu.is_connected(e.from, e.to)) { 61 | MST_weight += e.weight; 62 | count_nodes++; 63 | if (count_nodes == n - 1) { 64 | break; 65 | } 66 | dsu.connect(e.from, e.to); 67 | } 68 | } 69 | return MST_weight; 70 | } 71 | 72 | int main() { 73 | ios_base::sync_with_stdio(false); 74 | cin.tie(nullptr); 75 | cout.tie(nullptr); 76 | 77 | int n, m; 78 | cin >> n >> m; 79 | 80 | vector edges; 81 | for (int i = 0; i < m; i++) { 82 | int from, to, weight; 83 | cin >> from >> to >> weight; 84 | edges.emplace_back(from - 1, to - 1, weight); 85 | } 86 | 87 | cout << Kruskal(edges, n) << '\n'; 88 | } 89 | -------------------------------------------------------------------------------- /sem-3/solutions/7C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | template 7 | void print_vector(vector const& v) { 8 | for (auto const& x: v) { 9 | cout << x << '\n'; 10 | } 11 | } 12 | 13 | int main() { 14 | ios_base::sync_with_stdio(false); 15 | cin.tie(nullptr); 16 | cout.tie(nullptr); 17 | 18 | int n; 19 | cin >> n; 20 | 21 | vector a(n); 22 | vector pref(n + 2); 23 | for (int i = 0; i < n; i++) { 24 | cin >> a[i]; 25 | pref[i + 1] = pref[i] + a[i]; 26 | } 27 | 28 | vector mark_order(n); 29 | for (int i = 0; i < n; i++) { 30 | cin >> mark_order[i]; 31 | } 32 | 33 | vector left_mark(n + 2), right_mark(n + 2); 34 | vector answer(n); 35 | long long max_sum = 0LL; 36 | for (int i = n - 1; i >= 0; i--) { 37 | answer[i] = max_sum; 38 | 39 | int mark = mark_order[i]; 40 | int left = left_mark[mark - 1] == 0 ? mark : left_mark[mark - 1]; 41 | int right = right_mark[mark + 1] == 0 ? mark : right_mark[mark + 1]; 42 | 43 | if (pref[right] - pref[left - 1] > max_sum) { 44 | max_sum = pref[right] - pref[left - 1]; 45 | } 46 | 47 | left_mark[right] = left; 48 | right_mark[left] = right; 49 | } 50 | 51 | print_vector(answer); 52 | } 53 | -------------------------------------------------------------------------------- /sem-3/solutions/7D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | struct DSU { 8 | vector p; 9 | 10 | explicit DSU(int size) { 11 | p.resize(size); 12 | for (int i = 0; i < size; i++) { 13 | p[i] = i; 14 | } 15 | } 16 | 17 | int find(int x) { 18 | if (p[x] != x) { 19 | p[x] = find(p[x]); 20 | } 21 | return p[x]; 22 | } 23 | 24 | void join(int x, int y) { 25 | x = find(x); 26 | y = find(y); 27 | p[x] = y; 28 | } 29 | 30 | bool ask(int x, int y) { 31 | return find(x) == find(y); 32 | } 33 | }; 34 | 35 | int main() { 36 | ios_base::sync_with_stdio(false); 37 | cin.tie(nullptr); 38 | cout.tie(nullptr); 39 | 40 | int n, m, k; 41 | cin >> n >> m >> k; 42 | 43 | DSU dsu(n); 44 | 45 | for (int i = 0; i < m; i++) { 46 | int u, v; 47 | cin >> u >> v; 48 | } 49 | 50 | vector> action(k); 51 | for (int i = 0; i < k; i++) { 52 | cin >> get<0>(action[k - i - 1]) >> get<1>(action[k - i - 1]) >> get<2>(action[k - i - 1]); 53 | } 54 | 55 | vector answer(k - m); 56 | int index = k - m - 1; 57 | for (int i = 0; i < k; i++) { 58 | int u = get<1>(action[i]) - 1; 59 | int v = get<2>(action[i]) - 1; 60 | if (get<0>(action[i])[0] == 'a') { 61 | answer[index--] = dsu.ask(u, v); 62 | } else { 63 | dsu.join(u, v); 64 | } 65 | } 66 | 67 | for (auto const& b: answer) { 68 | cout << (b ? "YES" : "NO") << '\n'; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /sem-3/solutions/7E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | struct DSU { 8 | vector parent; 9 | vector rank; 10 | 11 | explicit DSU(int size) { 12 | parent.resize(size); 13 | rank.resize(size); 14 | for (int i = 0; i < size; i++) { 15 | parent[i] = i; 16 | rank[i] = 0; 17 | } 18 | } 19 | 20 | int find(int i) { 21 | if (i == parent[i]) { 22 | return i; 23 | } 24 | return parent[i] = find(parent[i]); 25 | } 26 | 27 | void connect(int x, int y) { 28 | x = find(x); 29 | y = find(y); 30 | if (x != y) { 31 | if (rank[x] < rank[y]) { 32 | swap(x, y); 33 | } 34 | parent[y] = x; 35 | if (rank[x] == rank[y]) { 36 | rank[x]++; 37 | } 38 | } 39 | } 40 | 41 | bool is_connected(int x, int y) { 42 | return find(x) == find(y); 43 | } 44 | }; 45 | 46 | struct Edge { 47 | int from, to, weight, id; 48 | 49 | Edge(int from, int to, int weight, int id) : from(from), to(to), weight(weight), id(id) {} 50 | }; 51 | 52 | pair> Kruskal(vector& edges, int ban, int n) { 53 | DSU dsu(n); 54 | vector taken_edges; 55 | int MST_weight = 0, count_nodes = 0; 56 | for (auto const& e: edges) { 57 | if (!dsu.is_connected(e.from, e.to) && e.id != ban) { 58 | MST_weight += e.weight; 59 | taken_edges.push_back(e.id); 60 | count_nodes++; 61 | if (count_nodes == n - 1) { 62 | break; 63 | } 64 | dsu.connect(e.from, e.to); 65 | } 66 | } 67 | return {count_nodes == n - 1 ? MST_weight : INT32_MAX, taken_edges}; 68 | } 69 | 70 | int main() { 71 | ios_base::sync_with_stdio(false); 72 | cin.tie(nullptr); 73 | cout.tie(nullptr); 74 | 75 | int n, m; 76 | cin >> n >> m; 77 | 78 | vector edges; 79 | for (int i = 0; i < m; i++) { 80 | int from, to, weight; 81 | cin >> from >> to >> weight; 82 | edges.emplace_back(from - 1, to - 1, weight, i); 83 | } 84 | 85 | sort(edges.begin(), edges.end(), [](Edge const& a, Edge const& b) { 86 | return a.weight < b.weight; 87 | }); 88 | 89 | auto [min1, taken_edges] = Kruskal(edges, -1, n); 90 | 91 | int min2 = INT32_MAX; 92 | for (int id: taken_edges) { 93 | min2 = min(min2, Kruskal(edges, id, n).first); 94 | } 95 | 96 | cout << min1 << " " << min2 << '\n'; 97 | } 98 | -------------------------------------------------------------------------------- /sem-3/solutions/7H.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | vector> edges; 8 | set not_mark; 9 | 10 | void dfs(int u) { 11 | not_mark.erase(u); 12 | vector v; 13 | for (int x: not_mark) { 14 | if (edges[u].find(x) == edges[u].end()) { 15 | v.push_back(x); 16 | } 17 | } 18 | for (int x: v) { 19 | not_mark.erase(x); 20 | } 21 | for (int x: v) { 22 | dfs(x); 23 | } 24 | } 25 | 26 | int main() { 27 | ios_base::sync_with_stdio(false); 28 | cin.tie(nullptr); 29 | cout.tie(nullptr); 30 | 31 | int n, m; 32 | cin >> n >> m; 33 | 34 | edges.resize(n); 35 | for (int i = 0; i < n; i++) { 36 | not_mark.insert(i); 37 | } 38 | 39 | for (int i = 0; i < m; i++) { 40 | int u, v; 41 | cin >> u >> v; 42 | edges[u - 1].insert(v - 1); 43 | edges[v - 1].insert(u - 1); 44 | } 45 | 46 | int count = 0; 47 | for (int u = 0; u < n; u++) { 48 | if (not_mark.find(u) != not_mark.end()) { 49 | dfs(u); 50 | count++; 51 | } 52 | } 53 | 54 | cout << count - 1 << '\n'; 55 | } 56 | -------------------------------------------------------------------------------- /sem-3/solutions/7I.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | const int INFINITY = INT32_MAX; 8 | 9 | struct DSU { 10 | vector parent; 11 | vector rank; 12 | 13 | explicit DSU(int size) { 14 | parent.resize(size); 15 | rank.resize(size); 16 | for (int i = 0; i < size; i++) { 17 | parent[i] = i; 18 | rank[i] = 0; 19 | } 20 | } 21 | 22 | int find(int i) { 23 | if (i == parent[i]) { 24 | return i; 25 | } 26 | return parent[i] = find(parent[i]); 27 | } 28 | 29 | void connect(int x, int y) { 30 | x = find(x); 31 | y = find(y); 32 | if (x != y) { 33 | if (rank[x] < rank[y]) { 34 | swap(x, y); 35 | } 36 | parent[y] = x; 37 | if (rank[x] == rank[y]) { 38 | rank[x]++; 39 | } 40 | } 41 | } 42 | 43 | bool is_connected(int x, int y) { 44 | return find(x) == find(y); 45 | } 46 | }; 47 | 48 | struct Edge { 49 | int from, to, weight; 50 | 51 | Edge(int from, int to, int weight) : from(from), to(to), weight(weight) {} 52 | }; 53 | 54 | int Kruskal(vector& edges, int n, int min_weight) { 55 | DSU dsu(n); 56 | int max_weight = 0, count_nodes = 0; 57 | for (auto const& e: edges) { 58 | if (!dsu.is_connected(e.from, e.to) && e.weight >= min_weight) { 59 | max_weight = e.weight; 60 | count_nodes++; 61 | if (count_nodes == n - 1) { 62 | break; 63 | } 64 | dsu.connect(e.from, e.to); 65 | } 66 | } 67 | return count_nodes == n - 1 ? (max_weight - min_weight) : INFINITY; 68 | } 69 | 70 | int main() { 71 | ios_base::sync_with_stdio(false); 72 | cin.tie(nullptr); 73 | cout.tie(nullptr); 74 | 75 | int n, m; 76 | cin >> n >> m; 77 | 78 | vector edges; 79 | for (int i = 0; i < m; i++) { 80 | int from, to, weight; 81 | cin >> from >> to >> weight; 82 | edges.emplace_back(from - 1, to - 1, weight); 83 | } 84 | 85 | sort(edges.begin(), edges.end(), [](Edge const& a, Edge const& b) { 86 | return a.weight < b.weight; 87 | }); 88 | 89 | int min_diff = INFINITY; 90 | for (int i = 0; i < m; i++) { 91 | min_diff = min(min_diff, Kruskal(edges, n, edges[i].weight)); 92 | } 93 | 94 | if (min_diff == INFINITY) { 95 | cout << "NO" << '\n'; 96 | } else { 97 | cout << "YES" << '\n'; 98 | cout << min_diff << '\n'; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /sem-3/solutions/8A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | vector prefix_function(string const& s) { 7 | int n = (int) s.length(); 8 | vector p(n); 9 | p[0] = 0; 10 | for (int i = 1; i < n; i++) { 11 | int j = p[i - 1]; 12 | while (j > 0 && s[i] != s[j]) { 13 | j = p[j - 1]; 14 | } 15 | p[i] = j + (s[i] == s[j]); 16 | } 17 | return p; 18 | } 19 | 20 | template 21 | void print_vector(vector const& v) { 22 | for (T const& x: v) { 23 | cout << x << " "; 24 | } 25 | cout << '\n'; 26 | } 27 | 28 | int main() { 29 | ios_base::sync_with_stdio(false); 30 | cin.tie(nullptr); 31 | cout.tie(nullptr); 32 | 33 | string s; 34 | cin >> s; 35 | print_vector(prefix_function(s)); 36 | } 37 | -------------------------------------------------------------------------------- /sem-3/solutions/8B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | vector z_function(string const& s) { 7 | int n = (int) s.length(); 8 | vector z(n); 9 | int l = 0; 10 | for (int i = 1; i < n; i++) { 11 | z[i] = max(0, min(z[i - l], z[l] + l - i)); 12 | while (i + z[i] < n && s[z[i]] == s[z[i] + i]) { 13 | z[i]++; 14 | } 15 | if (i + z[i] > l + z[l]) { 16 | l = i; 17 | } 18 | } 19 | z[0] = n; 20 | return z; 21 | } 22 | 23 | template 24 | void print_vector(vector const& v) { 25 | for (T const& x: v) { 26 | cout << x << " "; 27 | } 28 | cout << '\n'; 29 | } 30 | 31 | int main() { 32 | ios_base::sync_with_stdio(false); 33 | cin.tie(nullptr); 34 | cout.tie(nullptr); 35 | 36 | string s; 37 | cin >> s; 38 | print_vector(z_function(s)); 39 | } 40 | -------------------------------------------------------------------------------- /sem-3/solutions/8C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | vector z_function(string const& s) { 7 | int n = (int) s.length(); 8 | vector z(n); 9 | int l = 0; 10 | for (int i = 1; i < n; i++) { 11 | z[i] = max(0, min(z[i - l], z[l] + l - i)); 12 | while (i + z[i] < n && s[z[i]] == s[z[i] + i]) { 13 | z[i]++; 14 | } 15 | if (i + z[i] > l + z[l]) { 16 | l = i; 17 | } 18 | } 19 | return z; 20 | } 21 | 22 | int main() { 23 | ios_base::sync_with_stdio(false); 24 | cin.tie(nullptr); 25 | cout.tie(nullptr); 26 | 27 | string s, t; 28 | cin >> s >> t; 29 | 30 | vector z = z_function(t + '#' + s); 31 | for (int i = (int) t.size() + 1; i <= s.size() + 1; i++) { 32 | if (z[i] == (int) t.size()) { 33 | cout << i - t.size() - 1 << " "; 34 | } 35 | } 36 | cout << '\n'; 37 | } 38 | -------------------------------------------------------------------------------- /sem-3/solutions/8D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | vector z_function(string const& s) { 7 | int n = (int) s.length(); 8 | vector z(n); 9 | int l = 0; 10 | for (int i = 1; i < n; i++) { 11 | z[i] = max(0, min(z[i - l], z[l] + l - i)); 12 | while (i + z[i] < n && s[z[i]] == s[z[i] + i]) { 13 | z[i]++; 14 | } 15 | if (i + z[i] > l + z[l]) { 16 | l = i; 17 | } 18 | } 19 | return z; 20 | } 21 | 22 | int main() { 23 | ios_base::sync_with_stdio(false); 24 | cin.tie(nullptr); 25 | cout.tie(nullptr); 26 | 27 | string s1, s2; 28 | cin >> s1 >> s2; 29 | 30 | auto p = z_function(s1 + '#' + s2 + s2); 31 | for (int i = 0; i < p.size(); i++) { 32 | if (p[i] >= s1.size()) { 33 | cout << i - s1.size() - 1 << '\n'; 34 | return 0; 35 | } 36 | } 37 | cout << -1 << '\n'; 38 | } 39 | -------------------------------------------------------------------------------- /sem-3/solutions/8E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | vector z_function(string const& s) { 8 | int n = (int) s.length(); 9 | vector z(n); 10 | int l = 0; 11 | for (int i = 1; i < n; i++) { 12 | z[i] = max(0, min(z[i - l], z[l] + l - i)); 13 | while (i + z[i] < n && s[z[i]] == s[z[i] + i]) { 14 | z[i]++; 15 | } 16 | if (i + z[i] > l + z[l]) { 17 | l = i; 18 | } 19 | } 20 | z[0] = n; 21 | return z; 22 | } 23 | 24 | template 25 | void print_vector(vector const& v) { 26 | for (T const& x: v) { 27 | cout << x << " "; 28 | } 29 | cout << '\n'; 30 | } 31 | 32 | int main() { 33 | ios_base::sync_with_stdio(false); 34 | cin.tie(nullptr); 35 | cout.tie(nullptr); 36 | 37 | int n; 38 | cin >> n; 39 | 40 | string s; 41 | cin >> s; 42 | 43 | string s_rev = s; 44 | reverse(s_rev.begin(), s_rev.end()); 45 | 46 | auto z = z_function(s + '#' + s_rev); 47 | 48 | vector a(n); 49 | for (int i = n + 1; i < z.size(); i++) { 50 | a[2 * n - i] = z[i]; 51 | } 52 | 53 | print_vector(a); 54 | } 55 | -------------------------------------------------------------------------------- /sem-3/solutions/8F.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | const int DELIMITER = INT32_MIN; 8 | 9 | vector z_function(vector const& v) { 10 | int n = (int) v.size(); 11 | vector z(n); 12 | int l = 0; 13 | for (int i = 1; i < n; i++) { 14 | z[i] = max(0, min(z[i - l], z[l] + l - i)); 15 | while (i + z[i] < n && v[z[i]] == v[z[i] + i]) { 16 | z[i]++; 17 | } 18 | if (i + z[i] > l + z[l]) { 19 | l = i; 20 | } 21 | } 22 | return z; 23 | } 24 | 25 | int main() { 26 | ios_base::sync_with_stdio(false); 27 | cin.tie(nullptr); 28 | cout.tie(nullptr); 29 | 30 | int n, k; 31 | cin >> n >> k; 32 | 33 | vector a(2 * n); 34 | for (int i = 0; i < n; i++) { 35 | cin >> a[i]; 36 | a[i + n] = a[i]; 37 | } 38 | 39 | vector b(k); 40 | for (int i = 0; i < k; i++) { 41 | cin >> b[i]; 42 | } 43 | 44 | if (k > n) { 45 | return 0; 46 | } 47 | 48 | if (k == 1) { 49 | for (int i = 0; i < n; i++) { 50 | cout << i + 1 << " "; 51 | } 52 | cout << '\n'; 53 | return 0; 54 | } 55 | 56 | vector ab; 57 | for (int i = 1; i < k; i++) { 58 | ab.push_back(b[i] - b[i - 1]); 59 | } 60 | ab.push_back(DELIMITER); 61 | for (int i = 1; i < 2 * n; i++) { 62 | ab.push_back(a[i] - a[i - 1]); 63 | } 64 | 65 | auto z = z_function(ab); 66 | for (int i = k; i <= k + n - 1; i++) { 67 | if (z[i] == k - 1) { 68 | cout << i - k + 1 << " "; 69 | } 70 | } 71 | cout << '\n'; 72 | } 73 | -------------------------------------------------------------------------------- /sem-3/solutions/9B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | struct Trie { 8 | struct Node { 9 | int size; 10 | map link; 11 | 12 | Node() : size(0) {} 13 | 14 | bool count(char c) { 15 | return link.count(c); 16 | } 17 | 18 | void set(char c, Node* node) { 19 | get(c) = node; 20 | } 21 | 22 | Node*& get(char c) { 23 | return link[c]; 24 | } 25 | }; 26 | 27 | Node* root; 28 | 29 | explicit Trie() : root(new Node()) {} 30 | 31 | long long count_substr(string const& s) { 32 | for (int i = 0; i < s.length(); i++) { 33 | insert(s.substr(i)); 34 | } 35 | 36 | vector> count(s.length() + 1); 37 | dfs(root, count, 0); 38 | 39 | long long res = 0LL; 40 | for (auto const& v : count) { 41 | int sum = 0; 42 | for (int i = (int) v.size() - 1; i >= 0; i--) { 43 | res += sum * v[i]; 44 | sum += v[i]; 45 | } 46 | } 47 | return res; 48 | } 49 | 50 | void insert(string const& s) { 51 | Node* v = root; 52 | for (char c: s) { 53 | if (!v->count(c)) { 54 | v->set(c, new Node()); 55 | } 56 | v = v->get(c); 57 | v->size++; 58 | } 59 | } 60 | 61 | void dfs(Node* v, vector>& count, int depth) { 62 | count[depth].push_back(v->size); 63 | for (auto const& [c, u] : v->link) { 64 | dfs(u, count, depth + 1); 65 | } 66 | } 67 | }; 68 | 69 | int main() { 70 | ios_base::sync_with_stdio(false); 71 | cin.tie(nullptr); 72 | cout.tie(nullptr); 73 | 74 | Trie trie; 75 | 76 | string s; 77 | cin >> s; 78 | cout << trie.count_substr(s) << '\n'; 79 | } 80 | -------------------------------------------------------------------------------- /sem-3/solutions/9C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | struct Trie { 8 | 9 | explicit Trie(vector const& alphabet) : root(new Node), alphabet(alphabet) {} 10 | 11 | void insert(string const& s) { 12 | if (count(s)) { 13 | return; 14 | } 15 | Node* v = root; 16 | for (char c: s) { 17 | if (!(v->count(c))) { 18 | v->set(c, new Node()); 19 | } 20 | v->count_term_subtree++; 21 | v = v->go(c); 22 | } 23 | v->count_term_subtree++; 24 | v->is_term = true; 25 | } 26 | 27 | bool count(string const& s) { 28 | Node *v = root; 29 | for (char c: s) { 30 | if (!(v->count(c))) { 31 | return false; 32 | } 33 | v = v->go(c); 34 | } 35 | return v->is_term; 36 | } 37 | 38 | string get_kth(int k) { 39 | Node* v = root; 40 | string s; 41 | while (k > 1 || !(v->is_term)) { 42 | k -= v->is_term; 43 | for (auto const& [c, node]: v->link) { 44 | if (node->count_term_subtree >= k) { 45 | s += c; 46 | v = node; 47 | break; 48 | } else { 49 | k -= node->count_term_subtree; 50 | } 51 | } 52 | } 53 | return s; 54 | } 55 | 56 | private: 57 | struct Node { 58 | bool is_term; 59 | int count_term_subtree; 60 | map link; 61 | 62 | Node() : is_term(false), count_term_subtree(0) {} 63 | 64 | bool count(char c) { 65 | return link.count(c); 66 | } 67 | 68 | void set(char c, Node* node) { 69 | link[c] = node; 70 | } 71 | 72 | Node* go(char c) { 73 | return link[c]; 74 | } 75 | }; 76 | 77 | Node* root; 78 | vector alphabet; 79 | }; 80 | 81 | int main() { 82 | ios_base::sync_with_stdio(false); 83 | cin.tie(nullptr); 84 | cout.tie(nullptr); 85 | 86 | vector alphabet; 87 | for (char c = 'a'; c <= 'z'; c++) { 88 | alphabet.push_back(c); 89 | } 90 | 91 | Trie trie(alphabet); 92 | 93 | int n; 94 | cin >> n; 95 | 96 | while (n--) { 97 | int command; 98 | cin >> command; 99 | if (command == 1) { 100 | string s; 101 | cin >> s; 102 | trie.insert(s); 103 | } else { 104 | int k; 105 | cin >> k; 106 | cout << trie.get_kth(k) << '\n'; 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /sem-4/problems/1A.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryag/ct-itmo-algorithms/2019c7d4928bb04fc3e0b7c6fdd4453dbeb35f9a/sem-4/problems/1A.pdf -------------------------------------------------------------------------------- /sem-4/problems/5A.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryag/ct-itmo-algorithms/2019c7d4928bb04fc3e0b7c6fdd4453dbeb35f9a/sem-4/problems/5A.pdf -------------------------------------------------------------------------------- /sem-4/problems/6C.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryag/ct-itmo-algorithms/2019c7d4928bb04fc3e0b7c6fdd4453dbeb35f9a/sem-4/problems/6C.pdf -------------------------------------------------------------------------------- /sem-4/problems/6D.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryag/ct-itmo-algorithms/2019c7d4928bb04fc3e0b7c6fdd4453dbeb35f9a/sem-4/problems/6D.pdf -------------------------------------------------------------------------------- /sem-4/problems/8D.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryag/ct-itmo-algorithms/2019c7d4928bb04fc3e0b7c6fdd4453dbeb35f9a/sem-4/problems/8D.pdf -------------------------------------------------------------------------------- /sem-4/problems/problems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryag/ct-itmo-algorithms/2019c7d4928bb04fc3e0b7c6fdd4453dbeb35f9a/sem-4/problems/problems.pdf -------------------------------------------------------------------------------- /sem-4/solutions/1A.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Aleksandr Kiriak on 08.04.2024. 3 | // 4 | #include 5 | 6 | using namespace std; 7 | 8 | struct Node { 9 | vector edges; 10 | }; 11 | 12 | struct Bipartite_Graph { 13 | Bipartite_Graph(int L_size, int R_size) { 14 | L.resize(L_size); 15 | R.resize(R_size); 16 | } 17 | 18 | void add_edge(int L_index, int R_index) { 19 | L[L_index].edges.push_back(R_index); 20 | R[R_index].edges.push_back(L_index); 21 | } 22 | 23 | pair> find_maximal_matching() { 24 | int match_size = 0; 25 | vector p(R.size(), -1); 26 | mark.resize(L.size()); 27 | for (int i = 0; i < L.size(); i++) { 28 | fill(mark.begin(), mark.end(), false); 29 | if (dfs(i, p)) { 30 | match_size++; 31 | } 32 | } 33 | return {match_size, p}; 34 | } 35 | 36 | private: 37 | vector L, R; 38 | vector mark; 39 | 40 | bool dfs(int v, vector &p) { 41 | if (mark[v]) return false; 42 | mark[v] = true; 43 | for (int to: L[v].edges) { 44 | if (p[to] == -1) { 45 | p[to] = v; 46 | return true; 47 | } 48 | } 49 | for (int to: L[v].edges) { 50 | if (dfs(p[to], p)) { 51 | p[to] = v; 52 | return true; 53 | } 54 | } 55 | return false; 56 | } 57 | }; 58 | 59 | int main() { 60 | std::ios_base::sync_with_stdio(false); 61 | std::cin.tie(nullptr); 62 | std::cout.tie(nullptr); 63 | 64 | int n, m; 65 | cin >> n >> m; 66 | 67 | Bipartite_Graph graph(n, m); 68 | 69 | for (int i = 0; i < n; i++) { 70 | while (true) { 71 | int edge; 72 | cin >> edge; 73 | if (edge == 0) { 74 | break; 75 | } 76 | edge--; 77 | graph.add_edge(i, edge); 78 | } 79 | } 80 | 81 | auto result = graph.find_maximal_matching(); 82 | cout << result.first << endl; 83 | for (int i = 0; i < m; i++) { 84 | if (result.second[i] != -1) { 85 | cout << result.second[i] + 1 << " " << i + 1 << endl; 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /sem-4/solutions/1B.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Aleksandr Kiriak on 08.04.2024. 3 | // 4 | #include 5 | 6 | using namespace std; 7 | 8 | struct Node { 9 | vector edges; 10 | }; 11 | 12 | struct Graph { 13 | explicit Graph(int size) { 14 | nodes.resize(size); 15 | deg.resize(size); 16 | } 17 | 18 | void add_edge(int from, int to) { 19 | nodes[from].edges.push_back(to); 20 | deg[to]++; 21 | } 22 | 23 | int count_paths() { 24 | int leaves = 0; 25 | for (int i = 0; i < nodes.size(); i++) { 26 | if (deg[i] == 0) { 27 | leaves++; 28 | } 29 | } 30 | return leaves; 31 | } 32 | 33 | private: 34 | vector nodes; 35 | vector deg; 36 | }; 37 | 38 | struct Bipartite_Graph { 39 | Bipartite_Graph(int L_size, int R_size) { 40 | L.resize(L_size); 41 | R.resize(R_size); 42 | } 43 | 44 | void add_edge(int L_index, int R_index) { 45 | L[L_index].edges.push_back(R_index); 46 | } 47 | 48 | vector find_maximal_matching() { 49 | vector p(R.size(), -1); 50 | mark.resize(L.size()); 51 | for (int i = 0; i < L.size(); i++) { 52 | fill(mark.begin(), mark.end(), false); 53 | dfs(i, p); 54 | } 55 | return p; 56 | } 57 | 58 | private: 59 | vector L, R; 60 | vector mark; 61 | 62 | bool dfs(int v, vector &p) { 63 | if (mark[v]) return false; 64 | mark[v] = true; 65 | for (int to: L[v].edges) { 66 | if (p[to] == -1) { 67 | p[to] = v; 68 | return true; 69 | } 70 | } 71 | for (int to: L[v].edges) { 72 | if (dfs(p[to], p)) { 73 | p[to] = v; 74 | return true; 75 | } 76 | } 77 | return false; 78 | } 79 | }; 80 | 81 | int main() { 82 | std::ios_base::sync_with_stdio(false); 83 | std::cin.tie(nullptr); 84 | std::cout.tie(nullptr); 85 | 86 | int n, m; 87 | cin >> n >> m; 88 | 89 | Bipartite_Graph bipartite_graph(n, n); 90 | 91 | for (int i = 0; i < m; i++) { 92 | int v, u; 93 | cin >> v >> u; 94 | v--; u--; 95 | bipartite_graph.add_edge(v, u); 96 | } 97 | 98 | vector matching = bipartite_graph.find_maximal_matching(); 99 | Graph init_graph(n); 100 | for (int i = 0; i < n; i++) { 101 | if (matching[i] != -1) { 102 | init_graph.add_edge(matching[i], i); 103 | } 104 | } 105 | cout << init_graph.count_paths() << endl; 106 | } 107 | -------------------------------------------------------------------------------- /sem-4/solutions/1H.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Aleksandr Kiriak on 09.04.2024. 3 | // 4 | #include 5 | 6 | using namespace std; 7 | 8 | struct Edge { 9 | int index, v, u; 10 | 11 | Edge(int index, int v, int u) { 12 | this->index = index; 13 | this->v = v; 14 | this->u = u; 15 | } 16 | }; 17 | 18 | int main() { 19 | std::ios_base::sync_with_stdio(false); 20 | std::cin.tie(nullptr); 21 | std::cout.tie(nullptr); 22 | 23 | int T; 24 | cin >> T; 25 | 26 | while (T--) { 27 | int n, m; 28 | cin >> n >> m; 29 | 30 | vector edges; 31 | for (int i = 0; i < m; i++) { 32 | int v, u; 33 | cin >> v >> u; 34 | edges.emplace_back(i, v - 1, u - 1); 35 | } 36 | 37 | unordered_set matching_nodes; 38 | vector matching_edges_id; 39 | for (const auto& edge : edges) { 40 | if (!matching_nodes.count(edge.v) && !matching_nodes.count(edge.u)) { 41 | matching_nodes.insert(edge.v); 42 | matching_nodes.insert(edge.u); 43 | matching_edges_id.push_back(edge.index); 44 | if (matching_edges_id.size() == n) { 45 | break; 46 | } 47 | } 48 | } 49 | 50 | if (matching_edges_id.size() == n) { 51 | cout << "Matching" << endl; 52 | for (int edge_id : matching_edges_id) { 53 | cout << edge_id + 1 << " "; 54 | } 55 | } else { 56 | cout << "IndSet" << endl; 57 | int size = 0; 58 | for (int i = 0; i < 3 * n; i++) { 59 | if (!matching_nodes.count(i)) { 60 | cout << i + 1 << " "; 61 | size++; 62 | if (size == n) { 63 | break; 64 | } 65 | } 66 | } 67 | } 68 | cout << endl; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /sem-4/solutions/1I.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Aleksandr Kiriak on 09.04.2024. 3 | // 4 | #include 5 | 6 | using namespace std; 7 | 8 | struct Node { 9 | vector edges; 10 | }; 11 | 12 | struct Graph { 13 | vector nodes; 14 | vector mark; 15 | 16 | explicit Graph(int size) { 17 | nodes.resize(size); 18 | mark.resize(size); 19 | fill(mark.begin(), mark.end(), false); 20 | } 21 | 22 | void add_edge(int from, int to) { 23 | nodes[from].edges.push_back(to); 24 | } 25 | 26 | void dfs(int v) { 27 | if (mark[v]) return; 28 | mark[v] = true; 29 | for (int to : nodes[v].edges) { 30 | if (!mark[to]) { 31 | dfs(to); 32 | } 33 | } 34 | } 35 | }; 36 | 37 | template 38 | void print_vector(vector v) { 39 | for (auto const& elem : v) { 40 | cout << to_string(elem) << " "; 41 | } 42 | cout << endl; 43 | } 44 | 45 | int main() { 46 | ios_base::sync_with_stdio(false); 47 | cin.tie(nullptr); 48 | cout.tie(nullptr); 49 | 50 | int m, n; 51 | cin >> m >> n; 52 | 53 | vector> edges(m); 54 | for (int L = 0; L < m; L++) { 55 | int K; 56 | cin >> K; 57 | for (int R = 0; R < K; R++) { 58 | int node; 59 | cin >> node; 60 | edges[L].push_back(node - 1); 61 | } 62 | } 63 | 64 | vector match_node(m); 65 | int match_size = 0; 66 | for (int L = 0; L < m; L++) { 67 | cin >> match_node[L]; 68 | match_node[L]--; 69 | if (match_node[L] != -1) { 70 | match_size++; 71 | } 72 | } 73 | 74 | Graph graph(m + n); 75 | for (int L = 0; L < m; L++) { 76 | for (int R : edges[L]) { 77 | if (match_node[L] == R) { 78 | graph.add_edge(R + m, L); 79 | } else { 80 | graph.add_edge(L, R + m); 81 | } 82 | } 83 | } 84 | 85 | for (int L = 0; L < m; L++) { 86 | if (match_node[L] == -1) { 87 | graph.dfs(L); 88 | } 89 | } 90 | 91 | vector L_result; 92 | for (int L = 0; L < m; L++) { 93 | if (!graph.mark[L]) { 94 | L_result.push_back(L + 1); 95 | } 96 | } 97 | 98 | vector R_result; 99 | for (int R = m; R < n + m; R++) { 100 | if (graph.mark[R]) { 101 | R_result.push_back(R + 1 - m); 102 | } 103 | } 104 | 105 | cout << match_size << endl; 106 | cout << L_result.size() << " "; 107 | print_vector(L_result); 108 | cout << R_result.size() << " "; 109 | print_vector(R_result); 110 | } 111 | -------------------------------------------------------------------------------- /sem-4/solutions/4B.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Aleksandr Kiriak on 17.05.2024. 3 | // 4 | #include 5 | 6 | using namespace std; 7 | 8 | const int INF = INT32_MAX; 9 | 10 | int n; 11 | vector> C; 12 | 13 | pair> hungarian() { 14 | vector u(n + 1), v(n + 1), match(n + 1), path(n + 1); 15 | 16 | for (int i = 1; i <= n; i++) { 17 | vector min_v(n + 1, INF); 18 | vector mark(n + 1, false); 19 | match[0] = i; 20 | int cur_col = 0; 21 | 22 | do { 23 | int cur_row = match[cur_col], rem = INF, min_col = 0; 24 | mark[cur_col] = true; 25 | for (int j = 1; j <= n; j++) { 26 | if (mark[j]) { 27 | continue; 28 | } 29 | int cur = C[cur_row][j] - u[cur_row] - v[j]; 30 | if (cur < min_v[j]) { 31 | path[j] = cur_col; 32 | min_v[j] = cur; 33 | } 34 | if (min_v[j] < rem) { 35 | min_col = j; 36 | rem = min_v[j]; 37 | } 38 | } 39 | for (int j = 0; j <= n; j++) { 40 | if (mark[j]) { 41 | v[j] -= rem; 42 | u[match[j]] += rem; 43 | } else { 44 | min_v[j] -= rem; 45 | } 46 | } 47 | cur_col = min_col; 48 | } while (match[cur_col] != 0); 49 | 50 | do { 51 | int min_col = path[cur_col]; 52 | match[cur_col] = match[min_col], cur_col = min_col; 53 | } while (cur_col != 0); 54 | } 55 | 56 | vector answer(n + 1); 57 | for (int j = 1; j <= n; j++) { 58 | answer[match[j]] = j; 59 | } 60 | 61 | return {-v[0], answer}; 62 | } 63 | 64 | int main() { 65 | ios_base::sync_with_stdio(false); 66 | cin.tie(nullptr); 67 | cout.tie(nullptr); 68 | 69 | cin >> n; 70 | 71 | C.resize(n + 1, vector(n + 1)); 72 | for (int i = 0; i < n; i++) { 73 | for (int j = 0; j < n; j++) { 74 | cin >> C[i + 1][j + 1]; 75 | } 76 | } 77 | 78 | pair> answer = hungarian(); 79 | cout << answer.first << endl; 80 | for (int i = 1; i <= n; i++) { 81 | cout << i << ' ' << answer.second[i] << endl; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /sem-4/solutions/4D.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Aleksandr Kiriak on 17.05.2024. 3 | // 4 | #include 5 | 6 | using namespace std; 7 | 8 | const int INF = INT32_MAX; 9 | 10 | string encrypted_note, correct_answers; 11 | vector> weight; 12 | vector match_L, match_R; 13 | vector part_L, part_R; 14 | vector mark_L, mark_R; 15 | int dist, K; 16 | 17 | bool dfs(int v) { 18 | mark_L[v] = true; 19 | for (int y = 0; y < K; y++) { 20 | if (mark_R[y]) { 21 | continue; 22 | } 23 | if (part_L[v] + part_R[y] != weight[v][y]) { 24 | dist = min(dist, part_L[v] + part_R[y] - weight[v][y]); 25 | continue; 26 | } 27 | mark_R[y] = true; 28 | if (match_R[y] == -1 || dfs(match_R[y])) { 29 | match_L[v] = y; 30 | match_R[y] = v; 31 | return true; 32 | } 33 | } 34 | return false; 35 | } 36 | 37 | int main() { 38 | ios_base::sync_with_stdio(false); 39 | cin.tie(nullptr); 40 | cout.tie(nullptr); 41 | 42 | int N; 43 | cin >> N >> K; 44 | cin >> encrypted_note >> correct_answers; 45 | 46 | weight.resize(K, vector(K)); 47 | match_L.resize(K, -1); 48 | match_R.resize(K, -1); 49 | part_L.resize(K); 50 | part_R.resize(K); 51 | mark_L.resize(K); 52 | mark_R.resize(K); 53 | 54 | auto calc = [](char c) { 55 | return c >= 'a' ? c - 'a' : c - 'A' + 26; 56 | }; 57 | for (int i = 0; i < N; i++) { 58 | weight[calc(encrypted_note[i])][calc(correct_answers[i])]++; 59 | } 60 | 61 | for (int v = 0; v < K; v++) { 62 | for (int u = 0; u < K; u++) { 63 | part_L[v] = max(part_L[v], weight[v][u]); 64 | } 65 | } 66 | 67 | int v = 0; 68 | while (v < K) { 69 | fill(mark_L.begin(), mark_L.end(), false); 70 | fill(mark_R.begin(), mark_R.end(), false); 71 | dist = INF; 72 | if (dfs(v)) { 73 | v++; 74 | continue; 75 | } 76 | for (int u = 0; u < K; u++) { 77 | if (mark_L[u]) { 78 | part_L[u] -= dist; 79 | } 80 | if (mark_R[u]) { 81 | part_R[u] += dist; 82 | } 83 | } 84 | } 85 | 86 | int answer = 0; 87 | for (int u = 0; u < K; u++) { 88 | answer += weight[u][match_L[u]]; 89 | } 90 | 91 | cout << answer << endl; 92 | for (int u = 0; u < K; u++) { 93 | int x = match_L[u]; 94 | cout << (x < 26 ? char(x + 'a') : char(x + 'A' - 26)); 95 | } 96 | cout << endl; 97 | } 98 | -------------------------------------------------------------------------------- /sem-4/solutions/5B.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Aleksandr Kiriak on 18.05.2024. 3 | // 4 | #include 5 | 6 | using namespace std; 7 | 8 | typedef long long ll; 9 | 10 | struct Point { 11 | ll x, y; 12 | }; 13 | 14 | struct Vector { 15 | ll x, y; 16 | 17 | Vector(Point A, Point B) { 18 | this->x = B.x - A.x; 19 | this->y = B.y - A.y; 20 | } 21 | }; 22 | 23 | ll sign(ll x) { 24 | if (x == 0LL) { 25 | return 0LL; 26 | } 27 | return x > 0LL ? 1LL : -1LL; 28 | } 29 | 30 | ll skew_product(const Vector& A, const Vector& B) { 31 | return A.x * B.y - A.y * B.x; 32 | } 33 | 34 | // принадлежит ли точка P лучу AB 35 | bool is_point_on_ray(const Point& A, const Point& B, const Point& P) { 36 | bool on_line = (P.x - A.x) * (B.y - A.y) == (B.x - A.x) * (P.y - A.y); 37 | if (!on_line) { 38 | return false; 39 | } 40 | return (P.x - A.x) * (B.x - A.x) >= 0 && (P.y - A.y) * (B.y - A.y) >= 0; 41 | } 42 | 43 | // принадлежит ли точка P углу AOB (включая его стороны: лучи OA и OB) 44 | bool is_point_in_angle(const Point& A, const Point& O, const Point& B, const Point& P) { 45 | if (is_point_on_ray(O, A, P) || is_point_on_ray(O, B, P)) { 46 | return true; 47 | } 48 | Vector OA = {O, A}; 49 | Vector OP = {O, P}; 50 | Vector OB = {O, B}; 51 | return sign(skew_product(OA, OP)) * sign(skew_product(OA, OB)) > 0 && 52 | sign(skew_product(OB, OP)) * sign(skew_product(OB, OA)) > 0; 53 | } 54 | 55 | int main() { 56 | ios_base::sync_with_stdio(false); 57 | cin.tie(nullptr); 58 | cout.tie(nullptr); 59 | 60 | ll x, y; 61 | cin >> x >> y; 62 | Point A{x, y}; 63 | cin >> x >> y; 64 | Point O{x, y}; 65 | cin >> x >> y; 66 | Point B{x, y}; 67 | cin >> x >> y; 68 | Point P{x, y}; 69 | 70 | cout << (is_point_in_angle(A, O, B, P) ? "YES" : "NO") << endl; 71 | } 72 | -------------------------------------------------------------------------------- /sem-4/solutions/5D.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Aleksandr Kiriak on 18.05.2024. 3 | // 4 | #include 5 | 6 | using namespace std; 7 | 8 | const long double EPS = 0.000'001; 9 | 10 | int main() { 11 | ios_base::sync_with_stdio(false); 12 | cin.tie(nullptr); 13 | cout.tie(nullptr); 14 | 15 | long double x, y, r, a, b, c; 16 | cin >> x >> y >> r >> a >> b >> c; 17 | 18 | long double x_a, y_a; 19 | if (abs(a) < EPS) { 20 | x_a = 0.0; 21 | y_a = -c / b; 22 | } else { 23 | x_a = -c / a; 24 | y_a = 0.0; 25 | } 26 | x_a -= x; 27 | y_a -= y; 28 | c = -(a * x_a + b * y_a); 29 | 30 | long double x0 = -a * c / (a * a + b * b); 31 | long double y0 = -b * c / (a * a + b * b); 32 | cout << fixed << setprecision(6); 33 | if (c * c > r * r * (a * a + b * b) + EPS) { 34 | cout << 0 << endl; 35 | } else if (abs(c * c - r * r * (a * a + b * b)) < EPS) { 36 | cout << 1 << endl; 37 | cout << x0 + x << ' ' << y0 + y << endl; 38 | } else { 39 | long double temp = sqrt((r * r - c * c / (a * a + b * b)) / (a * a + b * b)); 40 | cout << 2 << endl; 41 | cout << x0 + b * temp + x << ' ' << y0 - a * temp + y << endl; 42 | cout << x0 - b * temp + x << ' ' << y0 + a * temp + y << endl; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /sem-4/solutions/5E.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Aleksandr Kiriak on 19.05.2024. 3 | // 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | typedef long long ll; 11 | 12 | double dist_point_to_point(double x1, double y1, double x2, double y2) { 13 | return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); 14 | } 15 | 16 | void solve() { 17 | ll x1, y1, r1, x2, y2, r2; 18 | cin >> x1 >> y1 >> r1 >> x2 >> y2 >> r2; 19 | 20 | if (x1 == x2 && y1 == y2 && r1 == r2) { 21 | cout << 3 << endl; 22 | return; 23 | } 24 | 25 | ll d = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2); 26 | ll sum_r = (r1 + r2) * (r1 + r2); 27 | ll sub_r = (r1 - r2) * (r1 - r2); 28 | 29 | if (d < sub_r || d > sum_r) { 30 | cout << 0 << endl; 31 | return; 32 | } 33 | 34 | if (d == sum_r) { 35 | cout << 1 << endl; 36 | cout << x1 + (double) r1 * (x2 - x1) / (r1 + r2) << ' ' << y1 + (double) r1 * (y2 - y1) / (r1 + r2) << endl; 37 | return; 38 | } 39 | if (d == sub_r) { 40 | cout << 1 << endl; 41 | cout << x1 + (double) r1 * (x2 - x1) / (r1 - r2) << ' ' << y1 + (double) r1 * (y2 - y1) / (r1 - r2) << endl; 42 | return; 43 | } 44 | 45 | double d_sqrt = sqrt(d); 46 | double a = (double) (r1 * r1 - r2 * r2 + d) / (2 * d_sqrt); 47 | double H_x = x1 + a * (x2 - x1) / d_sqrt; 48 | double H_y = y1 + a * (y2 - y1) / d_sqrt; 49 | double h = sqrt(r1 * r1 - a * a); 50 | double P1_x = H_x + h * (y2 - y1) / d_sqrt; 51 | double P1_y = H_y - h * (x2 - x1) / d_sqrt; 52 | double P2_x = H_x - h * (y2 - y1) / d_sqrt; 53 | double P2_y = H_y + h * (x2 - x1) / d_sqrt; 54 | 55 | cout << 2 << endl; 56 | cout << H_x << ' ' << H_y << endl; 57 | cout << dist_point_to_point(x1, y1, H_x, H_y) << ' ' << dist_point_to_point(P1_x, P1_y, H_x, H_y) << endl; 58 | cout << P1_x << ' ' << P1_y << endl; 59 | cout << P2_x << ' ' << P2_y << endl; 60 | } 61 | 62 | int main() { 63 | ios_base::sync_with_stdio(false); 64 | cin.tie(nullptr); 65 | cout.tie(nullptr); 66 | 67 | int t; 68 | cin >> t; 69 | 70 | cout << fixed << setprecision(10); 71 | while (t--) { 72 | solve(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /sem-4/solutions/5F.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Aleksandr Kiriak on 19.05.2024. 3 | // 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | typedef long long ll; 12 | 13 | double distance(double x1, double y1, double x2, double y2) { 14 | return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); 15 | } 16 | 17 | vector circles_inter(double x0, double y0, double x1, double y1, double r0, double r1) { 18 | double d = distance(x0, y0, x1, y1); 19 | double a = (r0 * r0 - r1 * r1 + d * d) / (2 * d); 20 | double h = sqrt(r0 * r0 - a * a); 21 | double x2 = x0 + a * (x1 - x0) / d; 22 | double y2 = y0 + a * (y1 - y0) / d; 23 | double x3 = x2 + h * (y1 - y0) / d; 24 | double y3 = y2 - h * (x1 - x0) / d; 25 | double x4 = x2 - h * (y1 - y0) / d; 26 | double y4 = y2 + h * (x1 - x0) / d; 27 | return {x3, y3, x4, y4}; 28 | } 29 | 30 | int main() { 31 | ios_base::sync_with_stdio(false); 32 | cin.tie(nullptr); 33 | cout.tie(nullptr); 34 | 35 | ll x0, y0, r, x1, y1; 36 | cin >> x0 >> y0 >> r >> x1 >> y1; 37 | 38 | ll d_sqr = (x0 - x1) * (x0 - x1) + (y0 - y1) * (y0 - y1); 39 | if (d_sqr < r * r) { 40 | cout << 0 << endl; 41 | return 0; 42 | } 43 | if (d_sqr == r * r) { 44 | cout << 1 << endl; 45 | cout << x1 << ' ' << y1 << endl; 46 | return 0; 47 | } 48 | 49 | double d = sqrt(d_sqr); 50 | double mid_x = (double) (x0 + x1) / 2; 51 | double mid_y = (double) (y0 + y1) / 2; 52 | double r2 = d / 2; 53 | auto intersection = circles_inter(x0, y0, mid_x, mid_y, r, r2); 54 | double x21 = intersection[0], y21 = intersection[1], x22 = intersection[2], y22 = intersection[3]; 55 | double x3 = (x21 + x22) / 2; 56 | double y3 = (y21 + y22) / 2; 57 | double d13 = distance(x1, y1, x3, y3); 58 | double d23 = distance(x21, y21, x3, y3); 59 | 60 | cout << 2 << endl; 61 | cout << fixed << setprecision(10); 62 | cout << x3 << ' ' << y3 << endl; 63 | cout << d13 << ' ' << d23 << endl; 64 | cout << x21 << ' ' << y21 << endl; 65 | cout << x22 << ' ' << y22 << endl; 66 | } 67 | -------------------------------------------------------------------------------- /sem-4/solutions/5G.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Aleksandr Kiriak on 18.05.2024. 3 | // 4 | #include 5 | 6 | using namespace std; 7 | 8 | typedef long long ll; 9 | 10 | struct Point { 11 | ll x, y; 12 | }; 13 | 14 | struct Vector { 15 | Point A{}, B{}; 16 | ll x, y; 17 | 18 | Vector(Point A, Point B) { 19 | this->A = A; 20 | this->B = B; 21 | this->x = B.x - A.x; 22 | this->y = B.y - A.y; 23 | } 24 | }; 25 | 26 | ll scalar_product(const Vector& A, const Vector& B) { 27 | return A.x * B.x + A.y * B.y; 28 | } 29 | 30 | bool is_point_on_line(const Point& A, const Point& B, const Point& P) { 31 | return ((P.x - A.x) * (B.y - A.y)) == ((P.y - A.y) * (B.x - A.x)); 32 | } 33 | 34 | ll angle_between(const Vector& a, const Vector& b) { 35 | ll scalar = scalar_product(a, b); 36 | if (scalar == 0) { 37 | return 0; 38 | } 39 | if (is_point_on_line(a.A, a.B, b.A) && is_point_on_line(a.A, a.B, b.B)) { 40 | return scalar > 0 ? 2 : -2; 41 | } 42 | return scalar > 0 ? 1 : -1; 43 | } 44 | 45 | int main() { 46 | ios_base::sync_with_stdio(false); 47 | cin.tie(nullptr); 48 | cout.tie(nullptr); 49 | 50 | int n; 51 | cin >> n; 52 | 53 | Point prev_point{0, 0}; 54 | Vector prev_vector(prev_point, {1, 0}); 55 | for (int i = 0; i < n; i++) { 56 | Point cur_point{}; 57 | cin >> cur_point.x >> cur_point.y; 58 | 59 | Vector cur_vector(prev_point, cur_point); 60 | Vector prev_vector_rot{prev_vector.A, {prev_vector.A.x - prev_vector.y, prev_vector.A.y + prev_vector.x}}; 61 | 62 | ll angle = angle_between(prev_vector, cur_vector); 63 | ll angle_rot = angle_between(prev_vector_rot, cur_vector); 64 | 65 | prev_vector = cur_vector; 66 | prev_point = cur_point; 67 | 68 | if (angle == 2) { 69 | cout << "F "; 70 | continue; 71 | } 72 | if (angle == -2) { 73 | cout << "B "; 74 | continue; 75 | } 76 | if (angle_rot >= 1) { 77 | if (angle == 0) { 78 | cout << "L "; 79 | } else if (angle == 1) { 80 | cout << "LF "; 81 | } else { 82 | cout << "LB "; 83 | } 84 | } else { 85 | if (angle == 0) { 86 | cout << "R "; 87 | } else if (angle == 1) { 88 | cout << "RF "; 89 | } else { 90 | cout << "RB "; 91 | } 92 | } 93 | } 94 | cout << endl; 95 | } 96 | -------------------------------------------------------------------------------- /sem-4/solutions/5H.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Aleksandr Kiriak on 19.05.2024. 3 | // 4 | #pragma GCC optimize("Ofast") 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | typedef long long ll; 12 | 13 | const int MAX_N = 7000; 14 | 15 | ll sqr_dist_point_to_point(int x1, int y1, int x2, int y2) { 16 | return (ll) (x1 - x2) * (x1 - x2) + (ll) (y1 - y2) * (y1 - y2); 17 | } 18 | 19 | int main() { 20 | ios_base::sync_with_stdio(false); 21 | cin.tie(nullptr); 22 | cout.tie(nullptr); 23 | 24 | int n; 25 | cin >> n; 26 | 27 | int x[MAX_N], y[MAX_N]; 28 | for (int i = 0; i < n; i++) { 29 | cin >> x[i] >> y[i]; 30 | } 31 | 32 | ll result = 0; 33 | for (int i = 0; i < n - 1; i++) { 34 | int xi = x[i]; 35 | int yi = y[i]; 36 | for (int j = i + 1; j < n; j++) { 37 | result = max(result, sqr_dist_point_to_point(xi, yi, x[j],y[j])); 38 | } 39 | } 40 | 41 | cout << fixed << setprecision(20); 42 | cout << sqrt(result) << endl; 43 | } 44 | -------------------------------------------------------------------------------- /sem-4/solutions/5I.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Aleksandr Kiriak on 20.05.2024. 3 | // 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | struct Point { 11 | int x, y; 12 | 13 | bool operator<(const Point& other) const { 14 | return y == other.y ? x < other.x : y < other.y; 15 | } 16 | }; 17 | 18 | struct Vector { 19 | int x, y; 20 | 21 | Vector(const Point& A, const Point& B) { 22 | this->x = B.x - A.x; 23 | this->y = B.y - A.y; 24 | } 25 | }; 26 | 27 | int skew_product(const Vector& A, const Vector& B) { 28 | return A.x * B.y - A.y * B.x; 29 | } 30 | 31 | int dist_sqr(const Point& A, const Point& B) { 32 | int dx = A.x - B.x; 33 | int dy = A.y - B.y; 34 | return dx * dx + dy * dy; 35 | } 36 | 37 | int main() { 38 | ios_base::sync_with_stdio(false); 39 | cin.tie(nullptr); 40 | cout.tie(nullptr); 41 | 42 | int n; 43 | cin >> n; 44 | 45 | vector points(n); 46 | for (int i = 0; i < n; i++) { 47 | cin >> points[i].x >> points[i].y; 48 | } 49 | 50 | int cur_time = 0; 51 | vector time(n); 52 | while (true) { 53 | int start = -1; 54 | for (int i = 0; i < n; i++) { 55 | if (time[i] == 0 && (start == -1 || points[i] < points[start])) { 56 | start = i; 57 | } 58 | } 59 | if (start == -1) { 60 | break; 61 | } 62 | int cur = start; 63 | time[start] = -1; 64 | while (true) { 65 | int next = start; 66 | for (int i = 0; i < n; i++) { 67 | if (time[i] != 0) { 68 | continue; 69 | } 70 | Vector cur_next(points[cur], points[next]); 71 | Vector cur_i(points[cur], points[i]); 72 | int skew = skew_product(cur_next, cur_i); 73 | if (skew > 0) { 74 | continue; 75 | } 76 | if (skew < 0 || next == start || dist_sqr(points[cur], points[next]) > dist_sqr(points[cur], points[i])) { 77 | next = i; 78 | continue; 79 | } 80 | } 81 | if (next == start) { 82 | break; 83 | } 84 | time[next] = -1; 85 | cur = next; 86 | } 87 | 88 | cur_time++; 89 | for (int i = 0; i < n; i++) { 90 | if (time[i] == -1) { 91 | time[i] = cur_time; 92 | } 93 | } 94 | } 95 | 96 | for (int i = 0; i < n; i++) { 97 | cout << time[i] << endl; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /sem-4/solutions/5K.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Aleksandr Kiriak on 20.05.2024. 3 | // 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | typedef long long ll; 11 | 12 | struct Point { 13 | ll x, y; 14 | 15 | bool operator<(const Point& other) const { 16 | return y == other.y ? x < other.x : y < other.y; 17 | } 18 | 19 | bool operator==(const Point& other) const { 20 | return x == other.x && y == other.y; 21 | } 22 | 23 | bool operator!=(const Point& other) const { 24 | return !(*this == other); 25 | } 26 | }; 27 | 28 | struct Vector { 29 | ll x, y; 30 | 31 | Vector(const Point& A, const Point& B) { 32 | this->x = B.x - A.x; 33 | this->y = B.y - A.y; 34 | } 35 | }; 36 | 37 | ll skew_product(const Vector& A, const Vector& B) { 38 | return A.x * B.y - A.y * B.x; 39 | } 40 | 41 | ll dist_sqr(const Point& A, const Point& B) { 42 | ll dx = A.x - B.x; 43 | ll dy = A.y - B.y; 44 | return dx * dx + dy * dy; 45 | } 46 | 47 | bool is_point_on_line(const Point& A, const Point& B, const Point& P) { 48 | return ((P.x - A.x) * (B.y - A.y)) == ((P.y - A.y) * (B.x - A.x)); 49 | } 50 | 51 | int main() { 52 | ios_base::sync_with_stdio(false); 53 | cin.tie(nullptr); 54 | cout.tie(nullptr); 55 | 56 | int n; 57 | cin >> n; 58 | 59 | vector v(n); 60 | Point start{}; 61 | for (int i = 0; i < n; i++) { 62 | cin >> v[i].x >> v[i].y; 63 | if (i == 0 || v[i] < start) { 64 | start = v[i]; 65 | } 66 | } 67 | 68 | sort(v.begin(), v.end(), [&](const auto& a, const auto& b) { 69 | ll skew = skew_product({start, a}, {start, b}); 70 | if (skew == 0) { 71 | return dist_sqr(start, a) > dist_sqr(start, b); 72 | } 73 | return skew > 0; 74 | }); 75 | 76 | vector points; 77 | points.push_back(start); 78 | for (auto const& p : v) { 79 | if (p != start && points.back() != p && (points.size() == 1 || !is_point_on_line(start, points.back(), p))) { 80 | points.push_back(p); 81 | } 82 | } 83 | 84 | vector path; 85 | for (auto point : points) { 86 | while (path.size() >= 2 && skew_product({path[path.size() - 2], path.back()}, {path.back(), point}) <= 0) { 87 | path.pop_back(); 88 | } 89 | path.push_back(point); 90 | } 91 | 92 | int size = (int) path.size(); 93 | ll s = 0; 94 | 95 | cout << size << endl; 96 | for (int i = 0; i < size; i++) { 97 | cout << path[i].x << ' ' << path[i].y << endl; 98 | int next = (i + 1) % size; 99 | s += (path[next].y + path[i].y) * (path[next].x - path[i].x); 100 | } 101 | s = abs(s); 102 | cout << s / 2 << (s % 2 ? ".5" : "") << endl; 103 | } 104 | -------------------------------------------------------------------------------- /sem-4/solutions/6F.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Aleksandr Kiriak on 20.05.2024. 3 | // 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | typedef long long ll; 10 | 11 | struct Point { 12 | ll x, y; 13 | }; 14 | 15 | struct Vector { 16 | ll x, y; 17 | 18 | Vector(Point A, Point B) { 19 | this->x = B.x - A.x; 20 | this->y = B.y - A.y; 21 | } 22 | }; 23 | 24 | ll sign(ll x) { 25 | if (x == 0) { 26 | return 0; 27 | } 28 | return x > 0 ? 1 : -1; 29 | } 30 | 31 | ll skew_product(const Vector& A, const Vector& B) { 32 | return A.x * B.y - A.y * B.x; 33 | } 34 | 35 | // Находится ли точка P внутри (нестрого) многоугольника (не обязательно выпуклого) polygon. 36 | bool is_point_in_polygon(const vector& polygon, const Point& P) { 37 | int n = (int) polygon.size(); 38 | int count_intersections = 0; 39 | for (int i = 0; i < n; i++) { 40 | Point cur = polygon[i]; 41 | Point next = polygon[(i + 1) % n]; 42 | if (cur.y >= next.y) { 43 | swap(cur, next); 44 | } 45 | if (next.y < P.y || cur.y > P.y) { 46 | continue; 47 | } 48 | ll skew = sign(skew_product({cur, next}, {cur, P})); 49 | if (skew == 0) { 50 | return true; 51 | } 52 | if (skew > 0) { 53 | count_intersections++; 54 | } 55 | } 56 | return count_intersections % 2; 57 | } 58 | 59 | int main() { 60 | ios_base::sync_with_stdio(false); 61 | cin.tie(nullptr); 62 | cout.tie(nullptr); 63 | 64 | int n; 65 | cin >> n; 66 | 67 | Point P{}; 68 | cin >> P.x >> P.y; 69 | 70 | vector polygon(n); 71 | for (int i = 0; i < n; i++) { 72 | cin >> polygon[i].x >> polygon[i].y; 73 | } 74 | 75 | cout << (is_point_in_polygon(polygon, P) ? "YES" : "NO") << endl; 76 | } 77 | -------------------------------------------------------------------------------- /sem-4/solutions/7A.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Aleksandr Kiriak on 29.05.2024. 3 | // 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | typedef long long ll; 10 | 11 | vector gcd(ll a, ll b) { 12 | if (b == 0) { 13 | return {a, 1, 0}; 14 | } 15 | auto ans = gcd(b, a % b); 16 | return {ans[0], ans[2], ans[1] - (a / b) * ans[2]}; 17 | } 18 | 19 | int main() { 20 | ios_base::sync_with_stdio(false); 21 | cin.tie(nullptr); 22 | cout.tie(nullptr); 23 | 24 | ll a, b, c; 25 | cin >> a >> b >> c; 26 | 27 | auto res = gcd(a, b); 28 | ll d = res[0], x = res[1], y = res[2]; 29 | 30 | if (c % d != 0) { 31 | cout << "Impossible" << endl; 32 | return 0; 33 | } 34 | 35 | ll k1 = c / d * x; 36 | ll k2 = b / d; 37 | if (k1 > 0) { 38 | ll tmp = -(k1 / k2); 39 | cout << k1 + k2 * tmp << " " << c / d * y - a / d * tmp << endl; 40 | } else if (k1 < 0) { 41 | ll tmp = -((k1 - k2 + 1) / k2); 42 | cout << k1 + k2 * tmp << " " << c / d * y - a / d * tmp << endl; 43 | } else { 44 | cout << 0 << " " << c / d * y << endl; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /sem-4/solutions/7B.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Aleksandr Kiriak on 03.06.2024. 3 | // 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | typedef long long ll; 10 | 11 | vector gcd(ll a, ll b) { 12 | if (b == 0) { 13 | return {a, 1, 0}; 14 | } 15 | auto ans = gcd(b, a % b); 16 | return {ans[0], ans[2], ans[1] - (a / b) * ans[2]}; 17 | } 18 | 19 | pair> solve_diophantine_equation(ll a, ll b, ll c) { 20 | auto res = gcd(a, b); 21 | ll d = res[0], x = res[1], y = res[2]; 22 | 23 | if (c % d != 0) { 24 | return {false, {}}; 25 | } 26 | 27 | ll k1 = c / d * x; 28 | ll k2 = b / d; 29 | pair ans; 30 | if (k1 > 0) { 31 | ll tmp = -(k1 / k2); 32 | ans = {k1 + k2 * tmp, c / d * y - a / d * tmp}; 33 | } else if (k1 < 0) { 34 | ll tmp = -((k1 - k2 + 1) / k2); 35 | ans = {k1 + k2 * tmp, c / d * y - a / d * tmp}; 36 | } else { 37 | ans = {0, c / d * y}; 38 | } 39 | 40 | return {true, ans}; 41 | } 42 | 43 | int main() { 44 | ios_base::sync_with_stdio(false); 45 | cin.tie(nullptr); 46 | cout.tie(nullptr); 47 | 48 | int t; 49 | cin >> t; 50 | 51 | while (t--) { 52 | ll a, b, n, m; 53 | cin >> a >> b >> n >> m; 54 | auto result = solve_diophantine_equation(n, -m, b - a); 55 | if (!result.first) { 56 | cout << "NO" << endl; 57 | } else { 58 | ll p = (n * m) / gcd(n, m)[0]; 59 | ll x0 = a + result.second.first * n; 60 | x0 = (x0 + p * (abs(x0) / p + 1)) % p; 61 | cout << "YES " << x0 << ' ' << p << endl; 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /sem-4/solutions/7C.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Aleksandr Kiriak on 30.05.2024. 3 | // 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | cout.tie(nullptr); 13 | 14 | int p; 15 | cin >> p; 16 | 17 | vector rec(p); 18 | rec[1] = 1; 19 | for (int i = 2; i < p; i++) { 20 | rec[i] = (p - (long long) (p / i) * rec[p % i] % p) % p; 21 | } 22 | for (int i = 1; i < p; i += 100) { 23 | int sum = 0; 24 | for (int j = i; j < min(i + 100, p); j++) { 25 | sum = (sum + rec[j]) % p; 26 | } 27 | cout << sum << ' '; 28 | } 29 | cout << endl; 30 | } 31 | -------------------------------------------------------------------------------- /sem-4/solutions/7D.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Aleksandr Kiriak on 30.05.2024. 3 | // 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | int p, sz; 10 | vector rec; 11 | 12 | int get_rec(int number) { 13 | if (number < sz) { 14 | return rec[number]; 15 | } 16 | return (p - (long long) (p / number) * get_rec(p % number) % p) % p; 17 | } 18 | 19 | int main() { 20 | ios_base::sync_with_stdio(false); 21 | cin.tie(nullptr); 22 | cout.tie(nullptr); 23 | 24 | cin >> p; 25 | sz = p < 10 ? p : p / 5; 26 | rec.resize(sz); 27 | 28 | rec[1] = 1; 29 | for (int i = 2; i < sz; i++) { 30 | rec[i] = (p - (long long) (p / i) * rec[p % i] % p) % p; 31 | } 32 | 33 | int sum = 0, count = 0; 34 | for (int i = 1; i < p; i++) { 35 | sum = (sum + get_rec(i)) % p; 36 | count++; 37 | if (count == 100 || i == p - 1) { 38 | cout << sum << ' '; 39 | sum = 0; 40 | count = 0; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /sem-4/solutions/7E.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Aleksandr Kiriak on 30.05.2024. 3 | // 4 | #include 5 | 6 | using namespace std; 7 | 8 | int main() { 9 | long long p; 10 | cin >> p; 11 | cout << ((p * (p - 1) / 2) % p) << endl; 12 | } 13 | -------------------------------------------------------------------------------- /sem-4/solutions/7G.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Aleksandr Kiriak on 03.06.2024. 3 | // 4 | #pragma GCC optimize("O3,unroll-loops") 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | typedef long long ll; 11 | 12 | ll power2[64]; 13 | 14 | void calculate() { 15 | power2[0] = 1; 16 | for (int i = 1; i <= 63; ++i) { 17 | power2[i] = 2 * power2[i - 1]; 18 | } 19 | } 20 | 21 | ll multiply(ll x, ll y, ll mod) { 22 | ll result = 0; 23 | while (y) { 24 | if (y & 1) { 25 | result = (result + x) % mod; 26 | } 27 | x = (x * 2) % mod; 28 | y >>= 1; 29 | } 30 | return result; 31 | } 32 | 33 | ll pow(ll x, ll p, ll mod) { 34 | ll result = 1; 35 | while (p) { 36 | if (p & 1) { 37 | result = multiply(result, x, mod); 38 | } 39 | x = multiply(x, x, mod); 40 | p >>= 1; 41 | } 42 | return result; 43 | } 44 | 45 | bool Miller_Rabin(ll number) { 46 | if (number == 1 || number % 2 == 0 && number > 2) { 47 | return false; 48 | } 49 | ll zeroes = 0; 50 | ll tmp = number - 1; 51 | while (tmp % 2 == 0) { 52 | tmp /= 2; 53 | zeroes++; 54 | } 55 | srand(time(nullptr)); 56 | for (int _ = 0; _ < 4; ++_) { 57 | ll a = rand() % number; 58 | if (a == 0) { 59 | a++; 60 | } 61 | bool check1 = pow(a % number, tmp, number) == 1; 62 | if (check1) { 63 | continue; 64 | } 65 | bool check2 = false; 66 | for (int z = 0; z < zeroes; z++) { 67 | if (pow(a % number, multiply(power2[z], tmp, number), number) == number - 1) { 68 | check2 = true; 69 | break; 70 | } 71 | } 72 | if (!check2) { 73 | return false; 74 | } 75 | } 76 | return true; 77 | } 78 | 79 | int main() { 80 | ios_base::sync_with_stdio(false); 81 | cin.tie(nullptr); 82 | cout.tie(nullptr); 83 | 84 | ll n; 85 | cin >> n; 86 | 87 | calculate(); 88 | while (n--) { 89 | ll number; 90 | cin >> number; 91 | cout << (Miller_Rabin(number) ? "YES" : "NO") << endl; 92 | } 93 | } 94 | --------------------------------------------------------------------------------