├── .gitattributes ├── README.md ├── term 1 ├── Dynamic programming │ ├── A.java │ ├── B.java │ ├── C.java │ ├── D.java │ ├── E.java │ ├── F.java │ ├── G.java │ ├── H.java │ ├── J.java │ ├── K.java │ └── README.md ├── Heaps, sort, binsearch │ ├── B.java │ ├── D.java │ ├── E.java │ ├── F.java │ ├── G.java │ ├── H.java │ ├── I.java │ ├── J.java │ ├── K.java │ └── README.md └── Lists, stacks, queues │ ├── A.java │ ├── B.java │ ├── C.java │ ├── D.java │ ├── E.java │ ├── F.java │ ├── G.java │ ├── H.java │ ├── I.java │ ├── J.java │ ├── K.java │ └── README.md ├── term 2 ├── Greed and bust │ ├── A.cpp │ ├── B.cpp │ ├── E.cpp │ ├── G.cpp │ ├── H.cpp │ ├── I.cpp │ └── README.md ├── Search tree │ ├── A.cpp │ ├── C.cpp │ ├── D.cpp │ ├── E.cpp │ ├── F.cpp │ ├── G.cpp │ └── README.md ├── Segment tree │ ├── A.cpp │ ├── B.cpp │ ├── B.java │ ├── C.cpp │ ├── D.cpp │ ├── E.cpp │ ├── F.cpp │ ├── G.cpp │ ├── H.cpp │ ├── I.cpp │ ├── J.cpp │ ├── K.cpp │ └── README.md └── Tree queries │ ├── A.cpp │ ├── B.cpp │ ├── H.cpp │ └── README.md ├── term 3 ├── Graphs, DFS, MST │ ├── A.cpp │ ├── B.cpp │ ├── C.cpp │ ├── D.cpp │ ├── E.cpp │ ├── F.cpp │ ├── G.cpp │ ├── H.cpp │ ├── I.cpp │ ├── J.cpp │ ├── K.cpp │ └── README.md ├── Graphs, Shortest paths │ ├── A.cpp │ ├── B.cpp │ ├── C.cpp │ ├── D.cpp │ ├── E.cpp │ ├── F.cpp │ ├── H.cpp │ └── README.md └── Strings │ ├── A.cpp │ ├── B.cpp │ ├── C.cpp │ ├── D.cpp │ ├── E.cpp │ ├── G.cpp │ ├── J.cpp │ ├── K.cpp │ ├── L.cpp │ ├── M.cpp │ └── README.md └── term 4 ├── Flows and matchings ├── A.cpp ├── B.cpp ├── C.cpp ├── D.cpp ├── E.cpp ├── F.cpp ├── G.cpp ├── H.cpp ├── I.cpp ├── J.cpp └── README.md ├── Math ├── A.cpp ├── B.cpp ├── C.cpp ├── D.cpp ├── E.cpp ├── F.hs └── README.md └── Min cost flow ├── A.cpp ├── B.cpp ├── C.cpp ├── D.cpp ├── E.cpp └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Лабораторные работы по курсу "Алгоритмы и структуры данных" 2 | 3 | ## Первый семестр 4 | 5 | * [Куча, сортировки, двоичный поиск](term%201/Heaps%2C%20sort%2C%20binsearch) - [Условия](term%201/Heaps%2C%20sort%2C%20binsearch/README.md) 6 | 7 | * [Списки, стеки, очереди, СНМ](term%201/Lists%2C%20stacks%2C%20queues) - [Условия](term%201/Lists%2C%20stacks%2C%20queues/README.md) 8 | 9 | * [Динамическое программирование](term%201/Dynamic%20programming) - [Условия](term%201/Dynamic%20programming/README.md) 10 | 11 | ## Второй семестр 12 | 13 | * [Дерево отрезков](term%202/Segment%20tree) - [Условия](term%202/Segment%20tree/README.md) 14 | 15 | * [Дерево поиска](term%202/Search%20tree) - [Условия](term%202/Search%20tree/README.md) 16 | 17 | * [Запросы на деревьях](term%202/Tree%20queries) - [Условия](term%202/Tree%20queries/README.md) 18 | 19 | * [Жадность и перебор](term%202/Greed%20and%20bust) - [Условия](term%202/Greed%20and%20bust/README.md) 20 | 21 | ## Третий семестр 22 | 23 | * [Графы, кратчайшие пути](term%203/Graphs%2C%20Shortest%20paths) - [Условия](term%203/Graphs%2C%20Shortest%20paths/README.md) 24 | 25 | * [Графы, DFS, MST](term%203/Graphs%2C%20DFS%2C%20MST) - [Условия](term%203/Graphs%2C%20DFS%2C%20MST/README.md) 26 | 27 | * [Алгоритмы на строках](term%203/Strings) - [Условия](term%203/Strings/README.md) 28 | 29 | ## Четвертый семестр 30 | 31 | * [Потоки и паросочетания](term%204/Flows%20and%20matchings) - [Условия](term%204/Flows%20and%20matchings/README.md) 32 | 33 | * [Поток минимальной стоимости](term%204/Min%20cost%20flow) - [Условия](term%204/Min%20cost%20flow/README.md) 34 | 35 | * [Математика](term%204/Math) - [Условия](term%204/Math/README.md) 36 | -------------------------------------------------------------------------------- /term 1/Dynamic programming/A.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.io.FileWriter; 3 | import java.io.IOException; 4 | import java.util.ArrayDeque; 5 | import java.util.Scanner; 6 | 7 | public class A { 8 | 9 | static String VTraveSidelOgurechik(int n, int k, int a[]) { 10 | String ans = ""; 11 | 12 | int dp[] = new int[n + 1]; 13 | int monetki[] = new int[n + 1]; 14 | 15 | dp[1] = 0; 16 | int nmax = 0; 17 | 18 | for (int i = 2; i <= n; i++) { 19 | nmax = i - 1; 20 | int max; 21 | if ((i - k) > 1) max = i - k; 22 | else max = 1; 23 | for (int j = max; j < i; j++) { 24 | if (dp[nmax] < dp[j]) nmax = j; 25 | } 26 | monetki[i] = nmax; 27 | dp[i] = dp[nmax] + a[i]; 28 | } 29 | 30 | int cnt = 0; 31 | int num = n; 32 | 33 | ArrayDeque jumps = new ArrayDeque<>(); 34 | 35 | jumps.addLast(num); 36 | while (num > 1) { 37 | num = monetki[num]; 38 | jumps.add(num); 39 | cnt++; 40 | } 41 | 42 | ans = dp[n] + "\n" + cnt + "\n"; 43 | 44 | while (!jumps.isEmpty()) ans += jumps.removeLast() + " "; 45 | 46 | return ans; 47 | } 48 | 49 | public static void main(String[] args) throws IOException { 50 | Scanner scanner = new Scanner(new File("input.txt")); 51 | FileWriter fileWriter = new FileWriter(new File("output.txt")); 52 | 53 | int n = scanner.nextInt(); 54 | int k = scanner.nextInt(); 55 | int a[] = new int[n + 1]; 56 | 57 | a[1] = 0; 58 | a[n] = 0; 59 | 60 | for (int i = 2; i < n; i++) a[i] = scanner.nextInt(); 61 | 62 | fileWriter.write(VTraveSidelOgurechik(n, k, a) + ""); 63 | fileWriter.flush(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /term 1/Dynamic programming/B.java: -------------------------------------------------------------------------------- 1 | import javafx.beans.binding.When; 2 | 3 | import java.io.File; 4 | import java.io.FileWriter; 5 | import java.io.IOException; 6 | import java.util.ArrayDeque; 7 | import java.util.Scanner; 8 | 9 | public class B { 10 | 11 | static class Posl { 12 | ArrayDeque p; 13 | int size; 14 | 15 | Posl(ArrayDeque x, int y) { 16 | this.p = x; 17 | this.size = y; 18 | } 19 | } 20 | 21 | static Posl ToTheInfinityAndBeyond(int a[], int n) { 22 | int prev[] = new int[n]; 23 | int dp[] = new int[n]; 24 | for (int i = 0; i < n; i++) { 25 | prev[i] = -1; 26 | dp[i] = 1; 27 | for (int j = 0; j < i; j++) { 28 | if (a[i] > a[j]) 29 | if (dp[i] - 1 < dp[j]) { 30 | prev[i] = j; 31 | dp[i] = dp[j] + 1; 32 | } 33 | } 34 | } 35 | 36 | int last = 0; 37 | int len = dp[0]; 38 | for (int i = 0; i < n; i++) { 39 | if (len < dp[i]) { 40 | last = i; 41 | len = dp[i]; 42 | } 43 | } 44 | 45 | ArrayDeque ans = new ArrayDeque<>(); 46 | while (last >= 0) { 47 | int cur = a[last]; 48 | ans.addLast(cur); 49 | last = prev[last]; 50 | } 51 | 52 | Posl x = new Posl(ans, len); 53 | return x; 54 | } 55 | 56 | public static void main(String[] args) throws IOException { 57 | Scanner scanner = new Scanner(System.in); 58 | int n = scanner.nextInt(); 59 | int a[] = new int[n]; 60 | 61 | for (int i = 0; i < n; i++) a[i] = scanner.nextInt(); 62 | 63 | Posl ans = ToTheInfinityAndBeyond(a, n); 64 | System.out.print(ans.size + "\n"); 65 | while (!ans.p.isEmpty()) System.out.print(ans.p.removeLast() + " "); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /term 1/Dynamic programming/C.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | 3 | public class C { 4 | 5 | static long HOOOOOOOOOOORSE(int n) { 6 | long dp[][] = new long[10][n + 1]; 7 | int mod = 1000000000; 8 | for (int i = 0; i < 10; i++) { 9 | dp[i][1] = 1; 10 | } 11 | for (int j = 2; j <= n; j++) { 12 | for (int i = 0; i < 10; i++) { 13 | switch (i) { 14 | case 0: 15 | dp[0][j] = (dp[4][j - 1] + dp[6][j - 1]) % mod; 16 | break; 17 | case 1: 18 | dp[1][j] = (dp[6][j - 1] + dp[8][j - 1]) % mod; 19 | break; 20 | case 2: 21 | dp[2][j] = (dp[9][j - 1] + dp[7][j - 1]) % mod; 22 | break; 23 | case 3: 24 | dp[3][j] = (dp[8][j - 1] + dp[4][j - 1]) % mod; 25 | break; 26 | case 4: 27 | dp[4][j] = (dp[0][j - 1] + dp[3][j - 1] + dp[9][j - 1]) % mod; 28 | break; 29 | case 6: 30 | dp[6][j] = (dp[0][j - 1] + dp[1][j - 1] + dp[7][j - 1]) % mod; 31 | break; 32 | case 7: 33 | dp[7][j] = (dp[6][j - 1] + dp[2][j - 1]) % mod; 34 | break; 35 | case 8: 36 | dp[8][j] = (dp[1][j - 1] + dp[3][j - 1]) % mod; 37 | break; 38 | case 9: 39 | dp[9][j] = (dp[2][j - 1] + dp[4][j - 1]) % mod; 40 | break; 41 | } 42 | } 43 | } 44 | 45 | long sum = 0; 46 | for (int i = 1; i < 10; i++) if (i != 8) sum = (sum + dp[i][n]) % mod; 47 | return sum; 48 | } 49 | 50 | public static void main(String[] args) { 51 | Scanner scanner = new Scanner(System.in); 52 | int n = scanner.nextInt(); 53 | System.out.print(HOOOOOOOOOOORSE(n)); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /term 1/Dynamic programming/D.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.io.FileWriter; 3 | import java.io.IOException; 4 | import java.util.Scanner; 5 | 6 | public class D { 7 | 8 | static int minimin(int a, int b, int c) { 9 | return Math.min(Math.min(a, b), c); 10 | } 11 | 12 | static int meme(char i, char j) { 13 | if (i == j) return 0; 14 | else return 1; 15 | } 16 | 17 | static int HereFishyFishy(String s1, String s2) { 18 | int m = s1.length(); 19 | int n = s2.length(); 20 | int dp[][] = new int[m + 1][n + 1]; 21 | for (int i = 0; i <= m; i++) { 22 | for (int j = 0; j <= n; j++) { 23 | if (i == 0 && j == 0) { 24 | dp[i][j] = 0; 25 | continue; 26 | } 27 | if (i == 0 && j > 0) { 28 | dp[i][j] = j; 29 | continue; 30 | } 31 | if (i > 0 && j == 0) { 32 | dp[i][j] = i; 33 | continue; 34 | } 35 | if (j > 0 && i > 0) { 36 | dp[i][j] = minimin(dp[i][j - 1] + 1, dp[i - 1][j] + 1, dp[i - 1][j - 1] + meme(s1.charAt(i - 1), s2.charAt(j - 1))); 37 | } 38 | } 39 | } 40 | return dp[m][n]; 41 | } 42 | 43 | public static void main(String[] args) throws IOException { 44 | Scanner scanner = new Scanner(new File("input.txt")); 45 | FileWriter fileWriter = new FileWriter(new File("output.txt")); 46 | 47 | String s1 = scanner.nextLine(); 48 | String s2 = scanner.nextLine(); 49 | 50 | fileWriter.write(HereFishyFishy(s1, s2) + ""); 51 | fileWriter.flush(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /term 1/Dynamic programming/E.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayDeque; 2 | import java.util.Scanner; 3 | 4 | public class E { 5 | static int inf = 1000000; 6 | static int dp[][]; 7 | static int a[]; 8 | 9 | 10 | static int DP(int i, int j) { 11 | if (j > i) return inf; 12 | else { 13 | int res; 14 | int cost = a[i]; 15 | if (j <= 0) { 16 | if (i >= 1) { 17 | if (cost <= 100) { 18 | int dif = Math.min(DP(i - 1, j + 1), DP(i - 1, j) + cost); 19 | res = dif; 20 | } else { 21 | return DP(i - 1, j + 1); 22 | } 23 | } else return 0; 24 | } else { 25 | if (dp[i][j] != -1) return dp[i][j]; 26 | if (cost > 100) { 27 | int dif = Math.min(DP(i - 1, j + 1), DP(i - 1, j - 1) + cost); 28 | res = dif; 29 | } else { 30 | int dif = Math.min(DP(i - 1, j + 1), DP(i - 1, j) + cost); 31 | res = dif; 32 | } 33 | } 34 | dp[i][j] = res; 35 | return res; 36 | } 37 | } 38 | 39 | 40 | static void GOODOLDDAYS(ArrayDeque used, int i, int j) { 41 | if (j < i) { 42 | int cost = a[i]; 43 | if (j <= 0) { 44 | if (i >= 1) { 45 | if (cost > 100) { 46 | used.add(i); 47 | GOODOLDDAYS(used, i - 1, j + 1); 48 | } else { 49 | boolean addi = (DP(i, j) == DP(i - 1, j + 1)); 50 | if (addi) { 51 | used.add(i); 52 | GOODOLDDAYS(used, i - 1, j + 1); 53 | } else GOODOLDDAYS(used, i - 1, j); 54 | } 55 | } 56 | } else { 57 | if (cost <= 100) { 58 | boolean addi = (DP(i - 1, j + 1) == DP(i, j)); 59 | if (addi) { 60 | used.add(i); 61 | GOODOLDDAYS(used, i - 1, j + 1); 62 | } else { 63 | GOODOLDDAYS(used, i - 1, j); 64 | } 65 | } else { 66 | boolean addi = (DP(i - 1, j + 1) == DP(i, j)); 67 | if (addi) { 68 | used.add(i); 69 | GOODOLDDAYS(used, i - 1, j + 1); 70 | } else { 71 | GOODOLDDAYS(used, i - 1, j - 1); 72 | } 73 | } 74 | } 75 | } 76 | } 77 | 78 | 79 | public static void main(String[] args) { 80 | Scanner scanner = new Scanner(System.in); 81 | 82 | int n = scanner.nextInt(); 83 | int k1 = 0; 84 | int k2 = 0; 85 | a = new int[n + 1]; 86 | for (int i = 1; i <= n; i++) a[i] = scanner.nextInt(); 87 | dp = new int[n + 1][n + 2]; 88 | for (int i = 0; i <= n; i++) { 89 | for (int j = 0; j <= n + 1; j++) 90 | dp[i][j] = -1; 91 | } 92 | 93 | int ans = inf; 94 | 95 | for (int i = 0; i <= n; i++) { 96 | if (ans >= DP(n, i)) { 97 | ans = DP(n, i); 98 | k1 = i; 99 | } 100 | } 101 | 102 | System.out.println(ans); 103 | 104 | ArrayDeque used = new ArrayDeque<>(); 105 | 106 | GOODOLDDAYS(used, n, k1); 107 | 108 | k2 = used.size(); 109 | 110 | System.out.println(k1 + " " + k2); 111 | 112 | while (!used.isEmpty()) { 113 | System.out.print(used.removeLast() + "\n"); 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /term 1/Dynamic programming/F.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | 3 | public class F { 4 | static int dp[][]; 5 | static int pos[][]; 6 | static String s; 7 | static StringBuilder res; 8 | 9 | public static void main(String[] args) { 10 | Scanner scanner = new Scanner(System.in); 11 | s = scanner.nextLine(); 12 | 13 | int n = s.length(); 14 | dp = new int[n][n]; 15 | pos = new int[n][n]; 16 | res = new StringBuilder(); 17 | 18 | if (n > 0) { 19 | for (int i = 0; i < n; i++) { 20 | for (int j = 0; j < n; j++) { 21 | if (i > j) { 22 | dp[i][j] = 0; 23 | continue; 24 | } 25 | if (i == j) dp[i][j] = 1; 26 | } 27 | } 28 | for (int right = 0; right < n; right++) { 29 | for (int left = right; left >= 0; left--) { 30 | if (left == right) { 31 | dp[left][right] = 1; 32 | } else { 33 | int min = 100000; 34 | int mink = -10; 35 | if ((s.charAt(left) == '(' && s.charAt(right) == ')') || (s.charAt(left) == '[' && s.charAt(right) == ']') || (s.charAt(left) == '{' && s.charAt(right) == '}')) 36 | min = dp[left + 1][right - 1]; 37 | for (int k = left; k < right; k++) { 38 | if (dp[left][k] + dp[k + 1][right] < min) { 39 | min = dp[left][k] + dp[k + 1][right]; 40 | mink = k; 41 | } 42 | } 43 | dp[left][right] = min; 44 | pos[left][right] = mink; 45 | } 46 | } 47 | } 48 | 49 | ans(0, n - 1); 50 | System.out.print(res.toString().length()); 51 | } else System.out.print(""); 52 | } 53 | 54 | static void ans(int left, int right) { 55 | if (dp[left][right] == right - left + 1) return; 56 | if (dp[left][right] == 0) { 57 | res.append(s.substring(left, right + 1)); 58 | return; 59 | } 60 | if (pos[left][right] == -10) { 61 | res.append(s.charAt(left)); 62 | ans(left + 1, right - 1); 63 | res.append(s.charAt(right)); 64 | return; 65 | } 66 | ans(left, pos[left][right]); 67 | ans(pos[left][right] + 1, right); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /term 1/Dynamic programming/G.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | 3 | public class G { 4 | static int dp[][]; 5 | static int pos[][]; 6 | static String s; 7 | static StringBuilder res; 8 | 9 | 10 | public static void main(String[] args) { 11 | Scanner scanner = new Scanner(System.in); 12 | s = scanner.nextLine(); 13 | int n = s.length(); 14 | dp = new int[n][n]; 15 | pos = new int[n][n]; 16 | res = new StringBuilder(); 17 | if (n > 0) { 18 | for (int i = 0; i < n; i++) { 19 | for (int j = 0; j < n; j++) { 20 | if (j < i) { 21 | dp[i][j] = 0; 22 | continue; 23 | } 24 | if (i == j) dp[i][j] = 1; 25 | } 26 | } 27 | for (int right = 0; right < n; right++) { 28 | for (int left = right; left >= 0; left--) { 29 | if (left == right) { 30 | dp[left][right] = 1; 31 | } else { 32 | int min = 100000; 33 | int mink = -10; 34 | if (s.charAt(left) == '(' && s.charAt(right) == ')') 35 | min = dp[left + 1][right - 1]; 36 | if (s.charAt(left) == '[' && s.charAt(right) == ']') min = dp[left + 1][right - 1]; 37 | if (s.charAt(left) == '{' && s.charAt(right) == '}') min = dp[left + 1][right - 1]; 38 | for (int k = left; k < right; k++) { 39 | if (min > dp[left][k] + dp[k + 1][right]) { 40 | min = dp[left][k] + dp[k + 1][right]; 41 | mink = k; 42 | } 43 | } 44 | dp[left][right] = min; 45 | pos[left][right] = mink; 46 | } 47 | } 48 | } 49 | 50 | ans(0, n - 1); 51 | System.out.print(res.toString()); 52 | } else System.out.print(""); 53 | } 54 | 55 | static void ans(int left, int right) { 56 | if (dp[left][right] == right - left + 1) return; 57 | if (dp[left][right] == 0) { 58 | res.append(s.substring(left, right + 1)); 59 | return; 60 | } 61 | if (pos[left][right] == -10) { 62 | res.append(s.charAt(left)); 63 | ans(left + 1, right - 1); 64 | res.append(s.charAt(right)); 65 | return; 66 | } 67 | ans(left, pos[left][right]); 68 | ans(pos[left][right] + 1, right); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /term 1/Dynamic programming/H.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.Scanner; 3 | 4 | public class H { 5 | static int mn = 101; 6 | static ArrayList> a = new ArrayList<>(); 7 | static int num[]; 8 | static boolean old[]; 9 | static int dp[][] = new int[mn][2]; 10 | 11 | 12 | static void DepthFirstSearh(int x, int y) { 13 | old[x] = true; 14 | 15 | for (int i = 0; i < a.get(x).size(); i++) { 16 | int tmp = a.get(x).get(i); 17 | if (!old[tmp]) { 18 | DepthFirstSearh(tmp, x); 19 | } 20 | } 21 | 22 | int cnt = 0; 23 | int sum = 0; 24 | 25 | for (int i = 0; i < a.get(x).size(); i++) { 26 | int tmp = a.get(x).get(i); 27 | if (tmp != y) { 28 | int max = Math.max(dp[tmp][0], dp[tmp][1]); 29 | sum = sum + max; 30 | cnt = cnt + dp[tmp][0]; 31 | } 32 | } 33 | 34 | dp[x][1] = dp[x][1] + cnt; 35 | dp[x][0] = sum; 36 | } 37 | 38 | public static void main(String[] args) { 39 | Scanner scanner = new Scanner(System.in); 40 | int n = scanner.nextInt(); 41 | int start = 0; 42 | 43 | for (int i = 0; i < mn; i++) { 44 | a.add(new ArrayList()); 45 | } 46 | 47 | old = new boolean[n]; 48 | num = new int[n]; 49 | 50 | for (int i = 0; i < n; i++) { 51 | int tmp = scanner.nextInt(); 52 | if (tmp > 0) { 53 | a.get(i).add(tmp - 1); 54 | a.get(tmp - 1).add(i); 55 | } else { 56 | start = i; 57 | } 58 | } 59 | 60 | for (int i = 0; i < n; i++) { 61 | dp[i][0] = 0; 62 | dp[i][1] = 1; 63 | } 64 | 65 | DepthFirstSearh(start, start); 66 | 67 | int max = Math.max(dp[start][0], dp[start][1]); 68 | System.out.print(max + ""); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /term 1/Dynamic programming/J.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.io.FileNotFoundException; 3 | import java.lang.reflect.Array; 4 | import java.util.ArrayList; 5 | import java.util.Scanner; 6 | 7 | public class J { 8 | static int infinity = 1000000000; 9 | static int dp[][]; 10 | static int a[][]; 11 | static int n, len; 12 | 13 | static int AREUREADY() { 14 | int res; 15 | int len = (1 << n); 16 | for (int i = 0; i < n; i++) { 17 | for (int j = 0; j < len; j++) { 18 | dp[i][j] = infinity; 19 | } 20 | } 21 | dp[0][0] = 0; 22 | res = ChipAndDale(0, len - 1); 23 | return res; 24 | } 25 | 26 | 27 | static int ChipAndDale(int i, int j) { 28 | if (dp[i][j] != infinity) { 29 | return dp[i][j]; 30 | } 31 | 32 | for (int e = 0; e < n; e++) { 33 | boolean bit; 34 | if ((j & (1 << e)) == 0) bit = false; 35 | else bit = true; 36 | if ((a[i][e] != 0) && 37 | bit) { 38 | dp[i][j] = Math.min(dp[i][j], (ChipAndDale(e, j - (1 << e)) + a[i][e])); 39 | } 40 | } 41 | 42 | return dp[i][j]; 43 | } 44 | 45 | static ArrayList HereYouAre() { 46 | ArrayList way = new ArrayList<>(); 47 | int i = 0; 48 | int j = len - 1; 49 | 50 | while (j != 0) { 51 | for (int e = 0; e < n; e++) { 52 | boolean bit; 53 | if ((j & (1 << e)) == 0) bit = false; 54 | else bit = true; 55 | if ((a[i][e] != 0) && 56 | bit && 57 | (dp[i][j] == dp[e][j - (1 << e)] + a[i][e])) { 58 | way.add(e); 59 | i = e; 60 | j = j - (1 << e); 61 | } 62 | } 63 | } 64 | 65 | return way; 66 | } 67 | 68 | public static void main(String[] args) throws FileNotFoundException { 69 | Scanner scanner = new Scanner(System.in); 70 | n = scanner.nextInt() + 1; 71 | a = new int[n][n]; 72 | len = 1 << n; 73 | dp = new int[n][len]; 74 | for (int i = 0; i < n; i++) { 75 | for (int j = 0; j < n; j++) { 76 | if (i == 0 && j == 0) { 77 | a[i][j] = 0; 78 | continue; 79 | } 80 | if (i == 0 || j == 0) a[i][j] = -1; 81 | else 82 | a[i][j] = scanner.nextInt(); 83 | } 84 | } 85 | 86 | int res = AREUREADY(); 87 | System.out.println((res + 2)); 88 | 89 | ArrayList ans; 90 | ans = HereYouAre(); 91 | 92 | for (int i = ans.size() - 2; i >= 0; i--) { 93 | System.out.print((ans.get(i)) + " "); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /term 1/Dynamic programming/K.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.io.FileWriter; 3 | import java.io.IOException; 4 | import java.util.Scanner; 5 | 6 | public class K { 7 | 8 | static boolean GOGO(long x, long y, int n) { 9 | long b[] = new long[5]; 10 | 11 | for (int i = 0; i < n - 1; i++) { 12 | if ((x & (1 << i)) == 0) b[1] = 0; 13 | else b[1] = 1; 14 | if ((x & (1 << i + 1)) == 0) b[2] = 0; 15 | else b[2] = 1; 16 | if ((y & (1 << i)) == 0) b[3] = 0; 17 | else b[3] = 1; 18 | if ((y & (1 << i + 1)) == 0) b[4] = 0; 19 | else b[4] = 1; 20 | if ((b[1] == b[2]) && (b[2] == b[3]) && (b[3] == b[4])) { 21 | return false; 22 | } 23 | } 24 | 25 | return true; 26 | } 27 | 28 | static int YouOnlyLiveNice(int n, int m) { 29 | int res = 0; 30 | int len = 1 << n; 31 | long a[][] = new long[m][len]; 32 | long dp[][] = new long[len][len]; 33 | 34 | for (int i = 0; i < len; i++) { 35 | for (int j = 0; j < len; j++) { 36 | if (GOGO(i, j, n)) { 37 | dp[i][j] = 1; 38 | } else { 39 | dp[i][j] = 0; 40 | } 41 | } 42 | } 43 | 44 | for (int i = 0; i < len; i++) { 45 | a[0][i] = 1; 46 | } 47 | 48 | for (int x = 1; x < m; x++) { 49 | for (int i = 0; i < len; i++) { 50 | for (int j = 0; j < len; j++) { 51 | a[x][i] = a[x][i] + a[x - 1][j] * dp[j][i]; 52 | } 53 | } 54 | } 55 | for (int i = 0; i < len; i++) { 56 | res += a[m - 1][i]; 57 | } 58 | return res; 59 | } 60 | 61 | public static void main(String[] args) throws IOException { 62 | Scanner scanner = new Scanner(new File("nice.in")); 63 | FileWriter fileWriter = new FileWriter(new File("nice.out")); 64 | int n = scanner.nextInt(); 65 | int m = scanner.nextInt(); 66 | 67 | if (n > m) { 68 | int tmp = n; 69 | n = m; 70 | m = tmp; 71 | } 72 | 73 | fileWriter.write(YouOnlyLiveNice(n, m) + ""); 74 | fileWriter.flush(); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /term 1/Heaps, sort, binsearch/B.java: -------------------------------------------------------------------------------- 1 | mport javafx.util.Pair; 2 | 3 | 4 | import java.io.File; 5 | import java.io.FileWriter; 6 | import java.io.IOException; 7 | import java.util.ArrayList; 8 | import java.util.Scanner; 9 | 10 | 11 | public class B { 12 | public static void main(String[] args) throws IOException { 13 | 14 | class MinHeap { 15 | public ArrayList> heap; 16 | 17 | MinHeap(ArrayList> a) { 18 | heap = a; 19 | } 20 | 21 | public void siftDown(int i) { 22 | while (2 * i + 1 < heap.size()) { 23 | int left = 2 * i + 1; 24 | int right = 2 * i + 2; 25 | int j = left; 26 | 27 | if ((right < heap.size()) && ((heap.get(right).getValue()) < (heap.get(left).getValue()))) { 28 | j = right; 29 | } 30 | 31 | if ((heap.get(i).getValue()) <= (heap.get(j).getValue())) { 32 | break; 33 | } 34 | Pair t = heap.get(i); 35 | heap.set(i, heap.get(j)); 36 | heap.set(j, t); 37 | i = j; 38 | } 39 | } 40 | 41 | public void siftUp(int i) { 42 | while ((heap.get(i).getValue()) < heap.get((i - 1) / 2).getValue()) { 43 | Pair t = heap.get(i); 44 | heap.set(i, heap.get((i - 1) / 2)); 45 | heap.set((i - 1) / 2, t); 46 | i = (i - 1) / 2; 47 | } 48 | } 49 | 50 | public Pair extractMin() { 51 | Pair min = heap.get(0); 52 | heap.set(0, heap.get(heap.size() - 1)); 53 | heap.remove((heap.size() - 1)); 54 | siftDown(0); 55 | return min; 56 | } 57 | 58 | public void insert(Pair k) { 59 | heap.add(k); 60 | siftUp((heap.size() - 1)); 61 | } 62 | } 63 | 64 | 65 | MinHeap myheap = new MinHeap(new ArrayList>()); 66 | Scanner scanner = new Scanner(new File("priorityqueue.in")); 67 | FileWriter fileWriter = new FileWriter(new File("priorityqueue.out")); 68 | int count = 0; 69 | while (scanner.hasNextLine()) { 70 | String split[] = scanner.nextLine().split(" "); 71 | count++; 72 | switch (split[0].charAt(0)) { 73 | case 'p': 74 | myheap.insert(new Pair(count, Integer.parseInt(split[1]))); 75 | break; 76 | case 'e': 77 | if (myheap.heap.size() < 1) { 78 | fileWriter.write("*" + "\r\n"); 79 | fileWriter.flush(); 80 | } else { 81 | fileWriter.write(myheap.extractMin().getValue() + "\r\n"); 82 | fileWriter.flush(); 83 | } 84 | break; 85 | case 'd': 86 | int num1 = Integer.parseInt(split[1]); 87 | for (int i = 0; i < myheap.heap.size(); i++) { 88 | if (myheap.heap.get(i).getKey() == num1) { 89 | myheap.heap.set(i, new Pair(num1, Integer.parseInt(split[2]))); 90 | myheap.siftUp(i); 91 | break; 92 | } 93 | } 94 | break; 95 | } 96 | } 97 | } 98 | } 99 | 100 | 101 | -------------------------------------------------------------------------------- /term 1/Heaps, sort, binsearch/D.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.io.FileNotFoundException; 3 | import java.io.FileWriter; 4 | import java.io.IOException; 5 | import java.util.Scanner; 6 | 7 | public class D { 8 | 9 | public static void main(String[] args) throws IOException { 10 | Scanner scanner = new Scanner(new File("radixsort.in")); 11 | FileWriter fileWriter = new FileWriter(new File("radixsort.out")); 12 | 13 | String s = scanner.nextLine(); 14 | String[] split = s.split(" "); 15 | 16 | int n = Integer.parseInt(split[0]); 17 | int m = Integer.parseInt(split[1]); 18 | int k = Integer.parseInt(split[2]); 19 | 20 | String[] list = new String[n]; 21 | for (int i = 0; i < n; i++) { 22 | list[i] = scanner.nextLine(); 23 | } 24 | 25 | int count = 0; 26 | int alpha = 26; 27 | for (int i = m - 1; i >= 0; i--) { 28 | String b[] = new String[n]; 29 | int[] c = new int[26]; 30 | for (int j = 0; j <= alpha - 1; j++) { 31 | c[j] = 0; 32 | } 33 | 34 | for (int j = 0; j <= n - 1; j++) { 35 | int d = list[j].charAt(i) - 97; 36 | c[d]++; 37 | } 38 | int count = 0; 39 | 40 | for (int j = 0; j <= alpha - 1; j++) { 41 | int tmp = c[j]; 42 | c[j] = count; 43 | count += tmp; 44 | } 45 | 46 | for (int j = 0; j <= n - 1; j++) { 47 | int d = list[j].charAt(i) - 97; 48 | b[c[d]] = list[j]; 49 | c[d]++; 50 | } 51 | 52 | list = b; 53 | 54 | count++; 55 | if (count == k) { 56 | break; 57 | } 58 | } 59 | 60 | for (int j = 0; j < list.length; j++) { 61 | fileWriter.write(list[j] + "\r\n"); 62 | fileWriter.flush(); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /term 1/Heaps, sort, binsearch/E.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.io.FileNotFoundException; 3 | import java.io.FileWriter; 4 | import java.io.IOException; 5 | import java.util.ArrayList; 6 | import java.util.Arrays; 7 | import java.util.Scanner; 8 | 9 | public class E { 10 | public static void antiQsort(int a[]) { 11 | for (int i = 0; i < a.length; i++) { 12 | int t = a[i]; 13 | a[i] = a[i / 2]; 14 | a[i / 2] = t; 15 | } 16 | } 17 | 18 | public static void main(String[] args) throws IOException { 19 | Scanner scanner = new Scanner(new File("antiqs.in")); 20 | 21 | int n = scanner.nextInt(); 22 | int a[] = new int[n]; 23 | for (int i = 0; i < n; i++) { 24 | a[i] = i + 1; 25 | } 26 | 27 | antiQsort(a); 28 | 29 | FileWriter fileWriter = new FileWriter(new File("antiqs.out")); 30 | 31 | for (int i = 0; i < n; i++) { 32 | fileWriter.write(a[i] + " "); 33 | fileWriter.flush(); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /term 1/Heaps, sort, binsearch/F.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.io.FileNotFoundException; 3 | import java.io.FileWriter; 4 | import java.io.IOException; 5 | import java.util.Scanner; 6 | 7 | public class F { 8 | 9 | public static void main(String[] args) throws IOException { 10 | Scanner scanner = new Scanner(new File("style.in")); 11 | 12 | int n = scanner.nextInt(); 13 | int a[] = new int[n]; 14 | for (int k = 0; k < n; k++) { 15 | a[k] = scanner.nextInt(); 16 | } 17 | 18 | int m = scanner.nextInt(); 19 | int b[] = new int[m]; 20 | for (int k = 0; k < m; k++) { 21 | b[k] = scanner.nextInt(); 22 | } 23 | 24 | int i = 0; 25 | int j = 0; 26 | int mini = -1; 27 | int minj = -1; 28 | int min = a[n - 1] + b[m - 1]; 29 | 30 | while (i < n && j < m) { 31 | if (Math.abs(a[i] - b[j]) < min) { 32 | min = Math.abs(a[i] - b[j]); 33 | mini = a[i]; 34 | minj = b[j]; 35 | } 36 | 37 | if (a[i] > b[j]) { 38 | j++; 39 | } else { 40 | i++; 41 | } 42 | } 43 | 44 | FileWriter fileWriter = new FileWriter(new File("style.out")); 45 | fileWriter.write(mini + " " + minj); 46 | fileWriter.flush(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /term 1/Heaps, sort, binsearch/G.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.io.FileNotFoundException; 3 | import java.io.FileWriter; 4 | import java.io.IOException; 5 | import java.lang.reflect.Array; 6 | import java.util.ArrayList; 7 | import java.util.Arrays; 8 | import java.util.Scanner; 9 | 10 | public class G { 11 | 12 | public static void main(String[] args) throws IOException { 13 | Scanner scanner = new Scanner(new File("style.in")); 14 | 15 | int i1 = 0, i2 = 0, i3 = 0, i4 = 0; 16 | int n1 = scanner.nextInt(); 17 | int[] a1 = new int[100001]; 18 | 19 | for (int i = 0; i < n1; i++) { 20 | a1[i] = scanner.nextInt(); 21 | } 22 | 23 | int n2 = scanner.nextInt(); 24 | int[] a2 = new int[100001]; 25 | 26 | for (int i = 0; i < n2; i++) { 27 | a2[i] = scanner.nextInt(); 28 | } 29 | 30 | int n3 = scanner.nextInt(); 31 | int[] a3 = new int[100001]; 32 | 33 | for (int i = 0; i < n3; i++) { 34 | a3[i] = scanner.nextInt(); 35 | } 36 | 37 | int n4 = scanner.nextInt(); 38 | int[] a4 = new int[100001]; 39 | for (int i = 0; i < n4; i++) { 40 | a4[i] = scanner.nextInt(); 41 | } 42 | 43 | Arrays.sort(a1, 0, n1); 44 | Arrays.sort(a2, 0, n2); 45 | Arrays.sort(a3, 0, n3); 46 | Arrays.sort(a4, 0, n4); 47 | 48 | 49 | int min = Math.min(Math.min(a1[0], a2[0]), Math.min(a3[0], a4[0])); 50 | int max = Math.max(Math.max(a1[0], a2[0]), Math.max(a3[0], a4[0])); 51 | int diff = Math.abs(max - min); 52 | 53 | int min1 = i1, min2 = i2, min3 = i3, min4 = i4; 54 | while (i1 < n1 && i2 < n2 && i3 < n3 && i4 < n4) { 55 | min = Math.min(Math.min(a1[i1], a2[i2]), Math.min(a3[i3], a4[i4])); 56 | max = Math.max(Math.max(a1[i1], a2[i2]), Math.max(a3[i3], a4[i4])); 57 | int diffR = Math.abs(max - min); 58 | 59 | if (diffR < diff) { 60 | diff = diffR; 61 | min1 = i1; 62 | min2 = i2; 63 | min3 = i3; 64 | min4 = i4; 65 | } 66 | 67 | if (diffR < 1) { 68 | break; 69 | } 70 | 71 | while (min == a1[i1]) { 72 | i1++; 73 | } 74 | 75 | while (min == a2[i2]) { 76 | i2++; 77 | } 78 | 79 | while (min == a3[i3]) { 80 | i3++; 81 | } 82 | 83 | while (min == a4[i4]) { 84 | i4++; 85 | } 86 | } 87 | 88 | FileWriter fileWriter = new FileWriter("style.out"); 89 | fileWriter.write(a1[min1] + " " + a2[min2] + " " + a3[min3] + " " + a4[min4]); 90 | fileWriter.flush(); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /term 1/Heaps, sort, binsearch/H.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.io.FileNotFoundException; 3 | import java.io.FileWriter; 4 | import java.io.IOException; 5 | import java.util.Scanner; 6 | 7 | public class H { 8 | static int kth(int[] a, int l, int r, int k) { 9 | int i = l; 10 | int j = r; 11 | int x = a[(int) (Math.random() * (r - l + 1)) + l]; 12 | 13 | while (i <= j) { 14 | while ((a[i] < x)) { 15 | i++; 16 | } 17 | 18 | while (a[j] > x) { 19 | j--; 20 | } 21 | 22 | if (i <= j) { 23 | int t = a[i]; 24 | a[i] = a[j]; 25 | a[j] = t; 26 | i++; 27 | j--; 28 | } 29 | } 30 | 31 | if (l <= k && k <= j) { 32 | return kth(a, l, j, k); 33 | } else if (i <= k && k <= r) { 34 | return kth(a, i, r, k); 35 | } 36 | return a[k]; 37 | } 38 | 39 | public static void main(String[] args) throws IOException { 40 | Scanner scanner = new Scanner(new File("kth.in")); 41 | FileWriter fileWriter = new FileWriter(new File("kth.out")); 42 | 43 | int n = scanner.nextInt(); 44 | int k = scanner.nextInt(); 45 | int A = scanner.nextInt(); 46 | int B = scanner.nextInt(); 47 | int C = scanner.nextInt(); 48 | 49 | int[] mas = new int[n]; 50 | mas[0] = scanner.nextInt(); 51 | mas[1] = scanner.nextInt(); 52 | 53 | for (int i = 2; i < n; i++) { 54 | mas[i] = A * mas[i - 2] + B * mas[i - 1] + C; 55 | } 56 | 57 | fileWriter.write(Integer.toString(kth(mas, 0, mas.length - 1, k - 1))); 58 | fileWriter.flush(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /term 1/Heaps, sort, binsearch/I.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.io.FileNotFoundException; 3 | import java.io.FileWriter; 4 | import java.io.IOException; 5 | import java.util.Scanner; 6 | 7 | public class I { 8 | static int binSearchFirst(int a[], int k) { 9 | int l = 0; 10 | int r = a.length - 1; 11 | 12 | while (l < r) { 13 | int m = l + (r - l) / 2; 14 | if (a[m] >= k) { 15 | r = m; 16 | } else { 17 | l = m + 1; 18 | } 19 | } 20 | 21 | if (a[l] == k) { 22 | return l + 1; 23 | } else { 24 | return -1; 25 | } 26 | } 27 | 28 | static int binSearchLast(int a[], int k) { 29 | int l = 0; 30 | int r = a.length - 1; 31 | 32 | while (l < r) { 33 | int m = r - (r - l) / 2; 34 | 35 | if (a[m] <= k) { 36 | l = m; 37 | } else { 38 | r = m - 1; 39 | } 40 | } 41 | 42 | if (a[l] == k) { 43 | return l + 1; 44 | } else { 45 | return -1; 46 | } 47 | } 48 | 49 | public static void main(String[] args) throws IOException { 50 | Scanner scanner = new Scanner(new File("binsearch.in")); 51 | FileWriter fileWriter = new FileWriter(new File("binsearch.out")); 52 | 53 | int n = Integer.parseInt(scanner.nextLine()); 54 | String s[] = scanner.nextLine().split(" "); 55 | int a[] = new int[n]; 56 | 57 | for (int i = 0; i < n; i++) { 58 | a[i] = Integer.parseInt(s[i]); 59 | 60 | } 61 | 62 | int m = Integer.parseInt(scanner.nextLine()); 63 | s = scanner.nextLine().split(" "); 64 | int z[] = new int[m]; 65 | 66 | for (int i = 0; i < m; i++) { 67 | z[i] = Integer.parseInt(s[i]); 68 | 69 | } 70 | 71 | for (int i = 0; i < m; i++) { 72 | int x = binSearchfirst(a, z[i]); 73 | int y = binSearchlast(a, z[i]); 74 | 75 | if (i < m - 1) { 76 | fileWriter.write(+x + " " + y + "\r\n"); 77 | fileWriter.flush(); 78 | } else { 79 | fileWriter.write(+x + " " + y); 80 | fileWriter.flush(); 81 | } 82 | 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /term 1/Heaps, sort, binsearch/J.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.io.FileNotFoundException; 3 | import java.io.FileWriter; 4 | import java.io.IOException; 5 | import java.text.DecimalFormat; 6 | import java.util.Locale; 7 | import java.util.Scanner; 8 | 9 | public class J { 10 | 11 | public static double binSearch(int n, double l, double r) { 12 | double x = -1; 13 | double h = r; 14 | 15 | while ((r - l) > 0.01 / (n - 1)) { 16 | double mid = (l + r) / 2; 17 | double h0 = h, hi = mid; 18 | boolean greater = hi > 0; 19 | 20 | for (int i = 3; i <= n; i++) { 21 | double hn = 2 * hi - h0 + 2; 22 | greater = (hn > 0) && (greater); 23 | h0 = hi; 24 | hi = hn; 25 | } 26 | 27 | if (greater) { 28 | r = mid; 29 | x = hi; 30 | } else { 31 | l = mid; 32 | } 33 | } 34 | return x; 35 | } 36 | 37 | public static void main(String[] args) throws IOException { 38 | Scanner scanner = new Scanner(new File("garland.in")).useLocale(Locale.US); 39 | 40 | int n = scanner.nextInt(); 41 | double A = scanner.nextDouble(); 42 | 43 | FileWriter filewriter = new FileWriter(new File("garland.out")); 44 | filewriter.write(new DecimalFormat("#0.00").format(search(n, 0, A))); 45 | filewriter.flush(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /term 1/Heaps, sort, binsearch/K.java: -------------------------------------------------------------------------------- 1 | import javafx.util.Pair; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.lang.reflect.Array; 6 | import java.util.ArrayList; 7 | import java.util.Scanner; 8 | 9 | public class K { 10 | public static void main(String[] args) throws FileNotFoundException { 11 | Scanner scanner = new Scanner(new File("C:/Users/dimka/Desktop/tests/trainin.txt")); 12 | String s[] = scanner.nextLine().split(" "); 13 | 14 | int n = Integer.parseInt(s[1]), L = Integer.parseInt(s[0]); 15 | ArrayList> a = new ArrayList>(); 16 | 17 | for (int i = 0; i < n; i++) { 18 | int time = scanner.nextInt(); 19 | int speed = scanner.nextInt(); 20 | 21 | a.add(new Pair(time, speed)); 22 | 23 | System.out.println(a.get(i).getKey() + " " + a.get(i).getValue()); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /term 1/Lists, stacks, queues/A.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.io.FileWriter; 3 | import java.io.IOException; 4 | import java.util.ArrayList; 5 | import java.util.Scanner; 6 | import java.util.Stack; 7 | 8 | public class A { 9 | public static void main(String[] args) throws IOException { 10 | Scanner scanner = new Scanner(new File("decode.in")); 11 | String s = scanner.nextLine(); 12 | ArrayList res = new ArrayList(); 13 | 14 | for (int i = 0; i < s.length(); i++) { 15 | char cur = s.charAt(i); 16 | int len = res.size(); 17 | if (len != 0 && cur == res.get(len - 1)) { 18 | res.remove(len - 1); 19 | } else { 20 | res.add(cur); 21 | } 22 | } 23 | 24 | FileWriter fileWriter = new FileWriter(new File("decode.out")); 25 | fileWriter.flush(); 26 | 27 | for (int i = 0; i < res.size(); i++) { 28 | fileWriter.write(res.get(i)); 29 | } 30 | fileWriter.flush(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /term 1/Lists, stacks, queues/B.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.io.FileWriter; 3 | import java.io.IOException; 4 | import java.util.Scanner; 5 | import java.util.Stack; 6 | 7 | public class B { 8 | 9 | static Boolean psp(String s) { 10 | Stack stack = new Stack(); 11 | for (int i = 0; i < s.length(); i++) { 12 | Character cur = s.charAt(i); 13 | if (stack.empty()) { 14 | stack.push(cur); 15 | } else { 16 | if (stack.peek() == '(' && cur == ')' || stack.peek() == '{' && cur == '}' || stack.peek() == '[' && cur == ']') { 17 | stack.pop(); 18 | } else { 19 | stack.push(cur); 20 | } 21 | } 22 | } 23 | if (stack.empty()) { 24 | return true; 25 | } else { 26 | return false; 27 | } 28 | } 29 | 30 | public static void main(String[] args) throws IOException { 31 | Scanner scanner = new Scanner(new File("brackets.in")); 32 | FileWriter fileWriter = new FileWriter(new File("brackets.out")); 33 | String s = scanner.nextLine(); 34 | 35 | if (psp(s)) { 36 | fileWriter.write("YES"); 37 | } else { 38 | fileWriter.write("NO"); 39 | } 40 | 41 | fileWriter.flush(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /term 1/Lists, stacks, queues/C.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.io.FileWriter; 3 | import java.io.IOException; 4 | import java.util.Scanner; 5 | import java.util.Stack; 6 | 7 | public class C { 8 | 9 | static int calc(String s) { 10 | Stack stack = new Stack(); 11 | String cur[] = s.split(" "); 12 | int res = 0, f1, f2; 13 | 14 | for (int i = 0; i < cur.length; i++) { 15 | switch (cur[i]) { 16 | case "+": 17 | f1 = stack.pop(); 18 | f2 = stack.pop(); 19 | res = f1 + f2; 20 | stack.push(res); 21 | break; 22 | case "-": 23 | f1 = stack.pop(); 24 | f2 = stack.pop(); 25 | res = f2 - f1; 26 | stack.push(res); 27 | break; 28 | case "*": 29 | f1 = stack.pop(); 30 | f2 = stack.pop(); 31 | res = f1 * f2; 32 | stack.push(res); 33 | break; 34 | default: 35 | stack.push(Integer.parseInt(cur[i])); 36 | } 37 | } 38 | 39 | res = stack.pop(); 40 | return res; 41 | } 42 | 43 | public static void main(String[] args) throws IOException { 44 | Scanner scanner = new Scanner(new File("postfix.in")); 45 | String s = scanner.nextLine(); 46 | 47 | FileWriter fileWriter = new FileWriter(new File("postfix.out")); 48 | fileWriter.write(calc(s) + ""); 49 | fileWriter.flush(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /term 1/Lists, stacks, queues/D.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.io.FileWriter; 3 | import java.io.IOException; 4 | import java.util.ArrayDeque; 5 | import java.util.Scanner; 6 | 7 | 8 | public class D { 9 | 10 | public static void main(String[] args) throws IOException { 11 | Scanner scanner = new Scanner(new File("stack-min.in")); 12 | FileWriter fileWriter = new FileWriter(new File("stack-min.out")); 13 | 14 | int n = scanner.nextInt(); 15 | ArrayDeque stack = new ArrayDeque(); 16 | 17 | for (int i = 0; i < n; i++) { 18 | int cur = scanner.nextInt(); 19 | switch (cur) { 20 | case 1: 21 | int val = scanner.nextInt(); 22 | if (stack.isEmpty()) { 23 | stack.push(val); 24 | } else { 25 | val = Integer.min(val, stack.peek()); 26 | stack.push(val); 27 | } 28 | break; 29 | case 2: 30 | stack.pop(); 31 | break; 32 | case 3: 33 | fileWriter.write(stack.peek() + "\n"); 34 | break; 35 | } 36 | } 37 | 38 | fileWriter.flush(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /term 1/Lists, stacks, queues/E.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.io.FileWriter; 3 | import java.io.IOException; 4 | import java.util.Arrays; 5 | import java.util.Scanner; 6 | 7 | public class E { 8 | static int p[] = new int[1000000]; 9 | static int max[] = new int[1000000]; 10 | static int min[] = new int[1000000]; 11 | static int size[] = new int[1000000]; 12 | 13 | 14 | static void fun(int x) { 15 | p[x] = x; 16 | size[x] = 1; 17 | max[x] = x; 18 | min[x] = x; 19 | } 20 | 21 | static int search(int x) { 22 | if (p[x] == x) { 23 | return x; 24 | } 25 | return p[x] = search(p[x]); 26 | } 27 | 28 | static void fun2(int x, int y) { 29 | x = search(x); 30 | y = search(y); 31 | if (x != y) { 32 | if (size[x] < size[y]) { 33 | int tmp = x; 34 | x = y; 35 | y = tmp; 36 | } 37 | p[y] = x; 38 | size[x] = size[x] + size[y]; 39 | if (max[x] < max[y]) { 40 | max[x] = max[y]; 41 | } else { 42 | max[y] = max[x]; 43 | } 44 | if (min[x] > min[y]) { 45 | min[x] = min[y]; 46 | } else { 47 | min[y] = min[x]; 48 | } 49 | } 50 | } 51 | 52 | static String show(int x) { 53 | x = search(x); 54 | return (min[x] + " " + max[x] + " " + size[x]); 55 | } 56 | 57 | public static void main(String[] args) throws IOException { 58 | Scanner scanner = new Scanner(new File("dsu.in")); 59 | FileWriter fileWriter = new FileWriter(new File("dsu.out")); 60 | int n = Integer.parseInt(scanner.nextLine()); 61 | for (int i = 1; i <= n; i++) { 62 | fun(i); 63 | } 64 | while (scanner.hasNextLine()) { 65 | String s[] = scanner.nextLine().split(" "); 66 | switch (s[0]) { 67 | case "union": 68 | fun2(Integer.parseInt(s[1]), Integer.parseInt(s[2])); 69 | break; 70 | case "get": 71 | fileWriter.write(show(Integer.parseInt(s[1])) + "\n"); 72 | break; 73 | } 74 | } 75 | fileWriter.flush(); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /term 1/Lists, stacks, queues/F.java: -------------------------------------------------------------------------------- 1 | import javafx.util.Pair; 2 | 3 | import java.io.File; 4 | import java.io.FileWriter; 5 | import java.io.IOException; 6 | import java.util.Arrays; 7 | import java.util.Scanner; 8 | 9 | public class F { 10 | 11 | static class vStroi{ 12 | int sleva; 13 | int sprava; 14 | } 15 | static vStroi a[]=new vStroi[75001]; 16 | 17 | static void GOLEFT(int i,int j){ 18 | a[i].sleva=a[j].sleva; 19 | if (a[i].sleva!=0){ 20 | a[a[i].sleva].sprava=i; 21 | } 22 | a[j].sleva=i; 23 | a[i].sprava=j; 24 | } 25 | static void GORIGHT(int i,int j){ 26 | a[i].sprava=a[j].sprava; 27 | if (a[i].sprava!=0){ 28 | a[a[i].sprava].sleva=i; 29 | } 30 | a[j].sprava=i; 31 | a[i].sleva=j; 32 | } 33 | static void LEAVEMEALONE(int i){ 34 | if (a[i].sleva!=0){ 35 | a[a[i].sleva].sprava=a[i].sprava; 36 | } 37 | if (a[i].sprava!=0){ 38 | a[a[i].sprava].sleva=a[i].sleva; 39 | } 40 | a[i].sleva=0; 41 | a[i].sprava=0; 42 | } 43 | static String TELLME(int i){ 44 | return (a[i].sleva+" "+a[i].sprava); 45 | } 46 | 47 | public static void main(String[] args) throws IOException { 48 | Scanner scanner = new Scanner(new File("formation.in")); 49 | FileWriter fileWriter=new FileWriter(new File("formation.out")); 50 | int n=scanner.nextInt(); 51 | int m=scanner.nextInt(); 52 | for (int i=0;i<=n;i++){ 53 | a[i]=new vStroi(); 54 | a[i].sleva=0; 55 | a[i].sprava=0; 56 | } 57 | for (int o=0;o ochred = new ArrayDeque<>(); 17 | int len = 0; 18 | 19 | for (int i = 0; i < n; i++) { 20 | int hour = scanner.nextInt(); 21 | int min = scanner.nextInt(); 22 | int st = scanner.nextInt(); 23 | int timein = hour * 60 + min; 24 | int timeout = 0; 25 | if (len == 0) { 26 | timeout = timein + 20; 27 | ochred.addLast(timeout); 28 | len++; 29 | fileWriter.write(timeout / 60 + " " + timeout % 60 + "\n"); 30 | continue; 31 | } 32 | int f = ochred.getFirst(); 33 | if (timein >= f) { 34 | while (len != 0 && timein >= ochred.getFirst()) { 35 | ochred.removeFirst(); 36 | len--; 37 | } 38 | } 39 | if (len == 0) { 40 | timeout = timein + 20; 41 | ochred.addLast(timeout); 42 | len++; 43 | fileWriter.write(timeout / 60 + " " + timeout % 60 + "\n"); 44 | continue; 45 | } 46 | if (st < len) { 47 | fileWriter.write(hour + " " + min + " " + "\n"); 48 | continue; 49 | } 50 | int l = ochred.peekLast(); 51 | timeout = l + 20; 52 | len++; 53 | ochred.addLast(timeout); 54 | fileWriter.write(timeout / 60 + " " + timeout % 60 + "\n"); 55 | } 56 | 57 | fileWriter.flush(); 58 | } 59 | } -------------------------------------------------------------------------------- /term 1/Lists, stacks, queues/I.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.io.FileWriter; 3 | import java.io.IOException; 4 | import java.util.Scanner; 5 | 6 | 7 | public class I { 8 | 9 | 10 | public static void main(String[] args) throws IOException { 11 | Scanner scanner = new Scanner(new File("hemoglobin.in")); 12 | FileWriter fileWriter = new FileWriter(new File("hemoglobin.out")); 13 | 14 | int n = scanner.nextInt(); 15 | int a[] = new int[n]; 16 | int kol = 0; 17 | 18 | for (int i = 0; i < n; i++) { 19 | String s = scanner.next(); 20 | switch (s.charAt(0)) { 21 | case '+': 22 | kol++; 23 | a[kol] = a[kol - 1] + Integer.parseInt(s.substring(1)); 24 | break; 25 | case '-': 26 | fileWriter.write((a[kol] - a[kol - 1]) + "\n"); 27 | a[kol] = 0; 28 | kol--; 29 | break; 30 | case '?': 31 | int k = Integer.parseInt(s.substring(1)); 32 | int sum = a[kol] - a[kol - k]; 33 | fileWriter.write(sum + "\n"); 34 | break; 35 | } 36 | } 37 | 38 | fileWriter.flush(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /term 1/Lists, stacks, queues/J.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.io.FileWriter; 3 | import java.io.IOException; 4 | import java.util.ArrayDeque; 5 | import java.util.Scanner; 6 | 7 | 8 | public class J { 9 | 10 | 11 | public static void main(String[] args) throws IOException { 12 | Scanner scanner = new Scanner(new File("bureaucracy.in")); 13 | FileWriter fileWriter = new FileWriter(new File("bureaucracy.out")); 14 | 15 | int n = scanner.nextInt(); 16 | long m = scanner.nextInt(); 17 | long obhod = m / n; 18 | long sum = 0; 19 | int count = n; 20 | 21 | ArrayDeque ochered = new ArrayDeque<>(); 22 | 23 | for (int i = 0; i < n; i++) { 24 | long cur = scanner.nextInt(); 25 | if (cur <= obhod) { 26 | count--; 27 | m = m - cur; 28 | } else { 29 | cur = cur - obhod; 30 | m = m - obhod; 31 | ochered.addLast(cur); 32 | sum = sum + cur; 33 | } 34 | } 35 | 36 | if (sum <= m) { 37 | fileWriter.write(-1 + ""); 38 | } else { 39 | while (m != 0) { 40 | long cur = ochered.removeFirst(); 41 | m--; 42 | cur--; 43 | if (cur > 0) { 44 | ochered.addLast(cur); 45 | } else { 46 | count--; 47 | } 48 | } 49 | fileWriter.write(count + "\n"); 50 | while (!ochered.isEmpty()) { 51 | fileWriter.write(ochered.removeFirst() + " "); 52 | } 53 | } 54 | 55 | fileWriter.flush(); 56 | } 57 | } -------------------------------------------------------------------------------- /term 1/Lists, stacks, queues/K.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.io.FileWriter; 3 | import java.io.IOException; 4 | import java.util.ArrayDeque; 5 | import java.util.Scanner; 6 | 7 | public class K { 8 | 9 | public static void main(String[] args) throws IOException { 10 | Scanner scanner = new Scanner(new File("kenobi.in")); 11 | FileWriter fileWriter = new FileWriter(new File("kenobi.out")); 12 | 13 | int n = scanner.nextInt(); 14 | ArrayDeque forobi = new ArrayDeque<>(); 15 | ArrayDeque formum = new ArrayDeque<>(); 16 | int count = 0; 17 | 18 | for (int i = 0; i < n; i++) { 19 | String s = scanner.next(); 20 | switch (s) { 21 | case "add": 22 | count++; 23 | int val = scanner.nextInt(); 24 | forobi.addLast(val); 25 | if (count % 2 == 0) { 26 | int tmp = forobi.removeFirst(); 27 | formum.addLast(tmp); 28 | } 29 | break; 30 | case "take": 31 | if (count != 0) { 32 | count--; 33 | forobi.pollLast(); 34 | if (count % 2 == 1) { 35 | int tmp = formum.removeLast(); 36 | forobi.addFirst(tmp); 37 | } 38 | } 39 | break; 40 | case "mum!": 41 | ArrayDeque tmp = formum; 42 | formum = forobi; 43 | forobi = tmp; 44 | if (count % 2 == 1) { 45 | int tmp2 = formum.removeLast(); 46 | forobi.addFirst(tmp2); 47 | } 48 | break; 49 | } 50 | } 51 | 52 | fileWriter.write(count + "\n"); 53 | 54 | while (!formum.isEmpty()) { 55 | fileWriter.write(formum.removeFirst() + " "); 56 | } 57 | while (!forobi.isEmpty()) { 58 | fileWriter.write(forobi.removeFirst() + " "); 59 | } 60 | fileWriter.flush(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /term 2/Greed and bust/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int K, n; 8 | vector mincobblers; 9 | 10 | 11 | int main() { 12 | freopen("cobbler.in", "r", stdin); 13 | freopen("cobbler.out", "w", stdout); 14 | 15 | scanf("%d %d", &K, &n); 16 | for (int i = 0; i < n; i++) { 17 | int x; 18 | scanf("%d", &x); 19 | mincobblers.push_back(x); 20 | } 21 | 22 | sort(mincobblers.begin(), mincobblers.end()); 23 | 24 | int work = mincobblers[0]; 25 | int count = 0; 26 | for (int i = 0; i < n; i++) { 27 | if (work <= K) { 28 | count++; 29 | work += mincobblers[count]; 30 | } else break; 31 | } 32 | 33 | printf("%d", count); 34 | 35 | return 0; 36 | } -------------------------------------------------------------------------------- /term 2/Greed and bust/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int n; 8 | vector> time; 9 | 10 | bool comp(pair& x, pair& y) { 11 | return (x.second < y.second); 12 | } 13 | 14 | int main() { 15 | freopen("request.in", "r", stdin); 16 | freopen("request.out", "w", stdout); 17 | 18 | scanf("%d", &n); 19 | for (int i = 0; i < n; i++) { 20 | int s, f; 21 | scanf("%d %d", &s, &f); 22 | time.emplace_back(make_pair(s, f)); 23 | } 24 | 25 | sort(time.begin(), time.end(), comp); 26 | 27 | int count = 1; 28 | int curtime = time[0].second; 29 | int cur = 0; 30 | while (cur < n) { 31 | if (time[cur].first < curtime) { 32 | cur++; 33 | } else { 34 | count++; 35 | curtime = time[cur].second; 36 | } 37 | } 38 | 39 | printf("%d", count); 40 | 41 | return 0; 42 | } -------------------------------------------------------------------------------- /term 2/Greed and bust/E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int n, s; 8 | 9 | struct Apple { 10 | int a; 11 | int b; 12 | int number; 13 | }; 14 | 15 | vector plusa; 16 | vector minusb; 17 | 18 | bool pluscompare(Apple& a, Apple& b) { 19 | return (a.a < b.a); 20 | } 21 | 22 | bool minuscompare(Apple& a, Apple& b) { 23 | return (a.b > b.b); 24 | } 25 | 26 | int main() { 27 | freopen("apples.in", "r", stdin); 28 | freopen("apples.out", "w", stdout); 29 | 30 | scanf("%d %d", &n, &s); 31 | for (int i = 1; i <= n; i++) { 32 | int a, b; 33 | scanf("%d %d", &a, &b); 34 | Apple x; 35 | x.a = a; 36 | x.b = b; 37 | x.number = i; 38 | if (b - a > 0) 39 | plusa.push_back(x); 40 | else 41 | minusb.push_back(x); 42 | } 43 | 44 | sort(plusa.begin(), plusa.end(), pluscompare); 45 | sort(minusb.begin(), minusb.end(), minuscompare); 46 | 47 | vector ressequence; 48 | for (int i = 0; i < plusa.size(); i++) { 49 | if (s - plusa[i].a <= 0) { 50 | printf("-1"); 51 | return 0; 52 | } else { 53 | s += (plusa[i].b - plusa[i].a); 54 | ressequence.push_back(plusa[i].number); 55 | } 56 | } 57 | 58 | for (int i = 0; i < minusb.size(); i++) { 59 | if (s - minusb[i].a <= 0) { 60 | printf("-1"); 61 | return 0; 62 | } else { 63 | s += (minusb[i].b - minusb[i].a); 64 | ressequence.push_back(minusb[i].number); 65 | } 66 | } 67 | 68 | for (int i = 0; i < ressequence.size(); i++) { 69 | printf("%d ", ressequence[i]); 70 | } 71 | 72 | return 0; 73 | } -------------------------------------------------------------------------------- /term 2/Greed and bust/G.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int n, r, * a; 7 | 8 | void swap(int* a, int i, int j) { 9 | int s = a[i]; 10 | a[i] = a[j]; 11 | a[j] = s; 12 | } 13 | 14 | bool nextPermutation(int* a, int n) { 15 | int j = n - 2; 16 | while (j != -1 && a[j] >= a[j + 1]) 17 | j--; 18 | 19 | if (j == -1)return false; 20 | int k = n - 1; 21 | while (a[j] >= a[k]) 22 | k--; 23 | 24 | swap(a, j, k); 25 | int l = j + 1; 26 | int r = n - 1; 27 | while (l < r) { 28 | swap(a, l++, r--); 29 | } 30 | 31 | return true; 32 | }; 33 | 34 | bool isBeautiful(int number) { 35 | if (number == 0) 36 | return true; 37 | 38 | int divcounter = 0; 39 | for (int i = 1; i <= sqrt(number); i++) { 40 | if (number % i == 0) { 41 | divcounter++; 42 | if (i != sqrt(number))divcounter++; 43 | } 44 | } 45 | 46 | return divcounter % 3 == 0; 47 | } 48 | 49 | int sum() { 50 | int sum = 0; 51 | for (int i = 0; i < n - 1; i++) { 52 | sum += a[i] * a[i + 1]; 53 | } 54 | sum = sum % r; 55 | return sum; 56 | } 57 | 58 | int main() { 59 | freopen("beautiful.in", "r", stdin); 60 | freopen("beautiful.out", "w", stdout); 61 | 62 | scanf("%d %d", &n, &r); 63 | a = new int[n]; 64 | for (int i = 0; i < n; i++) 65 | a[i] = i + 1; 66 | 67 | int counter = 0; 68 | int number = sum(); 69 | if (isBeautiful(number)) 70 | counter++; 71 | 72 | while (nextPermutation(a, n)) { 73 | number = sum(); 74 | if (isBeautiful(number))counter++; 75 | } 76 | 77 | printf("%d", counter); 78 | 79 | return 0; 80 | } -------------------------------------------------------------------------------- /term 2/Greed and bust/H.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int n; 7 | vector vectors; 8 | 9 | int main() { 10 | freopen("vectors2.in", "r", stdin); 11 | freopen("vectors2.out", "w", stdout); 12 | 13 | scanf("%d", &n); 14 | 15 | int m = 1 << n; 16 | for (int i = 0; i < m; i++) { 17 | string s; 18 | int pref = 0; 19 | int cur = i; 20 | bool hasone = false; 21 | for (int j = 0; j < n; j++) { 22 | if (cur % 2 == 1 && pref == 1) { 23 | hasone = true; 24 | break; 25 | } 26 | s = to_string(cur % 2) + s; 27 | if (cur % 2 == 1) { pref = 1; } 28 | else { pref = 0; } 29 | cur = cur / 2; 30 | } 31 | 32 | if (!hasone) { 33 | vectors.push_back(s); 34 | } 35 | } 36 | 37 | int count = vectors.size(); 38 | printf("%d\n", count); 39 | 40 | for (int i = 0; i < count; i++) { 41 | printf("%s\n", vectors[i]); 42 | } 43 | 44 | return 0; 45 | } -------------------------------------------------------------------------------- /term 2/Search tree/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | struct Node { 6 | long long x; 7 | int y; 8 | Node* l; 9 | Node* r; 10 | 11 | Node(long long nx) { 12 | x = nx; 13 | y = rand() * rand(); 14 | l = nullptr; 15 | r = nullptr; 16 | } 17 | }; 18 | 19 | void split(Node* t, Node*& l, Node*& r, long long x) { 20 | if (t == nullptr) { 21 | l = nullptr; 22 | r = nullptr; 23 | return; 24 | } 25 | 26 | if (t->x < x) { 27 | split(t->r, t->r, r, x); 28 | l = t; 29 | } else { 30 | split(t->l, l, t->l, x); 31 | r = t; 32 | } 33 | }; 34 | 35 | void merge(Node*& t, Node* l, Node* r) { 36 | if (l == nullptr || r == nullptr) { 37 | if (r == nullptr) t = l; 38 | else t = r; 39 | return; 40 | } 41 | 42 | if (l->y > r->y) { 43 | merge(l->r, l->r, r); 44 | t = l; 45 | } else { 46 | merge(r->l, l, r->l); 47 | t = r; 48 | } 49 | } 50 | 51 | void insert(Node*& t, Node* v) { 52 | if (t == nullptr) { 53 | t = v; 54 | return; 55 | } 56 | 57 | if (t->y > v->y) { 58 | if (v->x < t->x) 59 | insert(t->l, v); 60 | else insert(t->r, v); 61 | return; 62 | } 63 | 64 | split(t, v->l, v->r, v->x); 65 | t = v; 66 | } 67 | 68 | void remove(Node*& t, long long x) { 69 | if (t == nullptr) return; 70 | 71 | if (x < t->x) { 72 | remove(t->l, x); 73 | } else if (x > t->x) { 74 | remove(t->r, x); 75 | } else { 76 | merge(t, t->l, t->r); 77 | } 78 | } 79 | 80 | bool exists(Node*& t, long long x) { 81 | if (t == nullptr) return false; 82 | 83 | if (x == t->x) return true; 84 | 85 | if (x < t->x) { 86 | return exists(t->l, x); 87 | } else return exists(t->r, x); 88 | } 89 | 90 | 91 | Node* prev(Node*& t, long long x) { 92 | Node* cur = t, * succ = nullptr; 93 | 94 | while (cur != nullptr) { 95 | if (cur->x < x) { 96 | succ = cur; 97 | cur = cur->r; 98 | } else { 99 | cur = cur->l; 100 | } 101 | } 102 | 103 | return succ; 104 | } 105 | 106 | Node* next(Node*& t, long long x) { 107 | Node* cur = t, * succ = nullptr; 108 | 109 | while (cur != nullptr) { 110 | if (cur->x > x) { 111 | succ = cur; 112 | cur = cur->l; 113 | } else { 114 | cur = cur->r; 115 | } 116 | } 117 | return succ; 118 | } 119 | 120 | int main() { 121 | string s; 122 | long long x; 123 | Node* v; 124 | Node* t = nullptr; 125 | 126 | while (cin >> s >> x) { 127 | if (s[0] == 'i') { 128 | v = new Node(x); 129 | if (!exists(t, x))insert(t, v); 130 | continue; 131 | } 132 | if (s[0] == 'e') { 133 | if (exists(t, x))cout << "true"; 134 | else cout << "false"; 135 | cout << "\n"; 136 | continue; 137 | } 138 | if (s[0] == 'd') { 139 | if (exists(t, x))remove(t, x); 140 | continue; 141 | } 142 | if (s[0] == 'n') { 143 | v = next(t, x); 144 | if (v == nullptr) cout << "none"; 145 | else cout << v->x; 146 | cout << "\n"; 147 | continue; 148 | } 149 | if (s[0] == 'p') { 150 | v = prev(t, x); 151 | if (v == nullptr) cout << "none"; 152 | else cout << v->x; 153 | cout << "\n"; 154 | } 155 | } 156 | 157 | return 0; 158 | } -------------------------------------------------------------------------------- /term 2/Search tree/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int n; 8 | vector x, y, num; 9 | 10 | struct Node { 11 | int x; 12 | int y; 13 | int number; 14 | Node* l; 15 | Node* r; 16 | Node* p; 17 | 18 | Node(int xx, int yy, int num) { 19 | x = xx; 20 | y = yy; 21 | number = num; 22 | l = nullptr; 23 | r = nullptr; 24 | p = nullptr; 25 | } 26 | }; 27 | 28 | Node* t; 29 | vector xyn; 30 | vector originals; 31 | 32 | bool compare(Node*& a, Node*& b) { 33 | return a->x < b->x; 34 | } 35 | 36 | void printNum(Node* t, int num) { 37 | if (t == nullptr) 38 | return; 39 | 40 | if (t->number == num) { 41 | if (t->p == nullptr) cout << 0; 42 | else cout << t->p->number; 43 | cout << " "; 44 | if (t->l == nullptr) cout << 0; 45 | else cout << t->l->number; 46 | cout << " "; 47 | if (t->r == nullptr) cout << 0; 48 | else cout << t->r->number; 49 | cout << "\n"; 50 | } else { 51 | printNum(t->l, num); 52 | printNum(t->r, num); 53 | } 54 | } 55 | 56 | void build(Node*& t) { 57 | t = xyn[0]; 58 | Node* last = t; 59 | 60 | for (int i = 1; i < n; i++) { 61 | if (last->y < y[i]) { 62 | last->r = xyn[i]; 63 | last->r->p = last; 64 | last = last->r; 65 | } else { 66 | Node* cur = last; 67 | while (cur->p != nullptr && cur->y > xyn[i]->y) 68 | cur = cur->p; 69 | if (cur->y > xyn[i]->y) { 70 | last = xyn[i]; 71 | last->l = cur; 72 | cur->p = last; 73 | } else { 74 | last = xyn[i]; 75 | last->l = cur->r; 76 | cur->r->p = last; 77 | last->p = cur; 78 | cur->r = last; 79 | } 80 | } 81 | } 82 | 83 | while (last->p != nullptr) 84 | last = last->p; 85 | t = last; 86 | } 87 | 88 | int main() { 89 | cin >> n; 90 | int a, b; 91 | 92 | for (int i = 0; i < n; i++) { 93 | cin >> a >> b; 94 | Node* e = new Node(a, b, i + 1); 95 | xyn.push_back(e); 96 | originals.push_back(e); 97 | } 98 | 99 | sort(xyn.begin(), xyn.end(), compare); 100 | 101 | for (int i = 0; i < n; i++) { 102 | x.push_back(xyn[i]->x); 103 | y.push_back(xyn[i]->y); 104 | num.push_back(xyn[i]->y); 105 | } 106 | 107 | build(t); 108 | 109 | cout << "YES\n"; 110 | for (int i = 0; i < n; i++) { 111 | Node* cur = originals[i]; 112 | if (cur->p == nullptr) cout << 0; 113 | else cout << cur->p->number; 114 | cout << " "; 115 | if (cur->l == nullptr) cout << 0; 116 | else cout << cur->l->number; 117 | cout << " "; 118 | if (cur->r == nullptr) cout << 0; 119 | else cout << cur->r->number; 120 | cout << "\n"; 121 | } 122 | 123 | return 0; 124 | } -------------------------------------------------------------------------------- /term 2/Search tree/D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct Node { 6 | int size; 7 | int p; 8 | int data; 9 | bool zero; 10 | 11 | Node* left, * right; 12 | 13 | Node(int data = 0, bool isZero = true) { 14 | this->data = data; 15 | this->zero = isZero; 16 | p = rand() * rand(); 17 | size = 1; 18 | left = right = nullptr; 19 | } 20 | }; 21 | 22 | struct Treap { 23 | Node* root = nullptr; 24 | int num = 0; 25 | 26 | Node* merge(Node* l, Node* r) { 27 | if (l == nullptr) return r; 28 | if (r == nullptr) return l; 29 | 30 | if (l->p > r->p) { 31 | l->right = merge(l->right, r); 32 | updateSize(l); 33 | updateZero(l); 34 | return l; 35 | } else { 36 | r->left = merge(l, r->left); 37 | updateSize(r); 38 | updateZero(r); 39 | return r; 40 | } 41 | } 42 | 43 | void split(Node* t, int key, Node*& l, Node*& r) { 44 | if (t == nullptr) { 45 | l = r = nullptr; 46 | return; 47 | } 48 | if (getSize(t->left) < key) { 49 | split(t->right, key - getSize(t->left) - 1, t->right, r); 50 | l = t; 51 | } else { 52 | split(t->left, key, l, t->left); 53 | r = t; 54 | } 55 | updateSize(t); 56 | updateZero(t); 57 | } 58 | 59 | int getSize(Node* t) { 60 | if (t == nullptr)return 0; 61 | else return t->size; 62 | } 63 | 64 | void updateSize(Node* t) { 65 | t->size = getSize(t->left) + getSize(t->right) + 1; 66 | } 67 | 68 | void updateZero(Node* t) { 69 | t->zero = getZero(t->left) || getZero(t->right) || (t->data == 0); 70 | } 71 | 72 | bool getZero(Node* t) { 73 | if (t == nullptr)return false; 74 | return t->zero; 75 | } 76 | 77 | 78 | Node* searchNull(Node* t, int& ind) { 79 | Node* cur = t; 80 | ind = getSize(cur->left); 81 | 82 | while (getZero(cur)) { 83 | if (cur->left != nullptr && getZero(cur->left)) { 84 | cur = cur->left; 85 | ind = ind - getSize(cur->right) - 1; 86 | } else if (getData(cur) == 0) { 87 | break; 88 | } else { 89 | cur = cur->right; 90 | ind += getSize(cur->left); 91 | ind++; 92 | } 93 | } 94 | 95 | return cur; 96 | } 97 | 98 | int getData(Node* t) { 99 | if (t == nullptr)return -1; 100 | return t->data; 101 | } 102 | 103 | void toArray(Node* node, std::vector& a) { 104 | if (node) { 105 | toArray(node->left, a); 106 | a.push_back(getData(node)); 107 | toArray(node->right, a); 108 | } 109 | } 110 | 111 | Node* remove(Node* r, int key) { 112 | Node* t1, * t2, * t3; 113 | split(r, key, t1, t2); 114 | split(t2, 1, t2, t3); 115 | r = merge(t1, t3); 116 | delete (t2); 117 | return r; 118 | } 119 | 120 | void build(int n) { 121 | for (int i = 0; i < n; ++i) { 122 | root = merge(new Node, root); 123 | } 124 | } 125 | 126 | 127 | void insert(int ind) { 128 | Node* l, * r, * z; 129 | int i; 130 | 131 | split(root, ind, l, r); 132 | z = searchNull(r, i); 133 | if (z != nullptr && z->data == 0) { 134 | r = remove(r, i); 135 | } 136 | 137 | root = merge(merge(l, new Node(++num, false)), r); 138 | } 139 | 140 | }; 141 | 142 | int main() { 143 | int n, j, m; 144 | scanf("%d %d", &n, &m); 145 | 146 | Treap tree; 147 | tree.build(m); 148 | 149 | for (int i = 0; i < n; ++i) { 150 | scanf("%d", &j); 151 | tree.insert(j - 1); 152 | } 153 | 154 | std::vector ans; 155 | tree.toArray(tree.root, ans); 156 | while (!ans.empty() && ans.back() == 0) 157 | ans.pop_back(); 158 | 159 | printf("%d\n", ans.size()); 160 | for (int i = 0; i < ans.size(); i++) { 161 | printf("%d ", ans[i]); 162 | } 163 | 164 | return 0; 165 | } -------------------------------------------------------------------------------- /term 2/Search tree/F.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int MIN = -1000000001; 6 | 7 | struct Node { 8 | int x; 9 | int y; 10 | int size; 11 | Node* l; 12 | Node* r; 13 | 14 | Node(int nx) { 15 | x = nx; 16 | y = rand(); 17 | l = nullptr; 18 | r = nullptr; 19 | size = 1; 20 | } 21 | }; 22 | 23 | int size(Node*& t) { 24 | return t != nullptr ? t->size : 0; 25 | } 26 | 27 | void updateSize(Node*& t) { 28 | if (t != nullptr) { 29 | t->size = 1 + size(t->l) + size(t->r); 30 | } 31 | 32 | } 33 | 34 | void split(Node* t, Node*& l, Node*& r, int x) { 35 | if (t == nullptr) { 36 | l = nullptr; 37 | r = nullptr; 38 | } else if (t->x > x) { 39 | split(t->l, l, t->l, x); 40 | r = t; 41 | } else { 42 | split(t->r, t->r, r, x); 43 | l = t; 44 | } 45 | updateSize(t); 46 | }; 47 | 48 | void merge(Node*& t, Node* l, Node* r) { 49 | if (l == nullptr || r == nullptr) { 50 | t = r ? r : l; 51 | } else if (l->y > r->y) { 52 | merge(l->r, l->r, r); 53 | t = l; 54 | } else { 55 | merge(r->l, l, r->l); 56 | t = r; 57 | } 58 | updateSize(t); 59 | } 60 | 61 | void insert(Node*& t, Node* v) { 62 | if (t == nullptr) { 63 | t = v; 64 | } else if (t->y < v->y) { 65 | split(t, v->l, v->r, v->x); 66 | t = v; 67 | } else { 68 | insert(v->x < t->x ? t->l : t->r, v); 69 | } 70 | updateSize(t); 71 | } 72 | 73 | void remove(Node*& t, int x) { 74 | if (t->x == x) 75 | merge(t, t->l, t->r); 76 | else 77 | remove(x < t->x ? t->l : t->r, x); 78 | updateSize(t); 79 | } 80 | 81 | 82 | int findKthMax(Node*& t, int k) { 83 | int leftsize = size(t->l); 84 | if (leftsize == k) { 85 | return t->x; 86 | } else if (leftsize > k) 87 | return findKthMax(t->l, k); 88 | else { 89 | k -= leftsize + 1; 90 | return findKthMax(t->r, k); 91 | } 92 | } 93 | 94 | void printTree(Node*& t) { 95 | if (t == nullptr) return; 96 | printTree(t->l); 97 | printf("(%d,%d)\t", t->x, t->size); 98 | printTree(t->r); 99 | } 100 | 101 | int main() { 102 | int s; 103 | int x; 104 | int n; 105 | int length = 0; 106 | Node* v; 107 | Node* t = nullptr; 108 | scanf("%d", &n); 109 | 110 | for (int i = 0; i < n; i++) { 111 | scanf("%d %d", &s, &x); 112 | if (s == 1) { 113 | v = new Node(x); 114 | insert(t, v); 115 | length++; 116 | continue; 117 | } 118 | if (s == 0) { 119 | printf("%d\n", findKthMax(t, length - x)); 120 | continue; 121 | } 122 | if (s == -1) { 123 | remove(t, x); 124 | length--; 125 | } 126 | } 127 | 128 | return 0; 129 | } -------------------------------------------------------------------------------- /term 2/Search tree/G.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | struct Node { 7 | int y; 8 | int size; 9 | int x; 10 | 11 | Node* l; 12 | Node* r; 13 | }; 14 | 15 | Node* newNode(int value) { 16 | Node* res = new Node; 17 | res->y = rand() * rand(); 18 | res->size = 1; 19 | res->x = value; 20 | res->l = res->r = nullptr; 21 | return res; 22 | } 23 | 24 | int getSize(Node* t) { 25 | if (t == nullptr) 26 | return 0; 27 | return t->size; 28 | } 29 | 30 | void updateSize(Node* t) { 31 | if (t == nullptr) return;; 32 | t->size = 1 + getSize(t->l) + getSize(t->r); 33 | } 34 | 35 | Node* merge(Node* t1, Node* t2) { 36 | if (t1 == nullptr) { 37 | return t2; 38 | } 39 | 40 | if (t2 == nullptr) { 41 | return t1; 42 | } 43 | 44 | if (t1->y > t2->y) { 45 | t1->r = merge(t1->r, t2); 46 | updateSize(t1); 47 | return t1; 48 | } else { 49 | t2->l = merge(t1, t2->l); 50 | updateSize(t2); 51 | return t2; 52 | } 53 | } 54 | 55 | void split(Node* t, int x, Node*& t1, Node*& t2) { 56 | if (t == nullptr) { 57 | t1 = t2 = nullptr; 58 | return; 59 | } 60 | 61 | if (getSize(t->l) < x) { 62 | split(t->r, x - getSize(t->l) - 1, t->r, t2); 63 | t1 = t; 64 | } else { 65 | split(t->l, x, t1, t->l); 66 | t2 = t; 67 | } 68 | updateSize(t); 69 | } 70 | 71 | Node* build(const vector& v) { 72 | Node* result = nullptr; 73 | for (int i = 0; i < v.size(); ++i) { 74 | result = merge(result, newNode(v[i])); 75 | } 76 | return result; 77 | } 78 | 79 | Node* tostart(Node* t, int l, int r) { 80 | Node* t1, * t2, * t3, * t4; 81 | split(t, r + 1, t1, t2); 82 | split(t1, l, t3, t4); 83 | return merge(merge(t4, t3), t2); 84 | } 85 | 86 | 87 | void printTree(Node* t) { 88 | if (t == nullptr)return; 89 | printTree(t->l); 90 | cout << t->x << " "; 91 | printTree(t->r); 92 | } 93 | 94 | int main() { 95 | int n, m; 96 | int l, r; 97 | vector a; 98 | cin >> n; 99 | cin >> m; 100 | 101 | for (int i = 0; i < n; i++) 102 | a.push_back(i + 1); 103 | 104 | Node* t = build(a); 105 | 106 | for (int i = 0; i < m; i++) { 107 | cin >> l; 108 | cin >> r; 109 | tostart(t, l - 1, r - 1); 110 | } 111 | 112 | printTree(t); 113 | 114 | return 0; 115 | } -------------------------------------------------------------------------------- /term 2/Segment tree/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int main() { 6 | freopen("sum0.in", "r", stdin); 7 | freopen("sum0.out", "w", stdout); 8 | 9 | int n, x, y, m, z, t; 10 | cin >> n >> x >> y; 11 | 12 | int* a = new int[n]; 13 | long long* pref = new long long[n]; 14 | 15 | cin >> a[0]; 16 | pref[0] = a[0]; 17 | cin >> m >> z >> t; 18 | int* b = new int[2 * m]; 19 | int* c = new int[2 * m]; 20 | cin >> b[0]; 21 | 22 | for (int i = 1; i < n; i++) { 23 | a[i] = (x * a[i - 1] + y) % (1 << 16); 24 | pref[i] = a[i] + pref[i - 1]; 25 | } 26 | 27 | for (int i = 1; i < 2 * m; i++) { 28 | b[i] = (z * b[i - 1] + t) % (1 << 30); 29 | if (b[i] < 0) b[i] = (1 << 30) + b[i]; 30 | } 31 | 32 | for (int i = 0; i < 2 * m; i++) { 33 | c[i] = b[i] % n; 34 | } 35 | 36 | long long res = 0; 37 | for (int i = 0; i < m; i++) { 38 | int r = max(c[2 * i], c[2 * i + 1]); 39 | int l = min(c[2 * i], c[2 * i + 1]); 40 | if (l > 0) res += pref[r] - pref[l - 1]; 41 | else res += pref[r]; 42 | } 43 | 44 | cout << res; 45 | 46 | return 0; 47 | } -------------------------------------------------------------------------------- /term 2/Segment tree/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int getMiddle(int l, int r) { 6 | return l + (r - l) / 2; 7 | } 8 | 9 | void updating(long long* st, int tl, int tr, int i, long long diff, int ind) { 10 | if (i < tl || i > tr) { 11 | return; 12 | } 13 | 14 | st[ind] = st[ind] + diff; 15 | if (tr != tl) { 16 | int mid = getMiddle(tl, tr); 17 | updating(st, tl, mid, i, diff, 2 * ind + 1); 18 | updating(st, mid + 1, tr, i, diff, 2 * ind + 2); 19 | } 20 | } 21 | 22 | void update(long long* a, long long* st, int n, int i, long long new_Value) { 23 | long long diff = new_Value - a[i]; 24 | a[i] = new_Value; 25 | updating(st, 0, n - 1, i, diff, 0); 26 | } 27 | 28 | long long buildTree(long long* a, int tl, int tr, long long* st, int ind) { 29 | if (tl == tr) { 30 | st[ind] = a[tl]; 31 | return a[tl]; 32 | } 33 | 34 | int mid = getMiddle(tl, tr); 35 | st[ind] = buildTree(a, tl, mid, st, ind * 2 + 1) + buildTree(a, mid + 1, tr, st, ind * 2 + 2); 36 | 37 | return st[ind]; 38 | } 39 | 40 | long long sum(long long* st, int tl, int tr, int l, int r, int ind) { 41 | if (l <= tl && r >= tr) { 42 | return st[ind]; 43 | } 44 | 45 | if (tr < l || tl > r) { 46 | return 0; 47 | } 48 | 49 | int mid = getMiddle(tl, tr); 50 | 51 | return sum(st, tl, mid, l, r, 2 * ind + 1) + sum(st, mid + 1, tr, l, r, 2 * ind + 2); 52 | 53 | } 54 | 55 | long long* buildingTree(long long* a, int n) { 56 | long long* st = new long long[4 * n]; 57 | buildTree(a, 0, n - 1, st, 0); 58 | return st; 59 | } 60 | 61 | long long get(long long* st, int n, int l, int r) { 62 | return sum(st, 0, n - 1, l, r, 0); 63 | } 64 | 65 | 66 | int main() { 67 | freopen("rsq.in", "r", stdin); 68 | freopen("rsq.out", "w", stdout); 69 | 70 | int n; 71 | cin >> n; 72 | 73 | long long a[n]; 74 | for (int i = 0; i < n; i++) { 75 | cin >> a[i]; 76 | } 77 | 78 | long long* st = buildingTree(a, n); 79 | string s; 80 | 81 | while (cin >> s) { 82 | if (s == "sum") { 83 | int i, j; 84 | cin >> i; 85 | cin >> j; 86 | cout << get(st, n, i - 1, j - 1) << "\n"; 87 | } 88 | if (s == "set") { 89 | int i; 90 | long long x; 91 | cin >> i; 92 | cin >> x; 93 | update(a, st, n, i - 1, x); 94 | } 95 | } 96 | 97 | return 0; 98 | } -------------------------------------------------------------------------------- /term 2/Segment tree/B.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.io.FileNotFoundException; 3 | import java.io.FileWriter; 4 | import java.io.IOException; 5 | import java.util.Scanner; 6 | 7 | public class B2 { 8 | 9 | static class SegmentTree { 10 | int st[]; 11 | 12 | SegmentTree(int a[], int n) { 13 | st = new int[4 * n]; 14 | buildST(a, 0, n - 1, 0); 15 | } 16 | 17 | int getMiddle(int l, int r) { 18 | return l + (r - l) / 2; 19 | } 20 | 21 | int getSum(int ss, int se, int qs, int qe, int si) { 22 | 23 | if (qs <= ss && qe >= se) 24 | return st[si]; 25 | 26 | if (se < qs || ss > qe) 27 | return 0; 28 | 29 | int mid = getMiddle(ss, se); 30 | return getSum(ss, mid, qs, qe, 2 * si + 1) + 31 | getSum(mid + 1, se, qs, qe, 2 * si + 2); 32 | } 33 | 34 | void updateValue(int ss, int se, int i, int diff, int si) { 35 | if (i < ss || i > se) 36 | return; 37 | st[si] = st[si] + diff; 38 | if (se != ss) { 39 | int mid = getMiddle(ss, se); 40 | updateValue(ss, mid, i, diff, 2 * si + 1); 41 | updateValue(mid + 1, se, i, diff, 2 * si + 2); 42 | } 43 | } 44 | 45 | void update(int arr[], int n, int i, int new_val) { 46 | if (i < 0 || i > n - 1) { 47 | return; 48 | } 49 | int diff = new_val - arr[i]; 50 | arr[i] = new_val; 51 | updateValue(0, n - 1, i, diff, 0); 52 | } 53 | 54 | int get(int n, int qs, int qe) { 55 | if (qs < 0 || qe > n - 1 || qs > qe) { 56 | return -1; 57 | } 58 | return getSum(0, n - 1, qs, qe, 0); 59 | } 60 | 61 | int buildST(int arr[], int ss, int se, int si) { 62 | if (ss == se) { 63 | st[si] = arr[ss]; 64 | return arr[ss]; 65 | } 66 | int mid = getMiddle(ss, se); 67 | st[si] = buildST(arr, ss, mid, si * 2 + 1) + 68 | buildST(arr, mid + 1, se, si * 2 + 2); 69 | return st[si]; 70 | } 71 | } 72 | 73 | public static void main(String[] args) throws IOException { 74 | Scanner scanner = new Scanner(new File("rsq.in")); 75 | FileWriter fileWriter = new FileWriter(new File("rsq.out")); 76 | 77 | int n = scanner.nextInt(); 78 | int a[] = new int[n]; 79 | for (int i = 0; i < n; i++) a[i] = scanner.nextInt(); 80 | 81 | SegmentTree segmentTree = new SegmentTree(a, n); 82 | String s = ""; 83 | while (scanner.hasNext()) { 84 | s = scanner.next(); 85 | switch (s) { 86 | case "sum": 87 | int l = scanner.nextInt() - 1; 88 | int r = scanner.nextInt() - 1; 89 | fileWriter.write(segmentTree.get(n, l, r) + "\n"); 90 | break; 91 | case "set": 92 | int i = scanner.nextInt() - 1; 93 | int x = scanner.nextInt(); 94 | segmentTree.update(a, n, i, x); 95 | break; 96 | } 97 | } 98 | 99 | fileWriter.flush(); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /term 2/Segment tree/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int getMiddle(int l, int r) { 8 | return l + (r - l) / 2; 9 | } 10 | 11 | struct Node { 12 | long long data; 13 | long long add; 14 | long long set; 15 | long long l; 16 | long long r; 17 | bool up; 18 | 19 | Node() { 20 | data = LONG_LONG_MAX; 21 | add = 0; 22 | set = LONG_LONG_MAX; 23 | up = false; 24 | } 25 | 26 | Node(long long d, long long a, long long s, long left, long right, bool u) { 27 | data = d; 28 | add = a; 29 | set = s; 30 | l = left; 31 | r = right; 32 | up = u; 33 | } 34 | }; 35 | 36 | 37 | vector t; 38 | vector a; 39 | int n; 40 | 41 | 42 | void build(int v, int tl, int tr) { 43 | if (tl == tr) { 44 | t[v] = Node(a[tl], 0, a[tl], tl, tr, false); 45 | } else { 46 | int tm = getMiddle(tl, tr); 47 | build(v * 2, tl, tm); 48 | build(v * 2 + 1, tm + 1, tr); 49 | t[v] = Node(min(t[2 * v].data, t[2 * v + 1].data), 0, 0, tl, tr, false); 50 | t[v].set = t[v].data; 51 | } 52 | } 53 | 54 | void pushset(int v) { 55 | if (!t[v].up) 56 | return; 57 | 58 | t[v].data = t[v].set; 59 | t[v].up = false; 60 | 61 | if (t[v].l == t[v].r) 62 | return; 63 | 64 | t[v * 2].set = t[v].set; 65 | t[v * 2 + 1].set = t[v].set; 66 | 67 | t[v * 2].up = true; 68 | t[v * 2 + 1].up = true; 69 | 70 | t[v * 2].add = 0; 71 | t[v * 2 + 1].add = 0; 72 | } 73 | 74 | void push(int v) { 75 | pushset(v); 76 | if (t[v].add == 0) 77 | return; 78 | 79 | t[v].data += t[v].add; 80 | t[v].set = t[v].data; 81 | 82 | long long addi = t[v].add; 83 | t[v].add = 0; 84 | 85 | if (t[v].l == t[v].r) 86 | return; 87 | 88 | t[2 * v].add += addi; 89 | t[2 * v + 1].add += addi; 90 | } 91 | 92 | void updateset(int v, long long value, int l, int r) { 93 | if (t[v].r < l || t[v].l > r) 94 | return; 95 | 96 | if (t[v].r <= r && t[v].l >= l) { 97 | t[v].add = 0; 98 | pushset(v); 99 | 100 | t[v].set = value; 101 | t[v].up = true; 102 | 103 | return; 104 | } 105 | push(v); 106 | 107 | updateset(2 * v, value, l, r); 108 | updateset(2 * v + 1, value, l, r); 109 | 110 | t[v].data = min(t[v * 2].set + t[v * 2].add, t[v * 2 + 1].set + t[v * 2 + 1].add); 111 | t[v].set = t[v].data; 112 | } 113 | 114 | void updateadd(int v, long long value, int l, int r) { 115 | if (t[v].r < l || t[v].l > r) 116 | return; 117 | 118 | if (t[v].r <= r && t[v].l >= l) { 119 | push(v); 120 | t[v].add = value; 121 | return; 122 | } 123 | 124 | push(v); 125 | 126 | updateadd(2 * v, value, l, r); 127 | updateadd(2 * v + 1, value, l, r); 128 | 129 | t[v].data = min(t[v * 2 + 1].set + t[v * 2 + 1].add, t[v * 2].set + t[v * 2].add); 130 | t[v].set = t[v].data; 131 | } 132 | 133 | long long get(int v, int l, int r) { 134 | if (t[v].r < l || t[v].l > r) 135 | return LONG_LONG_MAX; 136 | 137 | if (t[v].r <= r && t[v].l >= l) { 138 | push(v); 139 | return t[v].data; 140 | } 141 | 142 | push(v); 143 | 144 | return min(get(v * 2, l, r), get(v * 2 + 1, l, r)); 145 | } 146 | 147 | int main() { 148 | freopen("rmq2.in", "r", stdin); 149 | freopen("rmq2.out", "w", stdout); 150 | 151 | scanf("%d ", &n); 152 | a.resize((unsigned) n); 153 | t.resize((unsigned) 4 * n); 154 | 155 | for (int i = 0; i < n; i++) { 156 | scanf("%lld", &a[i]); 157 | } 158 | 159 | build(1, 0, n - 1); 160 | char* s = new char[n + 2]; 161 | while (scanf("%s", s) != EOF) { 162 | int l, r; 163 | long long x; 164 | 165 | if (s[0] == 'm') { 166 | scanf("%d %d", &l, &r); 167 | printf("%lld\n", get(1, l - 1, r - 1)); 168 | } 169 | 170 | if (s[0] == 's') { 171 | scanf("%d %d %lld", &l, &r, &x); 172 | updateset(1, x, l - 1, r - 1); 173 | } 174 | 175 | if (s[0] == 'a') { 176 | scanf("%d %d %lld", &l, &r, &x); 177 | updateadd(1, x, l - 1, r - 1); 178 | } 179 | } 180 | 181 | return 0; 182 | } -------------------------------------------------------------------------------- /term 2/Segment tree/D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int getMiddle(int l, int r) { 7 | return l + (r - l) / 2; 8 | } 9 | 10 | 11 | struct Node { 12 | int number; 13 | int segments; 14 | int set; 15 | int l; 16 | int r; 17 | bool up; 18 | 19 | Node() { 20 | number = 1; 21 | segments = 1; 22 | set = 0; 23 | up = false; 24 | l = 0; 25 | r = 0; 26 | } 27 | 28 | Node(int n, int seg, int s, int left, int right, bool u) { 29 | number = n; 30 | segments = seg; 31 | set = s; 32 | l = left; 33 | r = right; 34 | up = u; 35 | } 36 | }; 37 | 38 | vector t; 39 | vector color; 40 | vector cord; 41 | vector delta; 42 | int n; 43 | 44 | void build(int v, int tl, int tr) { 45 | if (tl == tr) { 46 | t[v] = Node(0, 0, 0, tl, tr, false); 47 | } else { 48 | int tm = getMiddle(tl, tr); 49 | build(v * 2, tl, tm); 50 | build(v * 2 + 1, tm + 1, tr); 51 | t[v] = Node(0, 0, 0, tl, tr, false); 52 | } 53 | } 54 | 55 | void push(int v) { 56 | if (!t[v].up) 57 | return; 58 | 59 | t[v].number = t[v].set * (t[v].r - t[v].l + 1); 60 | t[v].segments = 1 * t[v].set; 61 | t[v].up = false; 62 | 63 | if (t[v].l == t[v].r) 64 | return; 65 | 66 | t[v * 2].set = t[v].set; 67 | t[v * 2 + 1].set = t[v].set; 68 | 69 | t[v * 2].up = true; 70 | t[v * 2 + 1].up = true; 71 | } 72 | 73 | bool leftisblack(int v) { 74 | push(v); 75 | 76 | if (t[v].l == t[v].r) 77 | return t[v].number == 1; 78 | 79 | return leftisblack(v * 2); 80 | } 81 | 82 | bool rightisblack(int v) { 83 | push(v); 84 | 85 | if (t[v].l == t[v].r) 86 | return t[v].number == 1; 87 | 88 | return rightisblack(v * 2 + 1); 89 | } 90 | 91 | void update(int v, int value, int l, int r) { 92 | if (t[v].r < l || t[v].l > r) 93 | return; 94 | 95 | if (t[v].r <= r && t[v].l >= l) { 96 | push(v); 97 | t[v].set = value; 98 | t[v].up = true; 99 | return; 100 | } 101 | 102 | push(v); 103 | update(v * 2, value, l, r); 104 | update(v * 2 + 1, value, l, r); 105 | 106 | bool left = rightisblack(v * 2); 107 | bool right = leftisblack(v * 2 + 1); 108 | 109 | t[v].number = t[v * 2].number + t[v * 2 + 1].number; 110 | t[v].segments = t[v * 2 + 1].segments + t[v * 2].segments; 111 | 112 | if (left && right) { 113 | t[v].segments--; 114 | } 115 | } 116 | 117 | int main() { 118 | freopen("painter.in", "r", stdin); 119 | freopen("painter.out", "w", stdout); 120 | 121 | scanf("%d", &n); 122 | color.resize((unsigned) n); 123 | cord.resize((unsigned) n); 124 | delta.resize((unsigned) n); 125 | 126 | int maxdelta = 0; 127 | int del; 128 | int maxcord = INT32_MIN; 129 | int mincord = INT32_MAX; 130 | 131 | for (int i = 0; i < n; i++) { 132 | scanf("\n%c %d %d", &color[i], &cord[i], &delta[i]); 133 | 134 | if (delta[i] > 0) delta[i]--; 135 | else delta[i]++; 136 | 137 | del = cord[i] + delta[i]; 138 | if (del > maxcord) { 139 | maxcord = del; 140 | } 141 | 142 | if (maxdelta > cord[i]) { 143 | maxdelta = cord[i]; 144 | } 145 | } 146 | 147 | int length; 148 | if (maxdelta < 0) { 149 | length = maxcord - maxdelta + 1; 150 | } else { 151 | length = maxcord + 1; 152 | } 153 | 154 | t.resize((unsigned) (4 * length)); 155 | build(1, 0, length); 156 | for (int i = 0; i < n; i++) { 157 | if (color[i] == 'W') { 158 | update(1, 0, cord[i] - maxdelta, cord[i] + delta[i] - maxdelta); 159 | printf("%d %d\n", t[1].segments, 160 | t[1].number); 161 | } 162 | 163 | if (color[i] == 'B') { 164 | update(1, 1, cord[i] - maxdelta, cord[i] + delta[i] - maxdelta); 165 | printf("%d %d\n", t[1].segments, 166 | t[1].number); 167 | } 168 | } 169 | return 0; 170 | } -------------------------------------------------------------------------------- /term 2/Segment tree/E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int r; 7 | 8 | struct Matrix2x2 { 9 | public: 10 | long long a11; 11 | long long a21; 12 | long long a12; 13 | long long a22; 14 | 15 | Matrix2x2() { 16 | a11 = 0; 17 | a12 = 0; 18 | a21 = 0; 19 | a22 = 0; 20 | } 21 | 22 | Matrix2x2(const Matrix2x2& other) { 23 | a11 = other.a11; 24 | a12 = other.a12; 25 | a21 = other.a21; 26 | a22 = other.a22; 27 | } 28 | 29 | 30 | Matrix2x2(long long a, long long b, long long c, long long d) { 31 | a11 = a; 32 | a12 = b; 33 | a21 = c; 34 | a22 = d; 35 | } 36 | 37 | Matrix2x2 operator*(const Matrix2x2& v) { 38 | Matrix2x2 res = Matrix2x2((this->a11 * v.a11 + this->a12 * v.a21) % r, 39 | (this->a11 * v.a12 + this->a12 * v.a22) % r, 40 | (this->a21 * v.a11 + this->a22 * v.a21) % r, 41 | (this->a21 * v.a12 + this->a22 * v.a22) % r); 42 | return res; 43 | } 44 | }; 45 | 46 | int n, m; 47 | 48 | int getMiddle(int l, int r) { 49 | return l + (r - l) / 2; 50 | } 51 | 52 | 53 | vector t; 54 | vector a; 55 | 56 | void build(int v, int tl, int tr) { 57 | if (tl == tr) { 58 | t[v] = a[tl]; 59 | } else { 60 | int tm = getMiddle(tl, tr); 61 | build(v * 2, tl, tm); 62 | build(v * 2 + 1, tm + 1, tr); 63 | t[v] = t[v * 2] * t[v * 2 + 1]; 64 | } 65 | } 66 | 67 | Matrix2x2 get(int v, int tl, int tr, int l, int r) { 68 | if (tr < l || tl > r) return Matrix2x2(1, 0, 0, 1); 69 | if (tr <= r && tl >= l) return t[v]; 70 | int tm = getMiddle(tl, tr); 71 | Matrix2x2 a = get(2 * v, tl, tm, l, r); 72 | Matrix2x2 b = get(2 * v + 1, tm + 1, tr, l, r); 73 | return a * b; 74 | } 75 | 76 | int main() { 77 | freopen("crypto.in", "r", stdin); 78 | freopen("crypto.out", "w", stdout); 79 | 80 | scanf("%d %d %d", &r, &n, &m); 81 | a.resize((unsigned) n); 82 | t.resize((unsigned) 4 * n); 83 | 84 | for (int i = 0; i < n; i++) { 85 | long long a11, a12, a21, a22; 86 | scanf("%lld %lld %lld %lld", &a11, &a12, &a21, &a22); 87 | a[i] = Matrix2x2(a11, a12, a21, a22); 88 | 89 | } 90 | 91 | build(1, 0, n - 1); 92 | for (int i = 0; i < m; i++) { 93 | int l, r; 94 | scanf("%d %d", &l, &r); 95 | Matrix2x2 res = get(1, 0, n - 1, l - 1, r - 1); 96 | printf("%lld %lld\n%lld %lld\n", res.a11, res.a12, res.a21, res.a22); 97 | } 98 | 99 | return 0; 100 | } -------------------------------------------------------------------------------- /term 2/Segment tree/F.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int a[100001]; 5 | int st[100001][17]; 6 | int n, m; 7 | 8 | void swap(int& a, int& b) { 9 | int tmp; 10 | if (a > b) { 11 | tmp = a; 12 | a = b; 13 | b = tmp; 14 | } 15 | } 16 | 17 | void ST() { 18 | for (int i = 1; i <= n; i++) 19 | st[i][0] = i; 20 | 21 | for (int j = 1; (1 << j) <= n; j++) { 22 | for (int i = 1; i + (1 << j) - 1 <= n; i++) { 23 | if (a[st[i][j - 1]] < a[st[i + (1 << (j - 1))][j - 1]]) 24 | st[i][j] = st[i][j - 1]; 25 | else 26 | st[i][j] = st[i + (1 << (j - 1))][j - 1]; 27 | } 28 | } 29 | } 30 | 31 | int getMin(int l, int r) { 32 | int k = (int) (log(1.0 * r - l + 1) / log(2.0)); 33 | int res = st[l][k]; 34 | 35 | if (a[st[r - (1 << k) + 1][k]] < a[res]) 36 | res = st[r - (1 << k) + 1][k]; 37 | 38 | return res; 39 | } 40 | 41 | int main() { 42 | freopen("sparse.in", "r", stdin); 43 | freopen("sparse.out", "w", stdout); 44 | 45 | int ans = 0, u, v; 46 | scanf("%d %d %d %d %d", &n, &m, &a[1], &u, &v); 47 | 48 | for (int i = 2; i <= n; i++) { 49 | a[i] = (23 * a[i - 1] + 21563) % 16714589; 50 | } 51 | 52 | ST(); 53 | for (int i = 1; i <= m; i++) { 54 | int uu = u; 55 | int vv = v; 56 | swap(uu, vv); 57 | ans = a[getMin(uu, vv)]; 58 | if (i < m) { 59 | u = ((17 * u + 751 + ans + 2 * i) % n) + 1; 60 | v = ((13 * v + 593 + ans + 5 * i) % n) + 1; 61 | } 62 | } 63 | 64 | printf("%d %d %d", u, v, ans); 65 | 66 | return 0; 67 | } -------------------------------------------------------------------------------- /term 2/Segment tree/H.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int minn(int a, int b) { 8 | if (a < b) 9 | return a; 10 | return b; 11 | } 12 | 13 | struct cord { 14 | int l; 15 | int r; 16 | int x; 17 | int id; 18 | 19 | cord() {}; 20 | 21 | }; 22 | 23 | bool compare(cord a, cord b) { 24 | return ((a.x > b.x) || ((a.x == b.x) && (a.id < b.id))); 25 | } 26 | 27 | int get(int* dsu, int v) { 28 | if (dsu[v] == v) 29 | return v; 30 | dsu[v] = get(dsu, dsu[v]); 31 | return dsu[v]; 32 | } 33 | 34 | int main() { 35 | freopen("rmq.in", "r", stdin); 36 | freopen("rmq.out", "w", stdout); 37 | 38 | int n, q; 39 | scanf("%d%d", &n, &q); 40 | 41 | int* dsu = new int[n + 1]; 42 | int l, r, x; 43 | int* ans = new int[n]; 44 | int* lg = new int[n + 1]; 45 | int** table = new int* [n]; 46 | lg[1] = 0; 47 | 48 | if (n > 1) 49 | lg[2] = 1; 50 | 51 | for (int i = 3; i <= n; i++) 52 | if (i & (i - 1)) 53 | lg[i] = lg[i - 1]; 54 | else 55 | lg[i] = lg[i - 1] + 1; 56 | 57 | for (int i = 0; i < n; i++) 58 | ans[i] = INT_MAX; 59 | 60 | cord* a = new cord[q]; 61 | 62 | for (int i = 0; i <= n; i++) 63 | dsu[i] = i; 64 | 65 | for (int i = 0; i < q; i++) { 66 | scanf("%d%d%d", &l, &r, &x); 67 | a[i].l = l - 1; 68 | a[i].r = r - 1; 69 | a[i].x = x; 70 | a[i].id = i; 71 | } 72 | 73 | sort(a, a + q, compare); 74 | for (int i = 0; i < q; i++) { 75 | l = a[i].l; 76 | r = a[i].r; 77 | x = a[i].x; 78 | for (int j = get(dsu, l); j <= r; j = get(dsu, j)) { 79 | dsu[j] = j + 1; 80 | ans[j] = x; 81 | } 82 | } 83 | 84 | for (int i = 0; i < n; i++) { 85 | table[i] = new int[17]; 86 | table[i][0] = ans[i]; 87 | } 88 | 89 | for (int j = 1; j < 17; j++) 90 | for (int i = 0; i < n; i++) 91 | if (i + (1 << (j - 1)) < n)table[i][j] = minn(table[i][j - 1], table[i + (1 << (j - 1))][j - 1]); 92 | else table[i][j] = minn(table[i][j - 1], INT_MAX + 1); 93 | 94 | for (int i = 0; i < q; i++) { 95 | l = a[i].l; 96 | r = a[i].r; 97 | x = a[i].x; 98 | if (minn(table[l][lg[r - l + 1]], table[r - (1 << lg[r - l + 1]) + 1][lg[r - l + 1]]) != x) { 99 | printf("inconsistent\n"); 100 | return 0; 101 | } 102 | } 103 | 104 | printf("consistent\n"); 105 | for (int i = 0; i < n; i++) 106 | printf("%d ", ans[i]); 107 | 108 | printf("\n"); 109 | 110 | return 0; 111 | } -------------------------------------------------------------------------------- /term 2/Segment tree/I.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const long long MAX = 1000000001; 6 | 7 | int n; 8 | 9 | struct Node { 10 | int maxx; 11 | int sum; 12 | int set; 13 | int id; 14 | Node* l; 15 | Node* r; 16 | 17 | Node() { 18 | l = nullptr; 19 | r = nullptr; 20 | maxx = 0; 21 | sum = 0; 22 | set = MAX; 23 | id = 0; 24 | } 25 | 26 | explicit Node(int index) { 27 | l = nullptr; 28 | r = nullptr; 29 | maxx = 0; 30 | sum = 0; 31 | set = MAX; 32 | id = index; 33 | } 34 | 35 | Node(Node* x, Node* y) { 36 | l = x; 37 | r = y; 38 | } 39 | 40 | ~Node() { 41 | delete l; 42 | delete r; 43 | } 44 | 45 | void updatemax() { 46 | maxx = max(l->maxx, r->maxx + l->sum); 47 | sum = l->sum + r->sum; 48 | } 49 | }; 50 | 51 | Node t; 52 | 53 | void push(Node* v) { 54 | v->l->set = v->set; 55 | v->r->set = v->set; 56 | } 57 | 58 | void getChild(Node* v, int l, int r) { 59 | if (v->l == nullptr) { 60 | int leftid = v->id * 2 + 1; 61 | int rightid = v->id * 2 + 2; 62 | v->l = new Node(leftid); 63 | v->r = new Node(rightid); 64 | } 65 | 66 | if (v->set == MAX) 67 | return; 68 | 69 | v->sum = v->set * (r - l + 1); 70 | v->maxx = v->sum; 71 | if (l != r) { 72 | push(v); 73 | } 74 | v->set = MAX; 75 | } 76 | 77 | void set(Node* v, int l, int r, int tl, int tr, int value) { 78 | getChild(v, l, r); 79 | if (tl > r || l > tr) 80 | return; 81 | 82 | if (l >= tl && r <= tr) { 83 | v->set = value; 84 | getChild(v, l, r); 85 | return; 86 | } 87 | 88 | int tm = l + (r - l) / 2; 89 | 90 | set(v->l, l, tm, tl, tr, value); 91 | set(v->r, tm + 1, r, tl, tr, value); 92 | 93 | v->updatemax(); 94 | } 95 | 96 | long long get(Node* v, int l, int r, int height) { 97 | getChild(v, l, r); 98 | 99 | if (l == r) 100 | return r; 101 | 102 | int m = l + (r - l) / 2; 103 | getChild(v->l, l, m); 104 | 105 | if (v->l->maxx <= height) { 106 | getChild(v->r, m + 1, r); 107 | height -= v->l->sum; 108 | return get(v->r, m + 1, r, height); 109 | } else { 110 | return get(v->l, l, m, height); 111 | } 112 | } 113 | 114 | int main() { 115 | scanf("%d", &n); 116 | char s; 117 | 118 | while (scanf("%s", &s) != EOF) { 119 | if (s == 'E') 120 | return 0; 121 | 122 | if (s == 'I') { 123 | int a, b, D; 124 | scanf("%d %d %d", &a, &b, &D); 125 | a -= 1; 126 | b -= 1; 127 | set(&t, 0, n, a, b, D); 128 | } 129 | 130 | if (s == 'Q') { 131 | int height; 132 | scanf("%d", &height); 133 | printf("%lld\n", get(&t, 0, n, height)); 134 | } 135 | } 136 | return 0; 137 | } -------------------------------------------------------------------------------- /term 2/Segment tree/J.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | long long MAX = 1000000000; 7 | 8 | struct Node { 9 | long long min; 10 | long long set; 11 | long long l; 12 | long long r; 13 | bool up; 14 | }; 15 | 16 | long long n, m, x; 17 | Node* t; 18 | 19 | 20 | long long min(long long l, long long r) { 21 | if (l < r)return l; 22 | else return r; 23 | } 24 | 25 | 26 | void push(long long current) { 27 | long long value = t[current].set; 28 | t[current].up = false; 29 | 30 | long long left = (current * 2) + 1; 31 | long long right = (current * 2) + 2; 32 | 33 | if (t[left].min < value) { 34 | t[left].set = value; 35 | t[left].up = true; 36 | t[left].min = value; 37 | } 38 | 39 | if (t[right].min < value) { 40 | t[right].set = value; 41 | t[right].up = true; 42 | t[right].min = value; 43 | } 44 | 45 | } 46 | 47 | long long get(long long l, long long r, long long v) { 48 | if (l > t[v].r || r < t[v].l) 49 | return MAX; 50 | 51 | if (l <= t[v].l && r >= t[v].r) { 52 | return t[v].min; 53 | } 54 | 55 | if (t[v].up) push(v); 56 | 57 | long long res = min(get(l, r, v * 2 + 1), get(l, r, v * 2 + 2)); 58 | t[v].min = min(t[v * 2 + 1].min, t[v * 2 + 2].min); 59 | 60 | return res; 61 | } 62 | 63 | 64 | void set(long long l, long long r, long long value, long long v) { 65 | if (l > t[v].r || r < t[v].l) 66 | return; 67 | 68 | if (l <= t[v].l && r >= t[v].r) { 69 | if (value > t[v].min) { 70 | t[v].up = true; 71 | t[v].set = value; 72 | t[v].min = value; 73 | } 74 | return; 75 | } 76 | 77 | if (t[v].up) push(v); 78 | 79 | set(l, r, value, 2 * v + 1); 80 | set(l, r, value, 2 * v + 2); 81 | 82 | t[v].min = min(t[v * 2 + 1].min, t[v * 2 + 2].min); 83 | } 84 | 85 | long long ind(long long l, long long r, long long v, long long value) { 86 | if (l > t[v].r || r < t[v].l) 87 | return -1; 88 | 89 | if (t[v].l == t[v].r) { 90 | if (t[v].min == value) 91 | return v; 92 | else return -1; 93 | } 94 | 95 | if (t[v].up) push(v); 96 | 97 | if (t[v * 2 + 1].min <= value) { 98 | long long i = ind(l, r, v * 2 + 1, value); 99 | if (i > 0) return i; 100 | } 101 | 102 | return ind(l, r, v * 2 + 2, value); 103 | } 104 | 105 | void upToDegree() { 106 | x = 1; 107 | while (n > x) { 108 | x = x << 1; 109 | } 110 | } 111 | 112 | void build() { 113 | for (long long i = x - 1; i > 0;) { 114 | i--; 115 | t[i].min = min(t[2 * i + 1].min, t[2 * i + 2].min); 116 | t[i].l = t[2 * i + 1].l; 117 | t[i].r = t[2 * i + 2].r; 118 | } 119 | } 120 | 121 | int main() { 122 | cin >> n; 123 | cin >> m; 124 | MAX = MAX * MAX + 1; 125 | upToDegree(); 126 | 127 | long long size = x << 1; 128 | t = new Node[size]; 129 | 130 | for (long long i = 0; i < size; i++) { 131 | t[i].min = MAX; 132 | t[i].set = 0; 133 | t[i].l = i; 134 | t[i].r = i; 135 | t[i].up = false; 136 | } 137 | 138 | for (long long i = 0; i < n; i++) { 139 | t[x + i - 1].min = 0; 140 | } 141 | 142 | build(); 143 | string s; 144 | 145 | for (long long i = 0; i < m; i++) { 146 | long long l, r, val; 147 | cin >> s; 148 | cin >> l; 149 | cin >> r; 150 | 151 | if (s == "attack") { 152 | long long res = get(x + l - 2, x + r - 2, 0); 153 | cout << res << " " << ind(x + l - 2, x + r - 2, 0, res) + 2 - x << "\n"; 154 | } else { 155 | cin >> val; 156 | set(x + l - 2, x + r - 2, val, 0); 157 | } 158 | } 159 | 160 | return 0; 161 | } -------------------------------------------------------------------------------- /term 2/Segment tree/K.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | long long n, m, * a, v; 6 | 7 | struct Node { 8 | long long sum; 9 | long long hsum; 10 | long long l; 11 | long long r; 12 | }; 13 | 14 | long long* prefhsum; 15 | long long* prefsum; 16 | long long* hf; 17 | Node* t; 18 | 19 | long long sum(long long l, long long r, long long current) { 20 | if (t[current].r < l || r < t[current].l) 21 | return 0; 22 | 23 | if (t[current].l >= l && r >= t[current].r) 24 | return t[current].sum; 25 | 26 | return sum(l, r, 2 * current + 1) + sum(l, r, 2 * current + 2); 27 | } 28 | 29 | long long hsum(long long l, long long r, long long current) { 30 | if (t[current].r < l || r < t[current].l) 31 | return 0; 32 | 33 | if (t[current].l >= l && r >= t[current].r) 34 | return t[current].hsum; 35 | 36 | return hsum(l, r, 2 * current + 1) + hsum(l, r, 2 * current + 2); 37 | } 38 | 39 | void set(long long i, long long value) { 40 | i = v + i - 2; 41 | t[i].sum = value; 42 | t[i].hsum = hf[value]; 43 | long long j = i; 44 | 45 | while (j >= 1) { 46 | j = (j - 1) / 2; 47 | t[j].sum = t[2 * j + 1].sum + t[2 * j + 2].sum; 48 | t[j].hsum = t[2 * j + 1].hsum + t[2 * j + 2].hsum; 49 | } 50 | } 51 | 52 | void upToDegree() { 53 | while (n > v) { 54 | v = v << 1; 55 | } 56 | } 57 | 58 | void hashh() { 59 | hf[0] = 1; 60 | 61 | for (int i = 0; i < n; i++) { 62 | t[v + i - 1].sum = a[i]; 63 | hf[i + 1] = hf[i] * 7; 64 | } 65 | 66 | hf[n] = hf[n - 1] * 7; 67 | } 68 | 69 | void prefsumms() { 70 | prefsum[0] = 0; 71 | prefhsum[0] = 0; 72 | 73 | for (int i = 1; i < n + 1; i++) { 74 | prefhsum[i] = prefhsum[i - 1] + hf[i]; 75 | prefsum[i] = prefsum[i - 1] + i; 76 | } 77 | 78 | for (int i = 0; i < n; i++) { 79 | t[v + i - 1].hsum = hf[a[i]]; 80 | } 81 | } 82 | 83 | void build() { 84 | for (long long i = v - 2; i >= 0; i--) { 85 | t[i].sum = t[2 * i + 1].sum + t[2 * i + 2].sum; 86 | t[i].hsum = t[2 * i + 1].hsum + t[2 * i + 2].hsum; 87 | t[i].l = t[2 * i + 1].l; 88 | t[i].r = t[2 * i + 2].r; 89 | } 90 | } 91 | 92 | int main() { 93 | freopen("permutation.in", "r", stdin); 94 | freopen("permutation.out", "w", stdout); 95 | 96 | scanf("%lld", &n); 97 | 98 | a = new long long[n]; 99 | hf = new long long[n + 1]; 100 | prefsum = new long long[n + 1]; 101 | prefhsum = new long long[n + 1]; 102 | 103 | for (int i = 0; i < n; i++) { 104 | scanf("%lld", &a[i]); 105 | } 106 | 107 | v = 1; 108 | upToDegree(); 109 | long long size = v << 1; 110 | t = new Node[size]; 111 | 112 | for (int i = 0; i < size; i++) { 113 | t[i].sum = 0; 114 | t[i].l = i; 115 | t[i].r = i; 116 | } 117 | 118 | hashh(); 119 | prefsumms(); 120 | build(); 121 | 122 | scanf("%lld", &m); 123 | for (int i = 0; i < m; i++) { 124 | long long f, x, y; 125 | scanf("%lld %lld %lld", &f, &x, &y); 126 | 127 | if (f == 1) set(x, y); 128 | else { 129 | long long length = y - x + 1; 130 | long long hashsumm = hsum(v + x - 2, v + y - 2, 0); 131 | long long summ = sum(v + x - 2, v + y - 2, 0); 132 | 133 | if (summ == prefsum[length] && hashsumm == prefhsum[length]) 134 | printf("YES\n"); 135 | else printf("NO\n"); 136 | } 137 | } 138 | return 0; 139 | } -------------------------------------------------------------------------------- /term 2/Tree queries/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | const int MAX = 200001; 7 | const int LOGMAX = 20; 8 | 9 | size_t n, l; 10 | vector g[MAX]; 11 | int tin[MAX], tout[MAX]; 12 | int timer; 13 | int up[MAX][LOGMAX]; 14 | 15 | void dfs(int v, int p = 1) { 16 | int to, i; 17 | tin[v] = timer++; 18 | up[v][0] = p; 19 | 20 | for (i = 1; i <= l; ++i) 21 | up[v][i] = up[up[v][i - 1]][i - 1]; 22 | 23 | for (i = 0; i < g[v].size(); ++i) { 24 | to = g[v][i]; 25 | if (to != p) 26 | dfs(to, v); 27 | } 28 | tout[v] = timer++; 29 | } 30 | 31 | bool upper(int a, int b) { 32 | return tin[a] <= tin[b] && tout[a] >= tout[b]; 33 | } 34 | 35 | int lca(int a, int b) { 36 | if (upper(a, b)) return a; 37 | 38 | if (upper(b, a)) return b; 39 | 40 | for (int i = l; i >= 0; --i) 41 | if (!upper(up[a][i], b)) 42 | a = up[a][i]; 43 | 44 | return up[a][0]; 45 | } 46 | 47 | 48 | int main() { 49 | int m; 50 | scanf("%d", &n); 51 | 52 | l = 1; 53 | while ((1 << l) <= n) 54 | ++l; 55 | 56 | for (int i = 2; i < n + 1; i++) { 57 | int x; 58 | scanf("%d", &x); 59 | g[x].push_back(i); 60 | } 61 | dfs(1); 62 | 63 | scanf("%d", &m); 64 | for (int i = 0; i < m; i++) { 65 | int u, v; 66 | scanf("%d %d", &u, &v); 67 | 68 | int res = lca(u, v); 69 | printf("%d\n", res); 70 | }; 71 | 72 | return 0; 73 | } -------------------------------------------------------------------------------- /term 2/Tree queries/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | const int MAX = 200001; 8 | const int LOGMAX = 20; 9 | 10 | size_t n, l; 11 | vector> g[MAX]; 12 | int tin[MAX], tout[MAX]; 13 | int timer; 14 | pair up[MAX][LOGMAX]; 15 | 16 | void dfs(int v, int p = 1, int c = INT_MAX) { 17 | tin[v] = timer++; 18 | up[v][0] = make_pair(p, c); 19 | for (int i = 1; i <= l; ++i) { 20 | up[v][i].first = up[up[v][i - 1].first][i - 1].first; 21 | up[v][i].second = min(up[v][i - 1].second, up[up[v][i - 1].first][i - 1].second); 22 | } 23 | for (int i = 0; i < g[v].size(); ++i) { 24 | int to = g[v][i].first; 25 | dfs(to, v, g[v][i].second); 26 | } 27 | tout[v] = timer++; 28 | } 29 | 30 | bool upper(int a, int b) { 31 | return tin[a] <= tin[b] && tout[a] >= tout[b]; 32 | } 33 | 34 | int minlca(int a, int b) { 35 | int res = INT_MAX; 36 | for (int i = l; i >= 0; i--) { 37 | if (!upper(up[a][i].first, b)) { 38 | res = min(res, up[a][i].second); 39 | a = up[a][i].first; 40 | } 41 | } 42 | 43 | if (!upper(a, b)) { 44 | res = min(res, up[a][0].second); 45 | } 46 | 47 | for (int i = l; i >= 0; i--) { 48 | if (!upper(up[b][i].first, a)) { 49 | res = min(res, up[b][i].second); 50 | b = up[b][i].first; 51 | } 52 | } 53 | 54 | if (!upper(b, a)) { 55 | res = min(res, up[b][0].second); 56 | } 57 | 58 | return res; 59 | } 60 | 61 | 62 | int main() { 63 | freopen("minonpath.in", "r", stdin); 64 | freopen("minonpath.out", "w", stdout); 65 | 66 | int m; 67 | scanf("%d", &n); 68 | 69 | l = 1; 70 | while ((1 << l) <= n) ++l; 71 | for (int i = 2; i < n + 1; i++) { 72 | int x; 73 | int p; 74 | scanf("%d %d", &x, &p); 75 | g[x].push_back(make_pair(i, p)); 76 | } 77 | dfs(1); 78 | 79 | scanf("%d", &m); 80 | for (int i = 0; i < m; i++) { 81 | int u, v; 82 | scanf("%d %d", &u, &v); 83 | int res = minlca(u, v); 84 | printf("%d\n", res); 85 | }; 86 | 87 | return 0; 88 | } -------------------------------------------------------------------------------- /term 2/Tree queries/H.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | const int MAX = 1000001; 8 | 9 | vector> graph; 10 | int color[MAX], res[MAX]; 11 | set sett[MAX]; 12 | 13 | void add(set& a, set& b) { 14 | if (a.size() < b.size())a.swap(b); 15 | 16 | for (auto i = b.begin(); i != b.end(); i++) { 17 | a.insert(*i); 18 | } 19 | b.clear(); 20 | } 21 | 22 | void dfs(int v) { 23 | int t; 24 | sett[v].insert(color[v]); 25 | 26 | for (int i = 0; i < graph[v].size(); i++) { 27 | t = graph[v][i]; 28 | dfs(t); 29 | add(sett[v], sett[t]); 30 | } 31 | 32 | res[v] = sett[v].size(); 33 | } 34 | 35 | int main() { 36 | size_t n; 37 | scanf("%d", &n); 38 | graph.resize(n + 1); 39 | 40 | for (int i = 1; i < n + 1; i++) { 41 | int parent, col; 42 | scanf("%d %d", &parent, &col); 43 | graph[parent].push_back(i); 44 | color[i] = col; 45 | } 46 | dfs(0); 47 | 48 | for (int i = 1; i < n + 1; i++) { 49 | printf("%d ", res[i]); 50 | } 51 | 52 | return 0; 53 | } -------------------------------------------------------------------------------- /term 3/Graphs, DFS, MST/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int n, m; 6 | const int MAX_N = 100000; 7 | std::vector g[MAX_N]; 8 | bool used[MAX_N]; 9 | std::vector answer; 10 | char color[MAX_N]; 11 | 12 | void dfs(const int v) { 13 | used[v] = true; 14 | 15 | for (int i = 0; i < g[v].size(); ++i) { 16 | int u = g[v][i]; 17 | if (!used[u]) { 18 | dfs(u); 19 | } 20 | } 21 | 22 | answer.push_back(v); 23 | } 24 | 25 | bool dfsForCycle(const int v) { 26 | color[v] = 'g'; 27 | 28 | for (int i = 0; i < g[v].size(); ++i) { 29 | int u = g[v][i]; 30 | if (color[u] == 'w') { 31 | if (dfsForCycle(u)) return true; 32 | } else if (color[u] == 'g') { 33 | return true; 34 | } 35 | } 36 | 37 | color[v] = 'b'; 38 | 39 | return false; 40 | } 41 | 42 | bool checkCycle() { 43 | for (int i = 0; i < n; ++i) { 44 | color[i] = 'w'; 45 | } 46 | 47 | bool hasCycle = false; 48 | for (int i = 0; i < n; i++) { 49 | hasCycle = dfsForCycle(i); 50 | if (hasCycle) { 51 | answer.clear(); 52 | std::cout << -1; 53 | break; 54 | } 55 | } 56 | 57 | return hasCycle; 58 | } 59 | 60 | 61 | void topSort() { 62 | if (!checkCycle()) { 63 | for (int i = 0; i < n; ++i) { 64 | used[i] = false; 65 | } 66 | 67 | for (int i = 0; i < n; ++i) { 68 | if (!used[i]) { 69 | dfs(i); 70 | } 71 | } 72 | 73 | std::reverse(answer.begin(), answer.end()); 74 | for (int i = 0; i < answer.size(); ++i) { 75 | std::cout << answer[i] + 1 << " "; 76 | } 77 | } 78 | } 79 | 80 | int main() { 81 | std::cin >> n >> m; 82 | 83 | for (int i = 0; i < m; ++i) { 84 | int beg, end; 85 | std::cin >> beg >> end; 86 | beg--; 87 | end--; 88 | g[beg].push_back(end); 89 | } 90 | topSort(); 91 | 92 | return 0; 93 | } -------------------------------------------------------------------------------- /term 3/Graphs, DFS, MST/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | int time, n, m; 9 | vector> graph; 10 | vector used, enter, ret; 11 | set bridges; 12 | map, int> numberOfEdges; 13 | 14 | pair getEdge(int a, int b) { 15 | if (a > b) { 16 | int temp = a; 17 | a = b; 18 | b = temp; 19 | } 20 | 21 | return make_pair(a, b); 22 | }; 23 | 24 | void dfs(int v, int p = -1) { 25 | used[v] = 1; 26 | enter[v] = ret[v] = time++; 27 | 28 | for (int i = 0; i < graph[v].size(); i++) { 29 | int to = graph[v][i]; 30 | if (to == p) continue; 31 | if (used[to]) 32 | ret[v] = min(ret[v], enter[to]); 33 | else { 34 | dfs(to, v); 35 | ret[v] = min(ret[v], ret[to]); 36 | if (ret[to] > enter[v]) bridges.insert(numberOfEdges[getEdge(v, to)]); 37 | 38 | } 39 | } 40 | } 41 | 42 | 43 | void findAll() { 44 | time = 1; 45 | 46 | for (int i = 0; i <= n; ++i) { 47 | if (!used[i]) dfs(i); 48 | } 49 | }; 50 | 51 | int main() { 52 | scanf("%d %d", &n, &m); 53 | 54 | graph.resize(n + 1); 55 | used.resize(n + 1); 56 | enter.resize(n + 1); 57 | ret.resize(n + 1); 58 | 59 | for (int i = 1; i <= m; i++) { 60 | int beg, end; 61 | scanf("%d %d", &beg, &end); 62 | 63 | graph[beg].push_back(end); 64 | graph[end].push_back(beg); 65 | numberOfEdges[getEdge(beg, end)] = i; 66 | } 67 | 68 | findAll(); 69 | 70 | printf("%d\n", bridges.size()); 71 | 72 | int c = 0; 73 | 74 | for (auto iter = bridges.begin(); iter != bridges.end(); iter++) { 75 | if (c++) printf(" "); 76 | printf("%d", *iter); 77 | } 78 | 79 | return 0; 80 | } -------------------------------------------------------------------------------- /term 3/Graphs, DFS, MST/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | vector> graph; 8 | vector used, enter, ret; 9 | set artPoints; 10 | int time, n, m; 11 | 12 | //p - parent 13 | void dfs(int v, int p = -1) { 14 | used[v] = 1; 15 | enter[v] = ret[v] = time++; 16 | int c = 0;//child 17 | for (int i = 0; i < graph[v].size(); ++i) { 18 | int to = graph[v][i]; 19 | if (to == p) continue; 20 | if (used[to]) { 21 | ret[v] = min(ret[v], enter[to]); 22 | } else { 23 | dfs(to, v); 24 | c++; 25 | ret[v] = min(ret[v], ret[to]); 26 | if ((ret[to] >= enter[v]) && (p != -1)) artPoints.insert(v); 27 | } 28 | } 29 | if ((p == -1) && (c > 1)) artPoints.insert(v); 30 | } 31 | 32 | void findAll() { 33 | time = 1; 34 | for (int i = 1; i <= n; ++i) { 35 | if (!used[i]) dfs(i); 36 | } 37 | } 38 | 39 | int main() { 40 | scanf("%d %d", &n, &m); 41 | 42 | graph.resize(n + 1); 43 | used.resize(n + 1); 44 | enter.resize(n + 1); 45 | ret.resize(n + 1); 46 | 47 | for (int i = 1; i <= m; i++) { 48 | int beg, end; 49 | scanf("%d %d", &beg, &end); 50 | 51 | graph[beg].push_back(end); 52 | graph[end].push_back(beg); 53 | } 54 | 55 | findAll(); 56 | 57 | printf("%d\n", artPoints.size()); 58 | 59 | for (auto iter = artPoints.begin(); iter != artPoints.end(); ++iter) { 60 | printf("%d ", *iter); 61 | } 62 | 63 | return 0; 64 | } -------------------------------------------------------------------------------- /term 3/Graphs, DFS, MST/D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | int time, n, m, maxColor; 10 | vector> graph; 11 | vector used, enter, ret, colors, mult; 12 | set bridges; 13 | map, int> numberOfEdge; 14 | 15 | pair getEdge(int a, int b) { 16 | if (a > b) { 17 | int temp = a; 18 | a = b; 19 | b = temp; 20 | } 21 | 22 | return make_pair(a, b); 23 | }; 24 | 25 | void dfs(int v, int p = -1) { 26 | used[v] = 1; 27 | enter[v] = ret[v] = time++; 28 | for (int i = 0; i < graph[v].size(); ++i) { 29 | int to = graph[v][i]; 30 | 31 | if (to == p) continue; 32 | 33 | if (used[to]) 34 | ret[v] = min(ret[v], enter[to]); 35 | else { 36 | dfs(to, v); 37 | ret[v] = min(ret[v], ret[to]); 38 | if (ret[to] > enter[v] && !mult[numberOfEdge[getEdge(v, to)]]) 39 | bridges.insert(numberOfEdge[getEdge(v, to)]); 40 | } 41 | } 42 | } 43 | 44 | void paint(int v, int color) { 45 | colors[v] = color; 46 | 47 | for (int i = 0; i < graph[v].size(); ++i) { 48 | int to = graph[v][i]; 49 | 50 | if (colors[to] == 0) { 51 | if (bridges.find(numberOfEdge[getEdge(v, to)]) != bridges.end()) { 52 | maxColor++; 53 | paint(to, maxColor); 54 | } else { 55 | paint(to, color); 56 | } 57 | } 58 | } 59 | } 60 | 61 | void solve() { 62 | time = 1; 63 | 64 | for (int i = 1; i <= n; ++i) { 65 | colors[i] = 0; 66 | if (!used[i]) 67 | dfs(i); 68 | } 69 | 70 | maxColor = 0; 71 | for (int i = 1; i <= n; ++i) { 72 | if (colors[i] == 0) { 73 | maxColor++; 74 | paint(i, maxColor); 75 | } 76 | } 77 | } 78 | 79 | int main() { 80 | scanf("%d %d", &n, &m); 81 | 82 | graph.resize(n + 1); 83 | used.resize(n + 1); 84 | enter.resize(n + 1); 85 | ret.resize(n + 1); 86 | colors.resize(n + 1); 87 | mult.resize(m + 1); 88 | 89 | for (int i = 1; i <= m; i++) { 90 | int beg, end; 91 | scanf("%d %d", &beg, &end); 92 | 93 | graph[beg].push_back(end); 94 | graph[end].push_back(beg); 95 | if (numberOfEdge[getEdge(beg, end)] == 0) { 96 | numberOfEdge[getEdge(beg, end)] = i; 97 | } else { 98 | mult[numberOfEdge[getEdge(beg, end)]] = true; 99 | } 100 | } 101 | 102 | solve(); 103 | 104 | printf("%d\n", maxColor); 105 | 106 | for (int i = 1; i <= n; ++i) { 107 | printf("%d ", colors[i]); 108 | } 109 | 110 | return 0; 111 | } -------------------------------------------------------------------------------- /term 3/Graphs, DFS, MST/E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | vector> graph; 9 | vector used, enter, ret, colors, painted; 10 | map, vector> numbersOfEdges; 11 | int time, n, m, maxColor; 12 | 13 | pair getEdge(int a, int b) { 14 | if (a > b) { 15 | int temp = a; 16 | a = b; 17 | b = temp; 18 | } 19 | return make_pair(a, b); 20 | }; 21 | 22 | void setColor(int v, int to, int color) { 23 | vector numbers = numbersOfEdges[getEdge(v, to)]; 24 | for (int i = 0; i < numbers.size(); ++i) { 25 | colors[numbers[i]] = color; 26 | } 27 | }; 28 | 29 | void dfs(int v, int p = -1) { 30 | used[v] = 1; 31 | enter[v] = ret[v] = time++; 32 | int c = 0; 33 | for (int i = 0; i < graph[v].size(); ++i) { 34 | int to = graph[v][i]; 35 | if (to == p) continue; 36 | if (used[to]) { 37 | ret[v] = min(ret[v], enter[to]); 38 | } else { 39 | dfs(to, v); 40 | c++; 41 | ret[v] = min(ret[v], ret[to]); 42 | } 43 | } 44 | } 45 | 46 | void paint(int v, int color, int p) { 47 | painted[v] = 1; 48 | for (int i = 0; i < graph[v].size(); ++i) { 49 | int to = graph[v][i]; 50 | if (to == p) continue; 51 | if (!painted[to]) { 52 | if (ret[to] >= enter[v]) { 53 | int newColor = ++maxColor; 54 | setColor(v, to, newColor); 55 | paint(to, newColor, v); 56 | } else { 57 | setColor(v, to, color); 58 | paint(to, color, v); 59 | } 60 | } else if (enter[to] < enter[v]) { 61 | setColor(v, to, color); 62 | } 63 | } 64 | } 65 | 66 | void solve() { 67 | time = 1; 68 | for (int i = 1; i <= n; ++i) { 69 | if (!used[i]) dfs(i); 70 | } 71 | maxColor = 0; 72 | for (int i = 1; i <= n; ++i) { 73 | if (!painted[i]) { 74 | paint(i, maxColor, -1); 75 | } 76 | } 77 | } 78 | 79 | int main() { 80 | scanf("%d %d", &n, &m); 81 | 82 | graph.resize(n + 1); 83 | used.resize(n + 1); 84 | painted.resize(n + 1); 85 | enter.resize(n + 1); 86 | ret.resize(n + 1); 87 | colors.resize(m + 1); 88 | 89 | for (int i = 1; i <= m; i++) { 90 | int beg, end; 91 | scanf("%d %d", &beg, &end); 92 | 93 | graph[beg].push_back(end); 94 | graph[end].push_back(beg); 95 | 96 | numbersOfEdges[getEdge(beg, end)].push_back(i); 97 | } 98 | 99 | solve(); 100 | 101 | printf("%d\n", maxColor); 102 | 103 | for (int i = 1; i <= m; ++i) { 104 | printf("%d ", colors[i]); 105 | } 106 | 107 | return 0; 108 | } -------------------------------------------------------------------------------- /term 3/Graphs, DFS, MST/F.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | using namespace std; 8 | 9 | vector> graph, transgraph; 10 | vector order, numberOfComponent; 11 | vector used; 12 | set > noMultEdges; 13 | int n, m, col; 14 | 15 | void dfsOne(int v) { 16 | used[v] = true; 17 | for (int i = 0; i < graph[v].size(); ++i) { 18 | int to = graph[v][i]; 19 | if (!used[to]) 20 | dfsOne(to); 21 | } 22 | order.push_back(v); 23 | } 24 | 25 | void dfsTwo(int v) { 26 | used[v] = true; 27 | numberOfComponent[v] = col; 28 | for (int i = 0; i < transgraph[v].size(); ++i) { 29 | int to = transgraph[v][i]; 30 | if (!used[to]) 31 | dfsTwo(to); 32 | } 33 | } 34 | 35 | int main() { 36 | scanf("%d %d", &n, &m); 37 | 38 | graph.resize(n); 39 | transgraph.resize(n); 40 | used.resize(n); 41 | numberOfComponent.resize(n); 42 | 43 | for (int i = 0; i < m; ++i) { 44 | int beg, end; 45 | scanf("%d %d", &beg, &end); 46 | graph[beg - 1].push_back(end - 1); 47 | transgraph[end - 1].push_back(beg - 1); 48 | } 49 | 50 | used.assign(n, false); 51 | for (int i = 0; i < n; ++i) { 52 | if (!used[i]) { 53 | dfsOne(i); 54 | } 55 | } 56 | 57 | used.assign(n, false); 58 | col = 1; 59 | for (int i = 0; i < n; ++i) { 60 | int v = order[n - 1 - i]; 61 | if (!used[v]) { 62 | dfsTwo(v); 63 | col++; 64 | } 65 | } 66 | 67 | 68 | for (int i = 0; i < n; ++i) { 69 | for (int j = 0; j < graph[i].size(); j++) { 70 | int to = graph[i][j]; 71 | if (numberOfComponent[i] != numberOfComponent[to]) 72 | noMultEdges.insert(make_pair(numberOfComponent[i], numberOfComponent[to])); 73 | } 74 | } 75 | 76 | 77 | printf("%d", noMultEdges.size()); 78 | return 0; 79 | } -------------------------------------------------------------------------------- /term 3/Graphs, DFS, MST/G.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | using namespace std; 6 | 7 | const int MAXN = 1001; 8 | int graph[MAXN][MAXN], gg[MAXN][MAXN]; 9 | vector used; 10 | int n; 11 | 12 | 13 | void dfs(int v, bool direction) { 14 | used[v] = true; 15 | for (int i = 0; i < n; ++i) { 16 | if ((direction ? gg[i][v] : gg[v][i]) && !used[i]) dfs(i, direction); 17 | } 18 | } 19 | 20 | bool visitAll() { 21 | for (int i = 0; i < n; ++i) { 22 | if (!used[i]) 23 | return false; 24 | } 25 | 26 | return true; 27 | } 28 | 29 | int main() { 30 | freopen("avia.in", "r", stdin); 31 | freopen("avia.out", "w", stdout); 32 | 33 | scanf("%d", &n); 34 | used.resize(n); 35 | 36 | for (int i = 0; i < n; ++i) { 37 | for (int j = 0; j < n; ++j) { 38 | int x; 39 | scanf("%d", &x); 40 | graph[i][j] = x; 41 | } 42 | } 43 | 44 | int l = 0; 45 | int r = 1000000000; 46 | 47 | while (l < r) { 48 | int middle = (l + r) / 2; 49 | 50 | for (int i = 0; i < n; ++i) { 51 | for (int j = 0; j < n; ++j) { 52 | gg[i][j] = (graph[i][j] <= middle); 53 | } 54 | } 55 | 56 | used.assign(n, false); 57 | dfs(0, false); 58 | bool done = false; 59 | if (visitAll()) { 60 | used.assign(n, false); 61 | dfs(0, true); 62 | if (!visitAll()) 63 | done = true; 64 | } else { 65 | done = true; 66 | } 67 | 68 | if (!done) { 69 | r = middle; 70 | } else { 71 | l = middle + 1; 72 | } 73 | } 74 | 75 | printf("%d", l); 76 | return 0; 77 | } -------------------------------------------------------------------------------- /term 3/Graphs, DFS, MST/H.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | using namespace std; 8 | 9 | int n, m; 10 | vector> graph, invgraph; 11 | vector used; 12 | stack order; 13 | vector comp; 14 | vector names; 15 | map numbers; 16 | 17 | int converterWithountNot(int i) { 18 | return 2 * i; 19 | } 20 | 21 | int converterWithNot(int i) { 22 | return 2 * i + 1; 23 | } 24 | 25 | void dfsOne(int v) { 26 | used[v] = true; 27 | 28 | for (int i = 0; i < graph[v].size(); ++i) { 29 | int to = graph[v][i]; 30 | if (!used[to]) { 31 | dfsOne(to); 32 | } 33 | } 34 | order.push(v); 35 | } 36 | 37 | void dfsTwo(int v, int col) { 38 | comp[v] = col; 39 | 40 | for (int i = 0; i < invgraph[v].size(); ++i) { 41 | int to = invgraph[v][i]; 42 | if (comp[to] == -1) 43 | dfsTwo(to, col); 44 | } 45 | } 46 | 47 | int main() { 48 | cin >> n >> m; 49 | 50 | graph.resize(2 * n); 51 | invgraph.resize(2 * n); 52 | comp.resize(2 * n); 53 | used.resize(2 * n); 54 | 55 | for (int i = 0; i < n; ++i) { 56 | string name; 57 | cin >> name; 58 | 59 | names.push_back(name); 60 | numbers[name] = i; 61 | } 62 | 63 | 64 | for (int i = 0; i < m; ++i) { 65 | string firstName, arrow, secondName; 66 | cin >> firstName >> arrow >> secondName; 67 | 68 | int firstNumber, secondNumber; 69 | 70 | if (firstName[0] == '-') { 71 | firstNumber = converterWithNot(numbers[firstName.substr(1, firstName.size())]); 72 | } else firstNumber = converterWithountNot(numbers[firstName.substr(1, firstName.size())]); 73 | 74 | if (secondName[0] == '-') { 75 | secondNumber = converterWithNot(numbers[secondName.substr(1, secondName.size())]); 76 | } else secondNumber = converterWithountNot(numbers[secondName.substr(1, secondName.size())]); 77 | 78 | //x => y && !y => !x 79 | graph[firstNumber].push_back(secondNumber); 80 | graph[secondNumber ^ 1].push_back(firstNumber ^ 1); 81 | //y => x && !x => !y 82 | invgraph[secondNumber].push_back(firstNumber); 83 | invgraph[firstNumber ^ 1].push_back(secondNumber ^ 1); 84 | } 85 | 86 | used.assign(2 * n, false); 87 | 88 | for (int i = 0; i < 2 * n; ++i) { 89 | if (!used[i]) 90 | dfsOne(i); 91 | } 92 | 93 | comp.assign(2 * n, -1); 94 | 95 | int col = 0; 96 | while (!order.empty()) { 97 | int v = order.top(); 98 | order.pop(); 99 | if (comp[v] == -1) { 100 | dfsTwo(v, col++); 101 | } 102 | } 103 | 104 | for (int i = 0; i < 2 * n; i += 2) { 105 | if (comp[i] == comp[i ^ 1]) { 106 | cout << -1; 107 | return 0; 108 | } 109 | } 110 | 111 | vector ans; 112 | for (int i = 0; i < 2 * n; i += 2) { 113 | if (comp[i] > comp[i ^ 1]) { 114 | ans.push_back(names[i / 2]); 115 | } 116 | } 117 | cout << ans.size() << "\n"; 118 | for (int i = 0; i < ans.size(); ++i) { 119 | cout << ans[i] << "\n"; 120 | } 121 | return 0; 122 | } -------------------------------------------------------------------------------- /term 3/Graphs, DFS, MST/I.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | using namespace std; 7 | 8 | int n; 9 | vector> points; 10 | vector used; 11 | vector selectedEdge; 12 | vector minEdge; 13 | 14 | const int INF = 1000000000; 15 | 16 | 17 | double distance(int v, int to) { 18 | if (v == to) 19 | return INF; 20 | pair a = points[v]; 21 | pair b = points[to]; 22 | return sqrt((b.first - a.first) * (b.first - a.first) + (b.second - a.second) * (b.second - a.second)); 23 | } 24 | 25 | 26 | int main() { 27 | scanf("%d", &n); 28 | used.resize(n); 29 | minEdge.resize(n); 30 | selectedEdge.resize(n); 31 | 32 | 33 | minEdge.assign(n, INF); 34 | selectedEdge.assign(n, -1); 35 | minEdge[0] = 0; 36 | 37 | for (int i = 0; i < n; ++i) { 38 | int xi, yi; 39 | scanf("%d %d", &xi, &yi); 40 | points.emplace_back(make_pair(xi, yi)); 41 | } 42 | 43 | double res = 0; 44 | for (int i = 0; i < n; ++i) { 45 | int v = -1; 46 | for (int j = 0; j < n; ++j) { 47 | if (!used[j] && (v == -1 || minEdge[j] < minEdge[v])) { 48 | v = j; 49 | } 50 | } 51 | 52 | used[v] = true; 53 | if (selectedEdge[v] != -1) { 54 | res += (distance(v, selectedEdge[v])); 55 | } 56 | 57 | for (int to = 0; to < n; ++to) { 58 | double dist = distance(v, to); 59 | if (dist < minEdge[to]) { 60 | minEdge[to] = dist; 61 | selectedEdge[to] = v; 62 | } 63 | } 64 | } 65 | 66 | printf("%f", res); 67 | return 0; 68 | } -------------------------------------------------------------------------------- /term 3/Graphs, DFS, MST/J.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | using namespace std; 7 | 8 | int n, m; 9 | vector parent, size; 10 | 11 | 12 | class Edge { 13 | public: 14 | int u, v; 15 | long long w; 16 | }; 17 | 18 | vector graph; 19 | 20 | int compare(Edge a, Edge b) { 21 | return (a.w < b.w); 22 | } 23 | 24 | int getDSU(int v) { 25 | if (v != parent[v]) 26 | parent[v] = getDSU(parent[v]); 27 | return parent[v]; 28 | } 29 | 30 | void uniteDsu(int x, int y) { 31 | x = getDSU(x); 32 | y = getDSU(y); 33 | 34 | if (size[x] < size[y]) { 35 | x = x + y; 36 | y = x - y; 37 | x = x - y; 38 | } 39 | 40 | parent[y] = x; 41 | size[x] += size[y]; 42 | 43 | } 44 | 45 | int main() { 46 | cin >> n >> m; 47 | graph.resize(m); 48 | parent.resize(n); 49 | size.resize(n); 50 | 51 | for (int i = 0; i < m; ++i) { 52 | int u, v; 53 | long long w; 54 | cin >> u >> v >> w; 55 | graph[i].u = u - 1; 56 | graph[i].v = v - 1; 57 | graph[i].w = w; 58 | } 59 | 60 | sort(graph.begin(), graph.begin() + m, compare); 61 | 62 | for (int i = 0; i < n; ++i) { 63 | parent[i] = i; 64 | size[i] = i; 65 | } 66 | 67 | long long res = 0; 68 | for (int i = 0; i < m; ++i) { 69 | int v = graph[i].v; 70 | int u = graph[i].u; 71 | long long w = graph[i].w; 72 | if (getDSU(v) != getDSU(u)) { 73 | res += w; 74 | uniteDsu(v, u); 75 | } 76 | } 77 | 78 | cout << res; 79 | 80 | return 0; 81 | } -------------------------------------------------------------------------------- /term 3/Graphs, Shortest paths/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | using namespace std; 6 | int n; 7 | 8 | void Floyd(vector>& graph) { 9 | for (int k = 0; k < n; ++k) { 10 | for (int i = 0; i < n; ++i) { 11 | for (int j = 0; j < n; ++j) { 12 | graph[i][j] = min(graph[i][j], graph[i][k] + graph[k][j]); 13 | } 14 | } 15 | } 16 | } 17 | 18 | int main() { 19 | cin >> n; 20 | 21 | vector> graph; 22 | graph.resize(n); 23 | 24 | for (int i = 0; i < n; ++i) { 25 | graph[i].resize(n); 26 | } 27 | 28 | for (int i = 0; i < n; ++i) { 29 | for (int j = 0; j < n; ++j) { 30 | cin >> graph[i][j]; 31 | } 32 | } 33 | 34 | Floyd(graph); 35 | for (int i = 0; i < n; ++i) { 36 | for (int j = 0; j < n; ++j) { 37 | cout << graph[i][j] << " "; 38 | } 39 | cout << "\n"; 40 | } 41 | 42 | return 0; 43 | } -------------------------------------------------------------------------------- /term 3/Graphs, Shortest paths/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | using namespace std; 8 | 9 | int n, m; 10 | const long long INFINITY = 4000000001; 11 | 12 | vector dijkstra(vector>>& graph) { 13 | vector distances(n, INFINITY); 14 | int start = 0; 15 | distances[start] = 0; 16 | set> queue; 17 | queue.insert({0, start}); 18 | while (!queue.empty()) { 19 | auto top = queue.begin(); 20 | int u = top->second; 21 | queue.erase(top); 22 | 23 | for (auto next: graph[u]) { 24 | int v = next.first; 25 | int length = next.second; 26 | if (distances[v] > distances[u] + length) { 27 | if (queue.find({distances[v], v}) != queue.end()) 28 | queue.erase(queue.find({distances[v], v})); 29 | distances[v] = distances[u] + length; 30 | queue.insert({distances[v], v}); 31 | } 32 | } 33 | } 34 | 35 | return distances; 36 | } 37 | 38 | int main() { 39 | cin >> n >> m; 40 | 41 | vector>> graph; 42 | graph.resize(n); 43 | 44 | for (int i = 0; i < m; ++i) { 45 | int u, v, w; 46 | cin >> u >> v >> w; 47 | graph[u - 1].push_back({v - 1, w}); 48 | graph[v - 1].push_back({u - 1, w}); 49 | } 50 | 51 | vector res = dijkstra(graph); 52 | for (int i = 0; i < res.size(); ++i) { 53 | cout << res[i] << " "; 54 | } 55 | 56 | return 0; 57 | } -------------------------------------------------------------------------------- /term 3/Graphs, Shortest paths/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | using namespace std; 7 | 8 | int n; 9 | const int INF = 100000000; 10 | const int NOEDGE = 100000; 11 | 12 | struct Edge { 13 | int u, v, w; 14 | }; 15 | 16 | vector edges; 17 | 18 | void findNegativeCycle() { 19 | vector dist(n, INF); 20 | vector p(n, -1); 21 | int x; 22 | dist[0] = 0; 23 | 24 | for (int i = 0; i < n; ++i) { 25 | x = -1; 26 | for (int j = 0; j < edges.size(); ++j) { 27 | int u = edges[j].u; 28 | int v = edges[j].v; 29 | int w = edges[j].w; 30 | if (dist[v] > dist[u] + w) { 31 | dist[v] = max(-INF, dist[u] + w); 32 | p[v] = u; 33 | x = v; 34 | } 35 | } 36 | } 37 | 38 | if (x == -1) { 39 | cout << "NO" << endl; 40 | } else { 41 | cout << "YES" << endl; 42 | vector cycle; 43 | int y = x; 44 | 45 | for (int i = 0; i < n; ++i) { 46 | y = p[y]; 47 | } 48 | 49 | for (int cur = y;; cur = p[cur]) { 50 | cycle.push_back(cur); 51 | if (cur == y && cycle.size() > 1) break; 52 | } 53 | 54 | reverse(cycle.begin(), cycle.end()); 55 | 56 | cout << cycle.size() - 1 << endl; 57 | for (int i = 1; i < cycle.size(); ++i) { 58 | cout << cycle[i] + 1; 59 | if (i != cycle.size() - 1) 60 | cout << " "; 61 | } 62 | 63 | cout << endl; 64 | } 65 | } 66 | 67 | int main() { 68 | cin >> n; 69 | 70 | for (int i = 0; i < n; ++i) { 71 | for (int j = 0; j < n; ++j) { 72 | int w; 73 | cin >> w; 74 | if (w != NOEDGE) { 75 | edges.push_back({i, j, w}); 76 | } 77 | } 78 | } 79 | 80 | findNegativeCycle(); 81 | 82 | return 0; 83 | } -------------------------------------------------------------------------------- /term 3/Graphs, Shortest paths/D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int n, m, s, k; 7 | const long long INF = (long long) 1e19; 8 | vector> dist; 9 | 10 | struct Edge { 11 | Edge(int i, int i1, long long int i2) : u(i), v(i1), w(i2) {} 12 | 13 | int u, v; 14 | long long w; 15 | }; 16 | 17 | vector edges; 18 | 19 | void findKPaths() { 20 | dist = vector>(k + 1, vector(n, INF)); 21 | dist[0][s] = 0; 22 | 23 | for (int i = 0; i < k; ++i) { 24 | for (int j = 0; j < m; ++j) { 25 | int u = edges[j].u; 26 | int v = edges[j].v; 27 | long long w = edges[j].w; 28 | if (dist[i][u] < INF) 29 | dist[i + 1][v] = min(dist[i + 1][v], dist[i][u] + w); 30 | } 31 | } 32 | } 33 | 34 | int main() { 35 | cin >> n >> m >> k >> s; 36 | s--; 37 | 38 | for (int i = 0; i < m; ++i) { 39 | int u, v; 40 | long long w; 41 | cin >> u >> v >> w; 42 | u--; 43 | v--; 44 | edges.push_back({u, v, w}); 45 | } 46 | 47 | findKPaths(); 48 | for (int i = 0; i < n; ++i) { 49 | if (dist[k][i] == INF) { 50 | cout << "-1\n"; 51 | } else cout << dist[k][i] << "\n"; 52 | } 53 | 54 | return 0; 55 | } -------------------------------------------------------------------------------- /term 3/Graphs, Shortest paths/E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | long long INF = (long long) 1e20; 8 | 9 | int n, m, s; 10 | 11 | struct Edge { 12 | int u, v; 13 | long long w; 14 | 15 | Edge(int u, int v, long long w) : u(u), v(v), w(w) {} 16 | }; 17 | 18 | vector edges; 19 | vector > graph; 20 | vector used; 21 | vector dist; 22 | 23 | void findShortestWays() { 24 | dist[s] = 0; 25 | for (int i = 0; i < n; ++i) { 26 | for (int j = 0; j < edges.size(); ++j) { 27 | int u = edges[j].u; 28 | int v = edges[j].v; 29 | long long w = edges[j].w; 30 | if ((dist[u] < INF) && (dist[v] > dist[u] + w)) { 31 | dist[v] = max(-INF, dist[u] + w); 32 | } 33 | } 34 | } 35 | } 36 | 37 | void dfs(int v) { 38 | used[v] = 1; 39 | for (int i = 0; i < graph[v].size(); ++i) { 40 | int to = graph[v][i]; 41 | if (!used[to]) 42 | dfs(to); 43 | } 44 | } 45 | 46 | int main() { 47 | cin >> n >> m >> s; 48 | s--; 49 | 50 | dist.assign(n, INF); 51 | graph.resize(n); 52 | used.resize(n); 53 | 54 | for (int i = 0; i < m; ++i) { 55 | int u, v; 56 | long long w; 57 | cin >> u >> v >> w; 58 | u--; 59 | v--; 60 | graph[u].push_back(v); 61 | edges.push_back(Edge(u, v, w)); 62 | } 63 | 64 | findShortestWays(); 65 | used.assign(n, 0); 66 | 67 | for (int i = 0; i < n; ++i) { 68 | for (int j = 0; j < edges.size(); ++j) { 69 | int u = edges[j].u; 70 | int v = edges[j].v; 71 | long long w = edges[j].w; 72 | if ((dist[u] < INF) && (dist[v] > dist[u] + w) && !used[v]) { 73 | dfs(v); 74 | } 75 | } 76 | } 77 | 78 | 79 | for (int i = 0; i < n; ++i) { 80 | if (dist[i] == INF) cout << "*\n"; 81 | else if (used[i]) cout << "-\n"; 82 | else cout << dist[i] << "\n"; 83 | } 84 | 85 | return 0; 86 | } -------------------------------------------------------------------------------- /term 3/Graphs, Shortest paths/F.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | using namespace std; 7 | 8 | 9 | int n, m, a, b, c; 10 | const long long INF = (long long) 1e18; 11 | 12 | vector dijkstra(vector>>& graph, int start) { 13 | vector distances(n, INF); 14 | distances[start] = 0; 15 | set> queue; 16 | queue.insert({0, start}); 17 | while (!queue.empty()) { 18 | auto top = queue.begin(); 19 | int u = top->second; 20 | queue.erase(top); 21 | for (auto next: graph[u]) { 22 | int v = next.first; 23 | long long length = next.second; 24 | if (distances[v] > distances[u] + length) { 25 | if (queue.find({distances[v], v}) != queue.end()) 26 | queue.erase(queue.find({distances[v], v})); 27 | distances[v] = distances[u] + length; 28 | queue.insert({distances[v], v}); 29 | } 30 | } 31 | } 32 | 33 | return distances; 34 | } 35 | 36 | int main() { 37 | cin >> n >> m; 38 | 39 | vector>> graph; 40 | graph.resize(n); 41 | 42 | for (int i = 0; i < m; ++i) { 43 | int u, v; 44 | long long w; 45 | cin >> u >> v >> w; 46 | u--; 47 | v--; 48 | graph[u].push_back({v, w}); 49 | graph[v].push_back({u, w}); 50 | } 51 | 52 | cin >> a >> b >> c; 53 | a--; 54 | b--; 55 | c--; 56 | 57 | vector distancesFromA = dijkstra(graph, a); 58 | vector distancesFromB = dijkstra(graph, b); 59 | vector distancesFromC = dijkstra(graph, c); 60 | 61 | long long res = INF; 62 | for (int i = 0; i < n; i++) { 63 | long long distanceFromAtoX = distancesFromA[i]; 64 | long long distanceFromBtoX = distancesFromB[i]; 65 | long long distanceFromCtoX = distancesFromC[i]; 66 | 67 | if (distancesFromA[i] != INF || distancesFromB[i] != INF || distancesFromC[i] != INF) { 68 | long long minDistance = min(distanceFromAtoX, distanceFromBtoX); 69 | minDistance = min(minDistance, distanceFromCtoX); 70 | if (minDistance == distanceFromAtoX) { 71 | res = min(res, 2 * minDistance + distanceFromBtoX + distanceFromCtoX); 72 | } 73 | if (minDistance == distanceFromBtoX) { 74 | res = min(res, 2 * minDistance + distanceFromAtoX + distanceFromCtoX); 75 | } 76 | if (minDistance == distanceFromCtoX) { 77 | res = min(res, 2 * minDistance + distanceFromBtoX + distanceFromAtoX); 78 | } 79 | } else continue; 80 | } 81 | 82 | if (res != INF) 83 | cout << res; 84 | else cout << "-1"; 85 | 86 | return 0; 87 | } -------------------------------------------------------------------------------- /term 3/Graphs, Shortest paths/H.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | const int maxn = 1000000 + 500; 7 | int d[maxn]; 8 | 9 | struct Node { 10 | int x, y; 11 | 12 | Node() {}; 13 | 14 | Node(int xx, int yy) : x(xx), y(yy) {}; 15 | }; 16 | 17 | vector e[maxn]; 18 | int inq[maxn]; 19 | 20 | int main() { 21 | freopen("dwarf.in", "r", stdin); 22 | freopen("dwarf.out", "w", stdout); 23 | 24 | int n, m; 25 | scanf("%d%d", &n, &m); 26 | 27 | for (int i = 1; i <= n; i++) 28 | scanf("%d", &d[i]); 29 | 30 | for (int i = 1; i <= m; i++) { 31 | int a, u, v; 32 | scanf("%d%d%d", &a, &u, &v); 33 | e[u].push_back(Node(v, a)); 34 | e[v].push_back(Node(u, a)); 35 | } 36 | 37 | queue q; 38 | for (int i = 1; i <= n; i++) { 39 | q.push(i); 40 | inq[i] = 1; 41 | } 42 | 43 | while (!q.empty()) { 44 | int now = q.front(); 45 | q.pop(); 46 | inq[now] = 0; 47 | for (int i = 0; i < e[now].size(); i++) { 48 | Node temp = e[now][i]; 49 | if (d[temp.y] > d[temp.x] + d[now]) { 50 | d[temp.y] = d[temp.x] + d[now]; 51 | if (!inq[temp.y]) 52 | q.push(temp.y); 53 | inq[temp.y] = 1; 54 | } 55 | } 56 | } 57 | 58 | printf("%d\n", d[1]); 59 | 60 | } 61 | -------------------------------------------------------------------------------- /term 3/Strings/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | using namespace std; 6 | 7 | size_t m; 8 | string s; 9 | const long long PRIME = 1000000009; 10 | vector primePows; 11 | vector hashes; 12 | 13 | unsigned long long getHash(int l, int r) { 14 | return hashes[r + 1] - hashes[l] * primePows[r - l + 1]; 15 | } 16 | 17 | bool checkTwoSubs(int a, int b, int c, int d) { 18 | return getHash(a, b) == getHash(c, d); 19 | } 20 | 21 | 22 | int main() { 23 | ios_base::sync_with_stdio(false); 24 | 25 | cin >> s; 26 | cin >> m; 27 | 28 | hashes.resize(s.length() + 1); 29 | primePows.resize(s.length() + 1); 30 | 31 | hashes[0] = 0; 32 | primePows[0] = 1; 33 | 34 | for (int i = 0; i < s.length(); ++i) { 35 | hashes[i + 1] = hashes[i] * PRIME + s[i]; 36 | primePows[i + 1] = primePows[i] * PRIME; 37 | } 38 | 39 | for (int i = 0; i < m; ++i) { 40 | int a, b, c, d; 41 | cin >> a >> b >> c >> d; 42 | a--; 43 | b--; 44 | c--; 45 | d--; 46 | cout << (checkTwoSubs(a, b, c, d) ? "Yes\n" : "No\n"); 47 | } 48 | 49 | return 0; 50 | } -------------------------------------------------------------------------------- /term 3/Strings/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | vector prefixFunction(const string& s) { 7 | size_t n = s.length(); 8 | vector prefix(n); 9 | prefix[0] = 0; 10 | 11 | for (int i = 1; i < n; ++i) { 12 | int j = prefix[i - 1]; 13 | while (j > 0 && s[i] != s[j]) { 14 | j = prefix[j - 1]; 15 | } 16 | if (s[i] == s[j]) { 17 | ++j; 18 | }; 19 | prefix[i] = j; 20 | } 21 | 22 | return prefix; 23 | } 24 | 25 | 26 | int main() { 27 | ios_base::sync_with_stdio(false); 28 | 29 | string s; 30 | cin >> s; 31 | 32 | vector res = prefixFunction(s); 33 | 34 | for (int i = 0; i < res.size(); ++i) { 35 | cout << res[i] << " "; 36 | } 37 | return 0; 38 | } -------------------------------------------------------------------------------- /term 3/Strings/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | using namespace std; 6 | 7 | vector zFunction(const string& s) { 8 | size_t n = s.length(); 9 | vector z(n); 10 | z[0] = 0; 11 | 12 | int left = 0; 13 | int right = 0; 14 | for (int i = 1; i < n; ++i) { 15 | if (i <= right) { 16 | z[i] = min(right - i + 1, z[i - left]); 17 | } 18 | while (i + z[i] < n && s[z[i]] == s[i + z[i]]) { 19 | z[i]++; 20 | } 21 | if (i + z[i] - 1 > right) { 22 | left = i; 23 | right = i + z[i] - 1; 24 | } 25 | } 26 | return z; 27 | } 28 | 29 | int main() { 30 | ios_base::sync_with_stdio(false); 31 | 32 | string s; 33 | cin >> s; 34 | 35 | vector res = zFunction(s); 36 | 37 | for (int i = 1; i < res.size(); ++i) { 38 | cout << res[i] << " "; 39 | } 40 | return 0; 41 | } -------------------------------------------------------------------------------- /term 3/Strings/D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | using namespace std; 6 | 7 | vector prefixFunction(const string& s) { 8 | size_t n = s.length(); 9 | vector prefix(n); 10 | prefix[0] = 0; 11 | 12 | for (int i = 1; i < n; ++i) { 13 | int j = prefix[i - 1]; 14 | while (j > 0 && s[i] != s[j]) { 15 | j = prefix[j - 1]; 16 | } 17 | if (s[i] == s[j]) { 18 | ++j; 19 | }; 20 | prefix[i] = j; 21 | } 22 | 23 | return prefix; 24 | } 25 | 26 | vector KMP(const string& pattern, const string& text) { 27 | int pSize = pattern.length(); 28 | int tSize = text.length(); 29 | vector prefix = prefixFunction(pattern + "#" + text); 30 | vector res; 31 | 32 | for (int i = pSize; i < pSize + 1 + tSize; ++i) { 33 | if (prefix[i] == pSize) { 34 | res.push_back(i - pSize * 2 + 1); 35 | } 36 | } 37 | 38 | return res; 39 | } 40 | 41 | int main() { 42 | ios_base::sync_with_stdio(false); 43 | 44 | string p, t; 45 | cin >> p >> t; 46 | 47 | vector res = KMP(p, t); 48 | 49 | cout << res.size() << "\n"; 50 | for (int i = 0; i < res.size(); ++i) { 51 | cout << res[i] << " "; 52 | } 53 | 54 | return 0; 55 | } -------------------------------------------------------------------------------- /term 3/Strings/E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | using namespace std; 6 | 7 | vector zFunction(const string& s) { 8 | size_t n = s.size(); 9 | vector z(n); 10 | z[0] = 0; 11 | 12 | int left = 0; 13 | int right = 0; 14 | for (int i = 1; i < n; ++i) { 15 | if (i <= right) { 16 | z[i] = min(right - i + 1, z[i - left]); 17 | } 18 | while (i + z[i] < n && s[z[i]] == s[i + z[i]]) { 19 | z[i]++; 20 | } 21 | if (i + z[i] - 1 > right) { 22 | left = i; 23 | right = i + z[i] - 1; 24 | } 25 | } 26 | return z; 27 | } 28 | 29 | int findLengthOfPeriod(const string& s) { 30 | size_t n = s.size(); 31 | vector z = zFunction(s); 32 | int period = n; 33 | 34 | for (int i = 1; i < n; ++i) { 35 | if (n % i == 0 && z[i] == n - i) { 36 | period = i; 37 | break; 38 | } 39 | } 40 | 41 | return period; 42 | } 43 | 44 | 45 | int main() { 46 | ios_base::sync_with_stdio(false); 47 | 48 | string s; 49 | cin >> s; 50 | 51 | cout << findLengthOfPeriod(s); 52 | return 0; 53 | } -------------------------------------------------------------------------------- /term 3/Strings/G.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | struct Automata { 8 | Automata() { 9 | nodes.emplace_back(); 10 | } 11 | 12 | struct Node { 13 | int next[26]; 14 | vector terminant; 15 | 16 | int sLink; 17 | int ssLink; 18 | }; 19 | 20 | vector nodes; 21 | size_t size = 0; 22 | 23 | void add(const string& s) { 24 | int cur = 0; 25 | 26 | for (char i : s) { 27 | int nextC = i - 'a'; 28 | 29 | if (!nodes[cur].next[nextC]) { 30 | nodes.emplace_back(); 31 | nodes[cur].next[nextC] = (int) nodes.size() - 1; 32 | } 33 | 34 | cur = nodes[cur].next[nextC]; 35 | } 36 | 37 | nodes[cur].terminant.push_back(size++); 38 | } 39 | 40 | void build() { 41 | queue q; 42 | 43 | q.push(0); 44 | 45 | while (!q.empty()) { 46 | int cur = q.front(); 47 | q.pop(); 48 | 49 | for (int i = 0; i < 26; ++i) { 50 | if (!nodes[cur].next[i]) { 51 | nodes[cur].next[i] = nodes[nodes[cur].sLink].next[i]; 52 | } else { 53 | int next = nodes[cur].next[i]; 54 | 55 | if (cur) { 56 | nodes[next].sLink = nodes[nodes[cur].sLink].next[i]; 57 | nodes[next].ssLink = !nodes[nodes[next].sLink].terminant.empty() ? nodes[next].sLink 58 | : nodes[nodes[next].sLink].ssLink; 59 | } 60 | 61 | q.push(next); 62 | } 63 | } 64 | } 65 | } 66 | 67 | vector findOccur(string& t) { 68 | vector occur(size); 69 | vector found(nodes.size()); 70 | 71 | int cur = 0; 72 | for (char i : t) { 73 | cur = nodes[cur].next[i - 'a']; 74 | 75 | int tmp = cur; 76 | 77 | while (!found[tmp]) { 78 | if (!nodes[tmp].terminant.empty()) { 79 | for (auto&& ends : nodes[tmp].terminant) 80 | occur[ends] = true; 81 | } 82 | 83 | found[tmp] = true; 84 | tmp = nodes[tmp].ssLink; 85 | } 86 | } 87 | return occur; 88 | } 89 | }; 90 | 91 | Automata a; 92 | int n; 93 | 94 | 95 | int main() { 96 | freopen("search4.in", "r", stdin); 97 | freopen("search4.out", "w", stdout); 98 | 99 | ios_base::sync_with_stdio(false); 100 | cin.tie(nullptr); 101 | 102 | cin >> n; 103 | 104 | string s, t; 105 | 106 | for (int i = 0; i < n; ++i) { 107 | cin >> s; 108 | a.add(s); 109 | } 110 | 111 | cin >> t; 112 | a.build(); 113 | 114 | vector ans = a.findOccur(t); 115 | 116 | for (auto&& an : ans) { 117 | cout << (an ? "YES\n" : "NO\n"); 118 | } 119 | 120 | return 0; 121 | } -------------------------------------------------------------------------------- /term 3/Strings/J.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | using namespace std; 7 | 8 | const size_t alphabet = 256; 9 | 10 | struct SuffixArray { 11 | explicit SuffixArray(const string& str) : s(str), permutation(str.size()) { 12 | s.push_back(1); 13 | size_t n = s.size(); 14 | 15 | vector classes(n), pm(n), count(max(n, alphabet)); 16 | 17 | for (int i = 0; i < n; ++i) { 18 | count[s[i]]++; 19 | } 20 | 21 | for (int i = 1; i < alphabet; ++i) { 22 | count[i] += count[i - 1]; 23 | } 24 | 25 | for (int i = 0; i < n; ++i) { 26 | pm[--count[s[i]]] = i; 27 | } 28 | 29 | classes[pm[0]] = 0; 30 | int numberCl = 1; 31 | for (int i = 1; i < n; i++) { 32 | if (s[pm[i]] != s[pm[i - 1]]) { 33 | numberCl++; 34 | } 35 | classes[pm[i]] = numberCl - 1; 36 | } 37 | 38 | vector npm(n), nclasses(n); 39 | for (int j = 0; (1 << j) < n; ++j) { 40 | int len = 1 << j; 41 | 42 | for (int i = 0; i < n; ++i) { 43 | npm[i] = pm[i] - len; 44 | if (npm[i] < 0) { 45 | npm[i] += n; 46 | } 47 | } 48 | 49 | fill(count.begin(), count.begin() + numberCl, 0); 50 | for (int i = 0; i < n; ++i) { 51 | count[classes[npm[i]]]++; 52 | } 53 | 54 | for (int i = 1; i < numberCl; ++i) { 55 | count[i] += count[i - 1]; 56 | } 57 | 58 | for (int i = n - 1; i >= 0; i--) { 59 | pm[--count[classes[npm[i]]]] = npm[i]; 60 | } 61 | 62 | nclasses[pm[0]] = 0; 63 | numberCl = 1; 64 | for (int i = 1; i < n; ++i) { 65 | pair current = {classes[pm[i]], classes[(pm[i] + (1 << j)) % n]}; 66 | pair prev = {classes[pm[i - 1]], classes[(pm[i - 1] + (1 << j)) % n]}; 67 | if (current != prev) { 68 | numberCl++; 69 | } 70 | nclasses[pm[i]] = numberCl - 1; 71 | } 72 | classes.swap(nclasses); 73 | } 74 | 75 | for (int i = 0; i < n - 1; ++i) { 76 | permutation[i] = pm[i + 1]; 77 | } 78 | s.pop_back(); 79 | } 80 | 81 | vector kasaiLCP() { 82 | size_t n = permutation.size(); 83 | 84 | vector r(n), res(n - 1); 85 | for (int i = 0; i < n; ++i) { 86 | r[permutation[i]] = i; 87 | } 88 | 89 | s.push_back(1); 90 | 91 | int current = 0; 92 | for (int i = 0; i < n; ++i) { 93 | if (current > 0) { 94 | --current; 95 | } 96 | if (r[i] == n - 1) { 97 | current = 0; 98 | } else { 99 | while (s[i + current] == s[permutation[r[i] + 1] + current]) { 100 | current++; 101 | } 102 | res[r[i]] = current; 103 | } 104 | } 105 | s.pop_back(); 106 | 107 | return res; 108 | } 109 | 110 | void print() { 111 | for (int i : permutation) { 112 | cout << i + 1 << " "; 113 | } 114 | cout << "\n"; 115 | } 116 | 117 | string s; 118 | vector permutation; 119 | }; 120 | 121 | 122 | int main() { 123 | freopen("array.in", "r", stdin); 124 | freopen("array.out", "w", stdout); 125 | 126 | ios_base::sync_with_stdio(false); 127 | 128 | string s; 129 | cin >> s; 130 | 131 | SuffixArray suffixArray(s); 132 | vector lcp = suffixArray.kasaiLCP(); 133 | 134 | suffixArray.print(); 135 | for (int i : lcp) { 136 | cout << i << " "; 137 | } 138 | 139 | return 0; 140 | } -------------------------------------------------------------------------------- /term 3/Strings/L.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | using namespace std; 7 | 8 | const size_t alphabet = 256; 9 | 10 | string kthShift(const string& s, int k) { 11 | size_t n = s.size(); 12 | vector classes(n), pm(n), count(max(n, alphabet)); 13 | 14 | for (int i = 0; i < n; ++i) { 15 | count[s[i]]++; 16 | } 17 | 18 | for (int i = 1; i < alphabet; ++i) { 19 | count[i] += count[i - 1]; 20 | } 21 | 22 | for (int i = 0; i < n; ++i) { 23 | pm[--count[s[i]]] = i; 24 | } 25 | 26 | classes[pm[0]] = 0; 27 | int numberCl = 1; 28 | for (int i = 1; i < n; i++) { 29 | if (s[pm[i]] != s[pm[i - 1]]) { 30 | numberCl++; 31 | } 32 | classes[pm[i]] = numberCl - 1; 33 | } 34 | 35 | vector npm(n), nclasses(n); 36 | for (int j = 0; (1 << j) < n; ++j) { 37 | int len = 1 << j; 38 | 39 | for (int i = 0; i < n; ++i) { 40 | npm[i] = pm[i] - len; 41 | if (npm[i] < 0) { 42 | npm[i] += n; 43 | } 44 | } 45 | 46 | fill(count.begin(), count.begin() + numberCl, 0); 47 | for (int i = 0; i < n; ++i) { 48 | count[classes[npm[i]]]++; 49 | } 50 | 51 | for (int i = 1; i < numberCl; ++i) { 52 | count[i] += count[i - 1]; 53 | } 54 | 55 | for (int i = n - 1; i >= 0; i--) { 56 | pm[--count[classes[npm[i]]]] = npm[i]; 57 | } 58 | 59 | nclasses[pm[0]] = 0; 60 | numberCl = 1; 61 | for (int i = 1; i < n; ++i) { 62 | pair current = {classes[pm[i]], classes[(pm[i] + (1 << j)) % n]}; 63 | pair prev = {classes[pm[i - 1]], classes[(pm[i - 1] + (1 << j)) % n]}; 64 | if (current != prev) { 65 | numberCl++; 66 | } 67 | nclasses[pm[i]] = numberCl - 1; 68 | } 69 | classes.swap(nclasses); 70 | } 71 | 72 | vector used(n, false); 73 | 74 | int cur = -1; 75 | if (k >= n) { 76 | return "IMPOSSIBLE"; 77 | } 78 | 79 | for (int i = 0; i < n; ++i) { 80 | if (!used[classes[pm[i]]]) { 81 | used[classes[pm[i]]] = true; 82 | cur++; 83 | } 84 | 85 | if (cur == k) { 86 | string res = s.substr(pm[i], n - (pm[i])) + s.substr(0, pm[i]); 87 | return res; 88 | } 89 | } 90 | 91 | return "IMPOSSIBLE"; 92 | } 93 | 94 | 95 | int main() { 96 | freopen("shifts.in", "r", stdin); 97 | freopen("shifts.out", "w", stdout); 98 | 99 | ios_base::sync_with_stdio(false); 100 | 101 | string s; 102 | int k; 103 | 104 | cin >> s >> k; 105 | k--; 106 | 107 | cout << kthShift(s, k); 108 | 109 | return 0; 110 | } -------------------------------------------------------------------------------- /term 4/Flows and matchings/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | const int INF = 0x3F3F3F3F; 6 | size_t n, m; 7 | int s, t; 8 | std::vector> graph; 9 | std::vector d, p; 10 | std::queue q; 11 | 12 | struct Edge { 13 | int a, b, c, f; 14 | }; 15 | std::vector edges; 16 | 17 | int dfs(int u, int flow) { 18 | if (u == t || flow == 0) { 19 | return flow; 20 | } 21 | for (; p[u] < graph[u].size(); ++p[u]) { 22 | int id = graph[u][p[u]]; 23 | int v = edges[id].b; 24 | if (d[v] == d[u] + 1) { 25 | int pushed = dfs(v, std::min(flow, edges[id].c - edges[id].f)); 26 | if (pushed) { 27 | edges[id].f += pushed; 28 | edges[id ^ 1].f -= pushed; 29 | return pushed; 30 | } 31 | } 32 | } 33 | return 0; 34 | } 35 | 36 | bool bfs() { 37 | d.assign(n, INF); 38 | d[s] = 0; 39 | q.push(s); 40 | while (!q.empty()) { 41 | int u = q.front(); 42 | q.pop(); 43 | for (int i = 0; i < graph[u].size(); ++i) { 44 | int id = graph[u][i];//number of edge (uv) 45 | int v = edges[id].b; 46 | 47 | if (d[v] == INF && edges[id].f < edges[id].c) { 48 | d[v] = d[u] + 1; 49 | q.push(v); 50 | } 51 | } 52 | } 53 | return d[t] != INF; 54 | } 55 | 56 | int algoDinic() { 57 | int flow = 0; 58 | while (bfs()) { 59 | p.assign(n, 0); 60 | int f = dfs(s, INF); 61 | while (f) { 62 | flow += f; 63 | f = dfs(s, INF); 64 | } 65 | } 66 | return flow; 67 | } 68 | 69 | int main() { 70 | std::cin >> n >> m; 71 | graph.resize(n); 72 | d.resize(n); 73 | p.resize(n); 74 | s = 0; 75 | t = n - 1; 76 | 77 | for (int i = 0; i < m; ++i) { 78 | int ai, bi, ci; 79 | std::cin >> ai >> bi >> ci; 80 | ai--; 81 | bi--; 82 | 83 | graph[ai].push_back(edges.size()); 84 | edges.push_back({ai, bi, ci, 0}); 85 | graph[bi].push_back(edges.size()); 86 | edges.push_back({bi, ai, ci, 0}); 87 | } 88 | 89 | int res = algoDinic(); 90 | 91 | std::cout << res << "\n"; 92 | 93 | for (int i = 0; i < 2 * m; i += 2) { 94 | std::cout << edges[i].f << "\n"; 95 | } 96 | return 0; 97 | } -------------------------------------------------------------------------------- /term 4/Flows and matchings/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | const int INF = 0x3F3F3F3F; 6 | size_t n, m; 7 | int s, t; 8 | std::vector> graph; 9 | std::vector d, p; 10 | std::queue q; 11 | std::vector reached; 12 | struct Edge { 13 | int a, b, c, f; 14 | }; 15 | std::vector edges; 16 | 17 | void dfs(int v) { 18 | reached[v] = true; 19 | 20 | for (int &edge : graph[v]) { 21 | if (edges[edge].f < edges[edge].c && !reached[edges[edge].b]) { 22 | dfs(edges[edge].b); 23 | } 24 | } 25 | } 26 | 27 | int dfs(int u, int flow) { 28 | if (u == t || flow == 0) { 29 | return flow; 30 | } 31 | for (; p[u] < graph[u].size(); ++p[u]) { 32 | int id = graph[u][p[u]]; 33 | int v = edges[id].b; 34 | if (d[v] == d[u] + 1) { 35 | int pushed = dfs(v, std::min(flow, edges[id].c - edges[id].f)); 36 | if (pushed) { 37 | edges[id].f += pushed; 38 | edges[id ^ 1].f -= pushed; 39 | return pushed; 40 | } 41 | } 42 | } 43 | return 0; 44 | } 45 | 46 | bool bfs() { 47 | d.assign(n, INF); 48 | d[s] = 0; 49 | q.push(s); 50 | while (!q.empty()) { 51 | int u = q.front(); 52 | q.pop(); 53 | for (int i = 0; i < graph[u].size(); ++i) { 54 | int id = graph[u][i];//number of edge (uv) 55 | int v = edges[id].b; 56 | 57 | if (d[v] == INF && edges[id].f < edges[id].c) { 58 | d[v] = d[u] + 1; 59 | q.push(v); 60 | } 61 | } 62 | } 63 | return d[t] != INF; 64 | } 65 | 66 | long long algoDinic() { 67 | long long flow = 0; 68 | while (bfs()) { 69 | p.assign(n, 0); 70 | int f = dfs(s, INF); 71 | while (f) { 72 | flow += f; 73 | f = dfs(s, INF); 74 | } 75 | } 76 | return flow; 77 | } 78 | 79 | int main() { 80 | std::cin >> n >> m; 81 | graph.resize(n); 82 | d.resize(n); 83 | p.resize(n); 84 | reached.assign(n, false); 85 | s = 0; 86 | t = n - 1; 87 | 88 | for (int i = 0; i < m; ++i) { 89 | int ai, bi, ci; 90 | std::cin >> ai >> bi >> ci; 91 | ai--; 92 | bi--; 93 | 94 | graph[ai].push_back(edges.size()); 95 | edges.push_back({ai, bi, ci, 0}); 96 | graph[bi].push_back(edges.size()); 97 | edges.push_back({bi, ai, ci, 0}); 98 | } 99 | 100 | long long minCutFlow = algoDinic(); 101 | std::vector cut; 102 | 103 | dfs(s); 104 | for (int i = 0; i < 2 * m; i += 2) { 105 | if ((reached[edges[i].a] && !reached[edges[i].b]) || (!reached[edges[i].a] && reached[edges[i].b])) { 106 | cut.push_back(i / 2); 107 | } 108 | } 109 | 110 | std::cout << cut.size() << " " << minCutFlow << "\n"; 111 | 112 | for (int i : cut) { 113 | std::cout << i + 1 << " "; 114 | } 115 | 116 | return 0; 117 | } -------------------------------------------------------------------------------- /term 4/Flows and matchings/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | const int INF = 0x3F3F3F3F; 7 | size_t n, m; 8 | int s, t; 9 | std::vector> graph; 10 | std::vector d, p, path; 11 | std::queue q; 12 | std::vector used; 13 | 14 | struct Edge { 15 | int a, b, c, f; 16 | }; 17 | std::vector edges; 18 | 19 | int dfs(int u, int flow) { 20 | if (u == t || flow == 0) { 21 | return flow; 22 | } 23 | for (; p[u] < graph[u].size(); ++p[u]) { 24 | int id = graph[u][p[u]]; 25 | int v = edges[id].b; 26 | if (d[v] == d[u] + 1) { 27 | int pushed = dfs(v, std::min(flow, edges[id].c - edges[id].f)); 28 | if (pushed) { 29 | edges[id].f += pushed; 30 | edges[id ^ 1].f -= pushed; 31 | return pushed; 32 | } 33 | } 34 | } 35 | return 0; 36 | } 37 | 38 | bool bfs() { 39 | d.assign(n, INF); 40 | d[s] = 0; 41 | q.push(s); 42 | while (!q.empty()) { 43 | int u = q.front(); 44 | q.pop(); 45 | for (int i = 0; i < graph[u].size(); ++i) { 46 | int id = graph[u][i];//number of edge (uv) 47 | int v = edges[id].b; 48 | 49 | if (d[v] == INF && edges[id].f < edges[id].c) { 50 | d[v] = d[u] + 1; 51 | q.push(v); 52 | } 53 | } 54 | } 55 | return d[t] != INF; 56 | } 57 | 58 | int algoDinic() { 59 | int flow = 0; 60 | while (bfs()) { 61 | p.assign(n, 0); 62 | int f = dfs(s, INF); 63 | while (f) { 64 | flow += f; 65 | f = dfs(s, INF); 66 | } 67 | } 68 | return flow; 69 | } 70 | 71 | void dfs2(int u) { 72 | path.push_back(u); 73 | 74 | if (u == t) { 75 | return; 76 | } 77 | 78 | for (int id : graph[u]) { 79 | int v = edges[id].b; 80 | 81 | if (!used[id] && edges[id].f == 1) { 82 | used[id] = true; 83 | dfs2(v); 84 | break; 85 | } 86 | } 87 | } 88 | 89 | void printPath() { 90 | dfs2(s); 91 | 92 | for (int i : path) { 93 | std::cout << i + 1 << " "; 94 | } 95 | std::cout << "\n"; 96 | 97 | path.clear(); 98 | } 99 | 100 | int main() { 101 | std::cin >> n >> m; 102 | graph.resize(n); 103 | d.resize(n); 104 | p.resize(n); 105 | std::cin >> s >> t; 106 | s--; 107 | t--; 108 | 109 | for (int i = 0; i < m; ++i) { 110 | int ai, bi; 111 | std::cin >> ai >> bi; 112 | ai--; 113 | bi--; 114 | 115 | 116 | graph[ai].push_back(edges.size()); 117 | edges.push_back({ai, bi, 1, 0}); 118 | graph[bi].push_back(edges.size()); 119 | edges.push_back({bi, ai, 0, 0}); 120 | } 121 | 122 | int maxFlow = algoDinic(); 123 | 124 | if (maxFlow < 2) { 125 | std::cout << "NO"; 126 | } else { 127 | std::cout << "YES\n"; 128 | 129 | used.assign(2 * m, false); 130 | 131 | printPath(); 132 | 133 | printPath(); 134 | } 135 | return 0; 136 | } -------------------------------------------------------------------------------- /term 4/Flows and matchings/D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | size_t n, m; 5 | std::vector> graph; 6 | std::vector matching; 7 | std::vector used; 8 | 9 | bool kuhn(int u) { 10 | if (used[u]) { 11 | return false; 12 | } 13 | used[u] = true; 14 | for (int i = 0; i < graph[u].size(); ++i) { 15 | int v = graph[u][i]; 16 | if (matching[v] == -1 || kuhn(matching[v])) { 17 | matching[v] = u; 18 | return true; 19 | } 20 | } 21 | return false; 22 | } 23 | 24 | int main() { 25 | std::cin >> n >> m; 26 | graph.resize(n); 27 | matching.assign(m, -1); 28 | 29 | for (int i = 0; i < n; ++i) { 30 | int v; 31 | std::cin >> v; 32 | while (v != 0) { 33 | graph[i].push_back(v - 1); 34 | std::cin >> v; 35 | } 36 | } 37 | 38 | for (int i = 0; i < n; ++i) { 39 | used.assign(n, false); 40 | kuhn(i); 41 | } 42 | 43 | int count = 0; 44 | for (int i = 0; i < m; ++i) { 45 | if (matching[i] != -1) { 46 | count++; 47 | } 48 | } 49 | 50 | std::cout << count << "\n"; 51 | 52 | for (int i = 0; i < m; ++i) { 53 | if (matching[i] != -1) { 54 | std::cout << matching[i] + 1 << " " << i + 1 << "\n"; 55 | } 56 | } 57 | return 0; 58 | } -------------------------------------------------------------------------------- /term 4/Flows and matchings/E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | const int MAXN = 101; 6 | const int MAXM = 101; 7 | 8 | size_t n, m; 9 | int type; 10 | 11 | struct Edge { 12 | int to; 13 | int x, y; 14 | int colour = 0; 15 | 16 | Edge* reversed; 17 | 18 | Edge(int to, int x, int y, int colour) : to(to), x(x), y(y), colour(colour) {} 19 | }; 20 | 21 | struct Square { 22 | int diagonalType; 23 | int x, y; 24 | }; 25 | std::vector> edges; 26 | std::vector> table; 27 | std::vector used; 28 | std::vector answer; 29 | 30 | void addEdge(int from, int to, int i, int j) { 31 | Edge* edge = new Edge(to, i, j, 1); 32 | Edge* reversed = new Edge(from, i, j, 0); 33 | 34 | edge->reversed = reversed; 35 | reversed->reversed = edge; 36 | 37 | edges[from].push_back(edge); 38 | edges[to].push_back(reversed); 39 | } 40 | 41 | bool kuhn(int v) { 42 | if (v == 4 * (n + m)) { 43 | return true; 44 | } 45 | used[v] = true; 46 | 47 | for (Edge* edge : edges[v]) { 48 | if (edge->colour == 1 && !used[edge->to] && kuhn(edge->to)) { 49 | edge->colour = 0; 50 | edge->reversed->colour = 1; 51 | return true; 52 | } 53 | } 54 | 55 | return false; 56 | } 57 | 58 | std::vector getCover() { 59 | edges.assign(4 * (MAXM + MAXN), std::vector()); 60 | int count = 0; 61 | 62 | for (int i = 0; i < n; ++i) { 63 | for (int j = 0; j < m; ++j) { 64 | if (table[i][j] == 1) { 65 | addEdge(i - j + n + m, i + j + 2 * (m + n), i + 1, j + 1); 66 | } 67 | } 68 | } 69 | 70 | for (int i = 1; i < 2 * (n + m); ++i) { 71 | addEdge(0, i, i + 1, i + 1); 72 | } 73 | 74 | for (int i = 2 * (n + m); i < 4 * (n + m); ++i) { 75 | addEdge(i, 4 * (n + m), i + 1, i + 1); 76 | } 77 | 78 | while (true) { 79 | used.assign(4 * (MAXN + MAXM), false); 80 | if (!kuhn(0)) { 81 | break; 82 | } 83 | count++; 84 | } 85 | 86 | std::vector res(count, {0, 0, 0}); 87 | int t = 0; 88 | 89 | for (int i = 0; i < 2 * (n + m); ++i) { 90 | if (!used[i]) { 91 | for (Edge* edge : edges[i]) { 92 | if (edge->to != 0) { 93 | res[t] = {2, edge->x, edge->y}; 94 | t++; 95 | break; 96 | } 97 | } 98 | } 99 | } 100 | 101 | for (int i = 2 * (n + m); i < 4 * (n + m); ++i) { 102 | if (used[i]) { 103 | for (Edge* edge : edges[i]) { 104 | if (edge->to != 4 * (n + m)) { 105 | res[t] = {1, edge->x, edge->y}; 106 | t++; 107 | break; 108 | } 109 | } 110 | } 111 | } 112 | 113 | return res; 114 | } 115 | 116 | void swapColour() { 117 | for (int i = 0; i < n; ++i) { 118 | for (int j = 0; j < m; ++j) { 119 | table[i][j] = 1 - table[i][j]; 120 | } 121 | } 122 | } 123 | 124 | void solve() { 125 | std::vector firstCover = getCover(); 126 | swapColour(); 127 | std::vector secondCover = getCover(); 128 | 129 | if (secondCover.size() > firstCover.size()) { 130 | answer = firstCover; 131 | type = 0; 132 | } else { 133 | answer = secondCover; 134 | type = 1; 135 | } 136 | } 137 | 138 | int main() { 139 | std::cin >> n >> m; 140 | edges.resize(4 * (MAXM + MAXN), std::vector()); 141 | table.resize((MAXN), std::vector(MAXM)); 142 | used.resize(4 * (MAXM + MAXM)); 143 | 144 | for (int i = 0; i < n; ++i) { 145 | std::string line; 146 | std::cin >> line; 147 | for (int j = 0; j < m; ++j) { 148 | if (line[j] == 'W') { 149 | table[i][j] = (i + j) % 2; 150 | } else { 151 | table[i][j] = abs((i + j) % 2 - 1); 152 | } 153 | } 154 | } 155 | 156 | solve(); 157 | 158 | std::cout << answer.size() << "\n"; 159 | 160 | for (Square& square : answer) { 161 | std::cout << square.diagonalType << " " 162 | << square.x << " " << square.y << " " 163 | << (((square.x + square.y) % 2 == type) ? 'W' : 'B') << "\n"; 164 | } 165 | return 0; 166 | } -------------------------------------------------------------------------------- /term 4/Flows and matchings/F.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | const double MAXTIME = 2000.0; 6 | size_t n; 7 | std::vector> graph; 8 | std::vector matching; 9 | std::vector used; 10 | 11 | struct Point { 12 | int x; 13 | int y; 14 | }; 15 | std::vector itemPoints; 16 | std::vector destinationPoints; 17 | 18 | std::vector speeds; 19 | double minTime; 20 | 21 | double getTime(int itemNum, int dNum) { 22 | return std::sqrt( 23 | (itemPoints[itemNum].x - destinationPoints[dNum].x) * (itemPoints[itemNum].x - destinationPoints[dNum].x) 24 | + (itemPoints[itemNum].y - destinationPoints[dNum].y) * (itemPoints[itemNum].y - destinationPoints[dNum].y) 25 | ) / speeds[itemNum]; 26 | } 27 | 28 | bool kuhn(int u) { 29 | if (used[u]) { 30 | return false; 31 | } 32 | used[u] = true; 33 | for (int i = 0; i < graph[u].size(); ++i) { 34 | int v = graph[u][i]; 35 | double edgeTime = getTime(u, v); 36 | if (edgeTime <= minTime) { 37 | if (matching[v] == -1 || kuhn(matching[v])) { 38 | matching[v] = u; 39 | return true; 40 | } 41 | } 42 | } 43 | return false; 44 | } 45 | 46 | bool isComplete() { 47 | int count = 0; 48 | for (int i = 0; i < n; ++i) { 49 | if (matching[i] != -1) { 50 | count++; 51 | } 52 | } 53 | return count == n; 54 | } 55 | 56 | void buildMatching() { 57 | matching.assign(n, -1); 58 | 59 | for (int i = 0; i < n; ++i) { 60 | used.assign(n, false); 61 | kuhn(i); 62 | } 63 | } 64 | 65 | void kuhnBinSearch() { 66 | minTime = MAXTIME; 67 | double left = 0; 68 | double right = MAXTIME; 69 | while (right - left > 0.0001/2) { 70 | minTime = (left + right) / 2; 71 | buildMatching(); 72 | if (isComplete()) { 73 | right = minTime; 74 | } else { 75 | left = minTime; 76 | } 77 | } 78 | } 79 | 80 | 81 | int main() { 82 | std::cin >> n; 83 | graph.resize(n); 84 | 85 | for (int i = 0; i < n; ++i) { 86 | int x, y, speed; 87 | 88 | std::cin >> x >> y >> speed; 89 | 90 | itemPoints.push_back({x, y}); 91 | speeds.push_back(speed); 92 | 93 | for (int j = 0; j < n; ++j) { 94 | graph[i].push_back(j); 95 | } 96 | } 97 | 98 | for (int i = 0; i < n; ++i) { 99 | int x, y; 100 | 101 | std::cin >> x >> y; 102 | 103 | destinationPoints.push_back({x, y}); 104 | } 105 | 106 | kuhnBinSearch(); 107 | std::cout << minTime << "\n"; 108 | return 0; 109 | } -------------------------------------------------------------------------------- /term 4/Flows and matchings/H.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | 14 | const int MAXN = 5555; 15 | const int MAXNM = 100000; 16 | const int INF = 1000000000; 17 | 18 | struct Edge { 19 | int u, v, cap, flow, next; 20 | }; 21 | vector edges; 22 | int currentCapacity; 23 | vector h, d, cur; 24 | vector visited; 25 | 26 | void add(int u, int v, int cap) { 27 | edges[currentCapacity] = {u, v, cap, 0, h[u]}; 28 | h[u] = currentCapacity++; 29 | edges[currentCapacity] = {v, u, 0, 0, h[v]}; 30 | h[v] = currentCapacity++; 31 | } 32 | 33 | 34 | bool bfs(int s, int t) { 35 | queue q; 36 | visited.assign(MAXN, false); 37 | d[s] = 0; 38 | visited[s] = true; 39 | q.push(s); 40 | while (!q.empty()) { 41 | int u = q.front(); 42 | q.pop(); 43 | for (int i = h[u]; i != -1; i = edges[i].next) { 44 | int v = edges[i].v; 45 | 46 | if (!visited[v] && edges[i].cap > edges[i].flow) { 47 | visited[v] = true; 48 | d[v] = d[u] + 1; 49 | q.push(v); 50 | } 51 | } 52 | } 53 | return visited[t]; 54 | } 55 | 56 | int dfs(int u, int a, int t) { 57 | if (u == t || a == 0) { 58 | return a; 59 | } 60 | int flow = 0; 61 | for (int &i = cur[u]; i != -1; i = edges[i].next) { 62 | int v = edges[i].v, &ef = edges[i].flow, cap = edges[i].cap; 63 | if (d[v] == d[u] + 1) { 64 | int pushed = dfs(v, min(a, edges[i].cap - edges[i].flow), t); 65 | if (pushed) { 66 | a -= pushed; 67 | flow += pushed; 68 | edges[i].flow += pushed; 69 | edges[i ^ 1].flow -= pushed; 70 | if (a == 0) break; 71 | } 72 | } 73 | } 74 | return flow; 75 | } 76 | 77 | int algoDinic(int s, int t, int n, int need) { 78 | int flow = 0; 79 | while (bfs(s, t)) { 80 | for (int i = 0; i < n; i++) { 81 | cur[i] = h[i]; 82 | } 83 | flow += dfs(s, need - flow, t); 84 | if (flow == need) { 85 | return flow; 86 | } 87 | } 88 | return flow; 89 | } 90 | 91 | int main() { 92 | freopen("bring.in", "r", stdin); 93 | freopen("bring.out", "w", stdout); 94 | size_t n, m, k, s, t; 95 | 96 | cin >> n >> m >> k >> s >> t; 97 | s--; 98 | t--; 99 | 100 | edges.resize(MAXNM); 101 | h.resize(MAXN); 102 | d.resize(MAXN); 103 | cur.resize(MAXN); 104 | visited.resize(MAXN); 105 | 106 | vector u(m), v(m); 107 | for (int i = 0; i < m; i++) { 108 | cin >> u[i] >> v[i]; 109 | u[i]--; 110 | v[i]--; 111 | } 112 | h.assign(MAXN, -1); 113 | currentCapacity = 0; 114 | int day = 1; 115 | int currentFLow = 0; 116 | 117 | 118 | while (true) { 119 | for (int i = 0; i < n; i++) 120 | add((day - 1) * n + i, day * n + i, INF); 121 | for (int i = 0; i < m; i++) { 122 | add((day - 1) * n + u[i], day * n + v[i], 1); 123 | add((day - 1) * n + v[i], day * n + u[i], 1); 124 | } 125 | 126 | currentFLow += algoDinic(s, day * n + t, day * n + n, k - currentFLow); 127 | 128 | if (currentFLow == k) break; 129 | day++; 130 | } 131 | 132 | 133 | cout << day << "\n"; 134 | vector location(k, s); 135 | for (int d = 1, id = n * 2; d <= day; d++, id += n * 2) { 136 | vector moved(k, 0); 137 | vector A, B; 138 | for (int i = 0; i < m; i++) { 139 | int firstFlow = edges[id].flow; 140 | id += 2; 141 | int secondFlow = edges[id].flow; 142 | id += 2; 143 | if (firstFlow == 1 && !secondFlow) { 144 | A.push_back(u[i]); 145 | B.push_back(v[i]); 146 | } 147 | if (!firstFlow && secondFlow == 1) { 148 | A.push_back(v[i]); 149 | B.push_back(u[i]); 150 | } 151 | } 152 | cout << A.size(); 153 | for (int i = 0; i < A.size(); i++) { 154 | for (int j = 0; j < k; j++) 155 | if (!moved[j] && location[j] == A[i]) { 156 | moved[j] = 1; 157 | cout << " " << j + 1 << " " << B[i] + 1; 158 | location[j] = B[i]; 159 | break; 160 | } 161 | } 162 | cout << "\n"; 163 | } 164 | return 0; 165 | } -------------------------------------------------------------------------------- /term 4/Flows and matchings/J.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | const long long INF = 10000000000; 5 | 6 | size_t n, w; 7 | std::vector d; 8 | std::vector used; 9 | std::vector> graph; 10 | 11 | struct Object { 12 | long long x1, y1, x2, y2; 13 | 14 | long long getMinY() { 15 | return std::min(y1, y2); 16 | } 17 | 18 | long long getMaxY() { 19 | return std::max(y1, y2); 20 | } 21 | }; 22 | 23 | std::vector objects; 24 | 25 | long long getDistance(Object first, Object second) { 26 | long long h = (first.x1 <= second.x1) ? (second.x1 - first.x2) : (first.x1 - second.x2); 27 | long long v = (first.y1 <= second.y1) ? (second.y1 - first.y2) : (first.y1 - second.y2); 28 | return std::max(h, v) < 0 ? 0 : std::max(h, v); 29 | } 30 | 31 | void dijkstra() { 32 | d[0] = 0; 33 | for (int i = 0; i < n; ++i) { 34 | long long v = -1; 35 | for (int j = 0; j < n; ++j) { 36 | if (!used[j] && (v == -1 || d[j] < d[v])) { 37 | v = j; 38 | } 39 | } 40 | 41 | used[v] = true; 42 | for (int u = 0; u < n; ++u) { 43 | if (v != u) { 44 | long long distance = graph[v][u]; 45 | if (d[v] + distance < d[u]) { 46 | d[u] = d[v] + distance; 47 | } 48 | } 49 | } 50 | 51 | } 52 | } 53 | 54 | int main() { 55 | d.assign(10000, INF); 56 | used.assign(10000, false); 57 | 58 | std::cin >> n >> w; 59 | graph.assign(n + 2, std::vector(n + 2)); 60 | 61 | for (int i = 0; i < n; ++i) { 62 | long long x1, y1, x2, y2; 63 | std::cin >> x1 >> y1 >> x2 >> y2; 64 | objects.push_back({x1, y1, x2, y2}); 65 | } 66 | graph[0][n + 1] = w; 67 | graph[n + 1][0] = w; 68 | 69 | for (int i = 0; i < n; ++i) { 70 | Object current = objects[i]; 71 | 72 | long long minY = current.getMinY(); 73 | long long maxY = current.getMaxY(); 74 | 75 | graph[0][i + 1] = w - maxY; 76 | graph[i + 1][0] = w - maxY; 77 | 78 | graph[n + 1][i + 1] = minY; 79 | graph[i + 1][n + 1] = minY; 80 | 81 | for (int j = 0; j < n; ++j) { 82 | if (i != j) { 83 | graph[i + 1][j + 1] = getDistance(current, objects[j]); 84 | graph[j + 1][i + 1] = getDistance(current, objects[j]); 85 | } 86 | } 87 | } 88 | 89 | n += 2; 90 | dijkstra(); 91 | 92 | std::cout << ((d[n - 1] == INF) ? 0 : d[n - 1]) << "\n"; 93 | return 0; 94 | } -------------------------------------------------------------------------------- /term 4/Math/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | const int INF = 2 * 10000000 + 5; 5 | 6 | int n; 7 | std::vector prime; 8 | 9 | void eratosthenesSieve() { 10 | prime.assign(INF + 1, true); 11 | prime[0] = prime[1] = false; 12 | 13 | for (int i = 2; i <= INF; ++i) 14 | if (prime[i]) 15 | if (i * 1ll * i <= INF) 16 | for (int j = i * i; j <= INF; j += i) 17 | prime[j] = false; 18 | 19 | } 20 | 21 | bool isPrime(int n) { 22 | return prime[n]; 23 | } 24 | 25 | int main() { 26 | scanf("%d", &n); 27 | eratosthenesSieve(); 28 | 29 | for (int i = 0; i < n; ++i) { 30 | int x; 31 | scanf("%d", &x); 32 | isPrime(x) ? printf("YES\n") : printf("NO\n"); 33 | } 34 | 35 | return 0; 36 | } -------------------------------------------------------------------------------- /term 4/Math/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | const int INF = 1000000 + 5; 6 | 7 | int n; 8 | std::vector prime; 9 | 10 | void eratosthenesSieve() { 11 | prime.assign(INF + 1, true); 12 | 13 | for (long long i = 0; i < prime.size(); ++i) { 14 | prime[i] = i; 15 | } 16 | 17 | for (long long i = 2; i <= INF; ++i) 18 | if (prime[i] == i) 19 | for (long long j = i * i; j <= INF; j += i) 20 | prime[j] = i; 21 | 22 | } 23 | 24 | std::vector factorization(long long x) { 25 | std::vector res; 26 | 27 | while (x != 1) { 28 | res.push_back(prime[x]); 29 | x /= prime[x]; 30 | } 31 | 32 | std::sort(res.begin(), res.end()); 33 | 34 | return res; 35 | } 36 | 37 | int main() { 38 | scanf("%d", &n); 39 | eratosthenesSieve(); 40 | 41 | for (int i = 0; i < n; ++i) { 42 | int x; 43 | scanf("%d", &x); 44 | 45 | for (long long p : factorization(x)) { 46 | printf("%lld ", p); 47 | } 48 | 49 | printf("\n"); 50 | } 51 | return 0; 52 | } -------------------------------------------------------------------------------- /term 4/Math/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | long long n; 5 | 6 | long long mul(long long a, long long n, long long m) { 7 | long long r = 0; 8 | while (n > 0) { 9 | if (n % 2 == 1) 10 | r = (r + a) % m; 11 | a = (a + a) % m; 12 | n /= 2; 13 | } 14 | return r; 15 | } 16 | 17 | long long pow(long long a, long long n, long long m) { 18 | long long res = 1; 19 | while (n > 0) { 20 | if ((n & 1) > 0) 21 | res = mul(res, a, m); 22 | a = mul(a, a, m); 23 | n >>= 1; 24 | } 25 | return res; 26 | } 27 | 28 | bool isPrime(long long val, long long k) { 29 | if (val == 2 || n == 3) { 30 | return true; 31 | } 32 | 33 | if (val == 1 || val % 2 == 0) { 34 | return false; 35 | } 36 | 37 | long long p = 0, q = val - 1; 38 | 39 | while (q % 2 == 0) { 40 | ++p; 41 | q /= 2; 42 | } 43 | 44 | for (int i = 0; i < k; i++) { 45 | long long a = (rand() % (val - 2)) + 2; 46 | long long x = pow(a, q, val); 47 | 48 | if (x == 1 || x == val - 1) 49 | continue; 50 | 51 | for (int j = 1; j < p; ++j) { 52 | x = mul(x, x, val); 53 | if (x == 1) 54 | return false; 55 | if (x == val - 1) 56 | break; 57 | } 58 | 59 | if (x != val - 1) 60 | return false; 61 | } 62 | 63 | return true; 64 | } 65 | 66 | 67 | int main() { 68 | scanf("%lld", &n); 69 | int k = 10; 70 | 71 | for (int i = 0; i < n; ++i) { 72 | long long x; 73 | scanf("%lld", &x); 74 | 75 | isPrime(x, k) ? printf("YES\n") : printf("NO\n"); 76 | } 77 | return 0; 78 | } -------------------------------------------------------------------------------- /term 4/Math/D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | long long gcd(long long a, long long b, long long& x, long long& y) { 5 | if (a == 0) { 6 | x = 0; 7 | y = 1; 8 | return b; 9 | } 10 | long long x1 = 0, y1 = 0; 11 | long long d = gcd(b % a, a, x1, y1); 12 | x = y1 - (b / a) * x1; 13 | y = x1; 14 | return d; 15 | } 16 | 17 | long long Euclid(long long a, long long m) { 18 | long long x, y; 19 | long long res = gcd(a, m, x, y); 20 | return (x + m) % m; 21 | } 22 | 23 | long long kto(std::vector& a, std::vector& p) { 24 | long long result = 0; 25 | long long mul = 1; 26 | 27 | size_t n = a.size(); 28 | 29 | std::vector> r(n, std::vector(n)); 30 | std::vector x(n); 31 | 32 | for (int i = 0; i < r.size(); ++i) 33 | for (int j = i + 1; j < p.size(); ++j) { 34 | r[i][j] = Euclid(p[i], p[j]); 35 | } 36 | 37 | for (int i = 0; i < n; ++i) { 38 | x[i] = a[i]; 39 | 40 | for (int j = 0; j < i; ++j) { 41 | x[i] = (x[i] - x[j]) * r[j][i]; 42 | x[i] = x[i] % p[i]; 43 | 44 | if (x[i] < 0) { 45 | x[i] += p[i]; 46 | } 47 | } 48 | 49 | result += mul * x[i]; 50 | mul *= p[i]; 51 | } 52 | return result; 53 | } 54 | 55 | int main() { 56 | std::vector a; 57 | std::vector p; 58 | 59 | for (int i = 0; i < 2; ++i) { 60 | long long aa; 61 | scanf("%lld", &aa); 62 | a.push_back(aa); 63 | } 64 | 65 | for (int i = 0; i < 2; ++i) { 66 | long long pp; 67 | scanf("%lld", &pp); 68 | p.push_back(pp); 69 | } 70 | 71 | printf("%lld\n", kto(a, p)); 72 | return 0; 73 | } -------------------------------------------------------------------------------- /term 4/Math/E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | std::vector factorization(long long n) { 5 | std::vector res; 6 | for (long long i = 2; i <= n; ++i) { 7 | if (n % i == 0) { 8 | res.push_back(i); 9 | res.push_back(n / i); 10 | break; 11 | } 12 | } 13 | return res; 14 | } 15 | 16 | long long gcd(long long a, long long b, long long& x, long long& y) { 17 | if (a == 0) { 18 | x = 0; 19 | y = 1; 20 | return b; 21 | } 22 | long long x1 = 0, y1 = 0; 23 | long long d = gcd(b % a, a, x1, y1); 24 | 25 | x = y1 - (b / a) * x1; 26 | y = x1; 27 | return d; 28 | } 29 | 30 | long long Euclid(long long a, long long m) { 31 | long long x, y; 32 | long long res = gcd(a, m, x, y); 33 | return (x + m) % m; 34 | } 35 | 36 | long long mul(long long a, long long n, long long m) { 37 | long long res = 0; 38 | while (n > 0) { 39 | if (n % 2 == 1) 40 | res = (res + a) % m; 41 | a = (a + a) % m; 42 | n /= 2; 43 | } 44 | return res; 45 | } 46 | 47 | long long pow(long long a, long long n, long long m) { 48 | long long res = 1; 49 | while (n > 0) { 50 | if ((n & 1) > 0) 51 | res = mul(res, a, m); 52 | a = mul(a, a, m); 53 | n >>= 1; 54 | } 55 | return res; 56 | } 57 | 58 | int main() { 59 | long long n, e, C; 60 | 61 | scanf("%lld %lld %lld", &n, &e, &C); 62 | 63 | std::vector f = factorization(n); 64 | long long p = (f[0] - 1) * (f[1] - 1); 65 | long long d = Euclid(e, p); 66 | 67 | printf("%lld", pow(C, d, n)); 68 | 69 | return 0; 70 | } -------------------------------------------------------------------------------- /term 4/Math/F.hs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | multiply :: Integer -> Integer -> Integer 4 | multiply x y = x * y 5 | 6 | main :: IO () 7 | main = do 8 | a <- getLine 9 | b <- getLine 10 | let x = (read a :: Integer) 11 | let y = (read b :: Integer) 12 | print (multiply x y) 13 | -------------------------------------------------------------------------------- /term 4/Min cost flow/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | size_t n, m; 7 | const long long INF = LONG_LONG_MAX; 8 | 9 | struct Edge { 10 | int from, to; 11 | long long flow, cap, cost; 12 | int reversed = -1; 13 | 14 | Edge(int from, int to, long long int f, long long int cap, long long int cost) : from(from), to(to), flow(f), 15 | cap(cap), 16 | cost(cost) {} 17 | 18 | }; 19 | 20 | std::vector> edges; 21 | std::vector d; 22 | std::vector id; 23 | std::vector p; 24 | 25 | void addEdge(int from, int to, long long flow, long long cap, long long cost) { 26 | Edge edge = Edge(from, to, flow, cap, cost); 27 | Edge rev = Edge(to, from, flow, 0, -cost); 28 | 29 | edges[from].push_back(edge); 30 | edges[to].push_back(rev); 31 | 32 | edges[from].back().reversed = edges[to].size() - 1; 33 | edges[to].back().reversed = edges[from].size() - 1; 34 | } 35 | 36 | long long levitAlgorithm() { 37 | long long minCost = 0; 38 | long long maxFlow = 0; 39 | while (true) { 40 | std::deque q; 41 | id.assign(n + 1, 0); 42 | d.assign(n + 1, INF); 43 | p.resize(n + 1); 44 | 45 | d[1] = 0; 46 | q.push_back(1); 47 | 48 | while (!q.empty()) { 49 | int u = q.front(); 50 | q.pop_front(); 51 | id[u] = 2; 52 | 53 | for (Edge& edge : edges[u]) { 54 | if (edge.flow < edge.cap && d[edge.to] > d[edge.from] + edge.cost) { 55 | d[edge.to] = d[edge.from] + edge.cost; 56 | 57 | if (!id[edge.to]) { 58 | q.push_back(edge.to); 59 | } else if (id[edge.to] == 2) { 60 | q.push_front(edge.to); 61 | } 62 | 63 | id[edge.to] = 1; 64 | p[edge.to] = &edge; 65 | } 66 | } 67 | } 68 | 69 | long long del = INF; 70 | 71 | if (d[n] == INF) { 72 | break; 73 | } else { 74 | for (int u = n; u != 1; u = p[u]->from) { 75 | Edge* edge = p[u]; 76 | 77 | del = std::min(del, edge->cap - edge->flow); 78 | } 79 | 80 | for (int u = n; u != 1; u = p[u]->from) { 81 | Edge* edge = p[u]; 82 | Edge* reversed = &edges[edge->to][edge->reversed]; 83 | 84 | edge->flow += del; 85 | reversed->flow -= del; 86 | 87 | minCost += del * edge->cost; 88 | } 89 | 90 | maxFlow += del; 91 | } 92 | } 93 | 94 | return minCost; 95 | } 96 | 97 | int main() { 98 | freopen("mincost.in", "r", stdin); 99 | freopen("mincost.out", "w", stdout); 100 | std::cin >> n >> m; 101 | edges.assign(n + 1, std::vector()); 102 | 103 | for (int i = 0; i < m; ++i) { 104 | int from, to; 105 | long long cap, cost; 106 | std::cin >> from >> to >> cap >> cost; 107 | 108 | addEdge(from, to, 0, cap, cost); 109 | } 110 | std::cout << levitAlgorithm(); 111 | return 0; 112 | } -------------------------------------------------------------------------------- /term 4/Min cost flow/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | const int INF = 1000000001; 5 | 6 | size_t n; 7 | std::vector> C; 8 | 9 | std::pair> hunragianAlgo(std::vector> C, size_t n, size_t m) { 10 | std::vector u(n + 1); 11 | std::vector v(m + 1); 12 | std::vector match(m + 1); 13 | std::vector way(m + 1); 14 | 15 | for (int i = 1; i <= m; ++i) { 16 | match[0] = i; 17 | int currentColumn = 0; 18 | std::vector minV(m + 1, INF); 19 | std::vector used(m + 1, false); 20 | 21 | do { 22 | used[currentColumn] = true; 23 | int currentRow = match[currentColumn]; 24 | int del = INF; 25 | int minColumn = 0; 26 | 27 | for (int j = 1; j <= m; ++j) { 28 | if (!used[j]) { 29 | int current = C[currentRow][j] - u[currentRow] - v[j];//potential 30 | 31 | if (current < minV[j]) { 32 | minV[j] = current; 33 | way[j] = currentColumn; 34 | } 35 | 36 | if (minV[j] < del) { 37 | del = minV[j]; 38 | minColumn = j; 39 | } 40 | } 41 | } 42 | 43 | for (int j = 0; j <= m; ++j) { 44 | if (used[j]) { 45 | u[match[j]] += del; 46 | v[j] -= del; 47 | } else { 48 | minV[j] -= del; 49 | } 50 | } 51 | 52 | currentColumn = minColumn; 53 | } while (match[currentColumn] != 0); 54 | 55 | do { 56 | int minColumn = way[currentColumn]; 57 | match[currentColumn] = match[minColumn]; 58 | currentColumn = minColumn; 59 | } while (currentColumn); 60 | } 61 | 62 | std::vector result(n + 1); 63 | for (int j = 1; j <= m; ++j) { 64 | result[match[j]] = j; 65 | } 66 | 67 | return {-v[0], result}; 68 | } 69 | 70 | int main() { 71 | freopen("assignment.in", "r", stdin); 72 | freopen("assignment.out", "w", stdout); 73 | 74 | std::cin >> n; 75 | C.assign(n + 1, std::vector(n + 1)); 76 | 77 | for (int i = 1; i <= n; ++i) { 78 | for (int j = 1; j <= n; ++j) { 79 | std::cin >> C[i][j]; 80 | } 81 | } 82 | 83 | std::pair> result = hunragianAlgo(C,n,n); 84 | 85 | std::cout<< result.first << "\n"; 86 | for (int i =1;i<=n;++i){ 87 | std::cout<< i << " " << result.second[i] << "\n"; 88 | } 89 | 90 | return 0; 91 | } -------------------------------------------------------------------------------- /term 4/Min cost flow/D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | freopen("rps2.in", "r", stdin); 5 | freopen("rps2.out", "w", stdout); 6 | 7 | int stones1, scissors1, papers1; 8 | int stones2, scissors2, papers2; 9 | 10 | std::cin >> stones1 >> scissors1 >> papers1; 11 | std::cin >> stones2 >> scissors2 >> papers2; 12 | 13 | int scissorsLost = scissors1 - scissors2 - stones2; 14 | int stonesLost = stones1 - stones2 - papers2; 15 | int papersLost = papers1 - papers2 - scissors2; 16 | 17 | std::cout << std::max(0, std::max(scissorsLost, std::max(stonesLost, papersLost))); 18 | 19 | return 0; 20 | } -------------------------------------------------------------------------------- /term 4/Min cost flow/E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | size_t n, m; 8 | const long long INF = LONG_LONG_MAX; 9 | 10 | struct Edge { 11 | int from, to; 12 | long long flow, cap, cost; 13 | int reversed = -1; 14 | 15 | Edge(int from, int to, long long int f, long long int cap, long long int cost) : from(from), to(to), flow(f), 16 | cap(cap), 17 | cost(cost) {} 18 | 19 | }; 20 | 21 | int nullSource, nullSink; 22 | std::vector> edges; 23 | std::vector d; 24 | std::vector id; 25 | std::vector p; 26 | 27 | void addEdge(int from, int to, long long flow, long long cap, long long cost) { 28 | Edge edge = Edge(from, to, flow, cap, cost); 29 | Edge rev = Edge(to, from, flow, 0, -cost); 30 | 31 | edges[from].push_back(edge); 32 | edges[to].push_back(rev); 33 | 34 | edges[from].back().reversed = edges[to].size() - 1; 35 | edges[to].back().reversed = edges[from].size() - 1; 36 | } 37 | 38 | long long levitAlgorithm() { 39 | long long minCost = 0; 40 | long long maxFlow = 0; 41 | while (true) { 42 | std::deque q; 43 | id.assign(n + 1, 0); 44 | d.assign(n + 1, INF); 45 | p.resize(n + 1); 46 | 47 | d[0] = 0; 48 | q.push_back(0); 49 | 50 | while (!q.empty()) { 51 | int u = q.front(); 52 | q.pop_front(); 53 | id[u] = 2; 54 | 55 | for (Edge& edge : edges[u]) { 56 | if (edge.flow < edge.cap && d[edge.to] > d[edge.from] + edge.cost) { 57 | d[edge.to] = d[edge.from] + edge.cost; 58 | 59 | if (!id[edge.to]) { 60 | q.push_back(edge.to); 61 | } else if (id[edge.to] == 2) { 62 | q.push_front(edge.to); 63 | } 64 | 65 | id[edge.to] = 1; 66 | p[edge.to] = &edge; 67 | } 68 | } 69 | } 70 | 71 | long long del = INF; 72 | 73 | if (d[nullSink] == INF) { 74 | break; 75 | } else { 76 | for (int u = nullSink; u != nullSource; u = p[u]->from) { 77 | Edge* edge = p[u]; 78 | 79 | del = std::min(del, edge->cap - edge->flow); 80 | } 81 | 82 | for (int u = nullSink; u != nullSource; u = p[u]->from) { 83 | Edge* edge = p[u]; 84 | Edge* reversed = &edges[edge->to][edge->reversed]; 85 | 86 | edge->flow += del; 87 | reversed->flow -= del; 88 | 89 | minCost += del * edge->cost; 90 | } 91 | 92 | maxFlow += del; 93 | } 94 | } 95 | 96 | return minCost; 97 | } 98 | 99 | int main() { 100 | std::cin >> n >> m; 101 | std::vector a(n + 1); 102 | size_t nn = 2 * n + 1; 103 | edges.assign(nn + 1, std::vector()); 104 | 105 | for (int i = 1; i <= n; ++i) { 106 | std::cin >> a[i]; 107 | addEdge(n + i, i, 0, INF, a[i]); 108 | addEdge(0, n + i, 0, 1, 0); 109 | addEdge(i, nn, 0, 1, 0); 110 | addEdge(i, n + i, 0, INF, 0); 111 | } 112 | 113 | for (int i = 0; i < m; ++i) { 114 | int u, v; 115 | long long cost; 116 | std::cin >> u >> v >> cost; 117 | addEdge(n + u, v, 0, INF, cost); 118 | } 119 | 120 | nullSource = 0; 121 | nullSink = nn; 122 | n = nn + 1; 123 | 124 | std::cout << levitAlgorithm() << "\n"; 125 | return 0; 126 | } --------------------------------------------------------------------------------