├── .gitattributes ├── 7 - NP полные задачи ├── 7.pdf ├── Алгоритмы hw7 первая посылка.pdf └── Алгоритмы hw7 вторая посылка.docx ├── 11 - Суффиксный массив ├── 11.pdf ├── C.cpp ├── A.cpp └── D.cpp ├── 12 - Суффиксное дерево ├── 12.pdf └── A.cpp ├── 3 - Базовая теория чисел ├── 3.pdf ├── A.py ├── C.py ├── E.py ├── D.py └── B.cpp ├── 5 - Запросы на отрезках ├── 5.pdf ├── A.cpp ├── D.cpp ├── E.cpp ├── B.cpp └── C.cpp ├── 9 - Потоки со стоимостью ├── 9.pdf ├── A.cpp └── B.cpp ├── 13 - Вычислительная геометрия ├── 13.pdf ├── A.py ├── B.py └── E.py ├── 4 - Продвинутая теория чисел ├── 4.pdf ├── B.py ├── D.py ├── A.py ├── E.py └── C.py ├── 10 - Грамматики и парсинг ├── грамматика.docx ├── ДЗ по парсингу.pdf ├── std.in └── hw_10.py ├── 14 - Быстрое преобразование Фурье ├── 14.pdf ├── B.cpp ├── C.cpp └── A.cpp ├── 15 - Персистентные структуры данных ├── 15.pdf ├── A.cpp └── B.cpp ├── 6 - Запросы на отрезках. Продолжение ├── 6.pdf ├── D.cpp ├── A.cpp ├── E.cpp ├── C.cpp └── B.cpp ├── 1 - Базовое динамическое программирование ├── 1.pdf ├── D.py ├── C.py ├── A.py ├── B.py └── E.py ├── 2 - Продвинутое динамическое программирование ├── 2.pdf ├── A.py ├── C.py ├── E.py ├── D.py └── B.py ├── 8 - Максимальный поток и минимальный разрез ├── 8.pdf ├── A.cpp ├── B.cpp └── C.cpp └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /7 - NP полные задачи/7.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrecpc/made_algo_spring_2020/HEAD/7 - NP полные задачи/7.pdf -------------------------------------------------------------------------------- /11 - Суффиксный массив/11.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrecpc/made_algo_spring_2020/HEAD/11 - Суффиксный массив/11.pdf -------------------------------------------------------------------------------- /12 - Суффиксное дерево/12.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrecpc/made_algo_spring_2020/HEAD/12 - Суффиксное дерево/12.pdf -------------------------------------------------------------------------------- /3 - Базовая теория чисел/3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrecpc/made_algo_spring_2020/HEAD/3 - Базовая теория чисел/3.pdf -------------------------------------------------------------------------------- /5 - Запросы на отрезках/5.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrecpc/made_algo_spring_2020/HEAD/5 - Запросы на отрезках/5.pdf -------------------------------------------------------------------------------- /9 - Потоки со стоимостью/9.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrecpc/made_algo_spring_2020/HEAD/9 - Потоки со стоимостью/9.pdf -------------------------------------------------------------------------------- /13 - Вычислительная геометрия/13.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrecpc/made_algo_spring_2020/HEAD/13 - Вычислительная геометрия/13.pdf -------------------------------------------------------------------------------- /4 - Продвинутая теория чисел/4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrecpc/made_algo_spring_2020/HEAD/4 - Продвинутая теория чисел/4.pdf -------------------------------------------------------------------------------- /10 - Грамматики и парсинг/грамматика.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrecpc/made_algo_spring_2020/HEAD/10 - Грамматики и парсинг/грамматика.docx -------------------------------------------------------------------------------- /14 - Быстрое преобразование Фурье/14.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrecpc/made_algo_spring_2020/HEAD/14 - Быстрое преобразование Фурье/14.pdf -------------------------------------------------------------------------------- /15 - Персистентные структуры данных/15.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrecpc/made_algo_spring_2020/HEAD/15 - Персистентные структуры данных/15.pdf -------------------------------------------------------------------------------- /6 - Запросы на отрезках. Продолжение/6.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrecpc/made_algo_spring_2020/HEAD/6 - Запросы на отрезках. Продолжение/6.pdf -------------------------------------------------------------------------------- /10 - Грамматики и парсинг/ДЗ по парсингу.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrecpc/made_algo_spring_2020/HEAD/10 - Грамматики и парсинг/ДЗ по парсингу.pdf -------------------------------------------------------------------------------- /1 - Базовое динамическое программирование/1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrecpc/made_algo_spring_2020/HEAD/1 - Базовое динамическое программирование/1.pdf -------------------------------------------------------------------------------- /2 - Продвинутое динамическое программирование/2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrecpc/made_algo_spring_2020/HEAD/2 - Продвинутое динамическое программирование/2.pdf -------------------------------------------------------------------------------- /8 - Максимальный поток и минимальный разрез/8.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrecpc/made_algo_spring_2020/HEAD/8 - Максимальный поток и минимальный разрез/8.pdf -------------------------------------------------------------------------------- /7 - NP полные задачи/Алгоритмы hw7 первая посылка.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrecpc/made_algo_spring_2020/HEAD/7 - NP полные задачи/Алгоритмы hw7 первая посылка.pdf -------------------------------------------------------------------------------- /7 - NP полные задачи/Алгоритмы hw7 вторая посылка.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrecpc/made_algo_spring_2020/HEAD/7 - NP полные задачи/Алгоритмы hw7 вторая посылка.docx -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # made_algo_spring_2020 2 | Solving tasks on advanced algorithms at the Made Mail.ru course 3 | 4 | Условия задач и решения весеннего курса алгоритмов Made Mail.ru 5 | Все задачи решены корректно на python или c++. Курс сдан на 4. 6 | -------------------------------------------------------------------------------- /10 - Грамматики и парсинг/std.in: -------------------------------------------------------------------------------- 1 | a = 2.5 2 | b = ((3)) 3 | K = 6 - 7 4 | as = 3 * 4 + 5 * 6.8 5 | rtd = 2 / 1 6 | o = 0 + 9 7 | c = (2 * (5 - 3)) 8 | d = b - a 9 | r = 18 / 6 - 5 * (o / ( b - 2)) + 49 - (k + 1) 10 | e = 11 | dfgh = ik 12 | чс = 5 + 5 13 | n = 8 14 | n = a 15 | n = a 16 | n = b 17 | 18 | fg = 6+7 19 | yui = 3 / 0 20 | adh = - 21 | dfgh = 2 ^ o 22 | t = ((3+4) 23 | sdf = 18 / 6 - 5 * (o / ( b - (2)) + 49 - (k + 1) 24 | ert :=7 25 | step = 2 ^ 3 * 5 ^ 2 26 | hj = 2 -5 ^2 -------------------------------------------------------------------------------- /2 - Продвинутое динамическое программирование/A.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import sys 3 | 4 | n = int(sys.stdin.readline().strip()) 5 | a = [0] * n 6 | for i in range(n): 7 | a[i] = sys.stdin.readline().strip() 8 | 9 | 10 | 11 | dp = [0] * (1 << n) 12 | 13 | n2 = 1 << n 14 | for i in range(n2): 15 | for j in range(n): 16 | if (i & 1 << j): 17 | for k in range(j + 1, n): 18 | if (i & 1 << k): 19 | if (a[j][k] == 'Y'): 20 | dp[i]=max(dp[i], 2 + dp[i &~ (1 << j) &~ (1 << k)]) 21 | print (dp[n2 - 1]) 22 | -------------------------------------------------------------------------------- /1 - Базовое динамическое программирование/D.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import sys 4 | 5 | word_1 = sys.stdin.readline().strip() 6 | word_2 = sys.stdin.readline().strip() 7 | 8 | # word_1 = 'ABCDEFGH' 9 | # word_2 = 'ACDEXGIH' 10 | 11 | a = len(word_1) + 1 12 | b = len(word_2) + 1 13 | 14 | dp = [ [0] * b for i in range(a) ] 15 | dp[0][1:] = range(1, b) 16 | for el in range(1, a): 17 | dp[el][0] = el 18 | 19 | for i in range(1, a): 20 | for j in range(1, b): 21 | if word_1[i - 1] == word_2[j - 1]: 22 | dp[i][j] = dp[i - 1][j - 1] 23 | else: 24 | dp[i][j] = 1 + min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]) 25 | 26 | print (dp[a-1][b-1]) 27 | -------------------------------------------------------------------------------- /4 - Продвинутая теория чисел/B.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import sys 3 | 4 | a, b, m = list(map(int, (sys.stdin.readline().strip().split(' ')))) 5 | 6 | def dlog(a, b, m): 7 | 8 | k = int(m ** 0.5 + 1) 9 | baby_steps = {} 10 | baby_step = 1 11 | 12 | for r in range(k + 1): 13 | baby_steps[baby_step] = r 14 | baby_step = baby_step * a % m 15 | 16 | g = pow(a, (m - 2) * k, m) 17 | giant_step = b 18 | 19 | for s in range(k + 1): 20 | if giant_step in baby_steps: 21 | return s * k + baby_steps[giant_step] 22 | else: 23 | giant_step = giant_step * g % m 24 | 25 | return -1 26 | 27 | print(dlog(a, b, m)) 28 | -------------------------------------------------------------------------------- /1 - Базовое динамическое программирование/C.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # n = 5 4 | # a = [1, 3, 5, 4, 2] 5 | 6 | import sys 7 | 8 | n = int(sys.stdin.readline().strip()) 9 | a = list( map( int, sys.stdin.readline().strip().split(' ') ) ) 10 | out = [] 11 | 12 | dp = [0] * n 13 | for i in range(n): 14 | for j in range(i): 15 | if a[i] > a[j] and dp[j] > dp[i]: 16 | dp[i] = dp[j] 17 | dp[i] += 1 18 | 19 | ind = dp.index(max(dp)) 20 | out.append(a[ind]) 21 | 22 | while dp[ind] != 1: 23 | j = ind - 1 24 | while (dp[j] != dp[ind] - 1) or (a[j] >= a[ind]): 25 | j -= 1 26 | ind = j 27 | out.append(a[ind]) 28 | 29 | print (len(out)) 30 | print (' '.join(map( str, out[::-1]) )) 31 | -------------------------------------------------------------------------------- /3 - Базовая теория чисел/A.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | kor=1000001 4 | 5 | numbs = [60, 456,232,11,678] 6 | 7 | lp = [0]*(kor+1) 8 | primes=[] 9 | for i in range (2,kor+1): 10 | if (lp[i] == 0): 11 | lp[i] = i 12 | primes.append(i) 13 | for p in primes: 14 | if ((p > lp[i]) | (i * p >= kor+1)): 15 | break 16 | lp[i * p] = p 17 | ''' 18 | for num in numbs: 19 | while (num > 1): 20 | sys.stdout.write(str(lp[num]) + ' ') 21 | num = int(num/lp[num]) 22 | sys.stdout.write('\n') 23 | ''' 24 | 25 | n = int(sys.stdin.readline().strip()) 26 | 27 | for _ in range(n): 28 | num = int(sys.stdin.readline().strip()) 29 | while (num > 1): 30 | sys.stdout.write(str(lp[num]) + ' ') 31 | num = int(num/lp[num]) 32 | sys.stdout.write('\n') 33 | -------------------------------------------------------------------------------- /3 - Базовая теория чисел/C.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import sys 4 | 5 | n = int(sys.stdin.readline().strip()) 6 | e = int(sys.stdin.readline().strip()) 7 | c = int(sys.stdin.readline().strip()) 8 | 9 | #n, e, c = 143, 113, 41 10 | #n, e, c = 9173503, 3, 4051753 11 | 12 | def euler(n): 13 | result = n 14 | i = 2 15 | while i * i <= n: 16 | if n % i == 0: 17 | while n % i == 0: 18 | n /= i 19 | result -= result / i 20 | i += 1 21 | if n > 1: 22 | result -= result / n 23 | return int(result) 24 | 25 | def binpow(a, n, mod): 26 | if n == 0: 27 | return 1 28 | if int(n) & 1: 29 | return (a * binpow(a, n - 1, mod)) % mod 30 | return binpow((a * a) % mod, n / 2, mod) 31 | 32 | p = euler(n) 33 | pp = euler(p) 34 | d = binpow(e, pp - 1, p) 35 | print (binpow(c, d, n)) 36 | -------------------------------------------------------------------------------- /4 - Продвинутая теория чисел/D.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import random 3 | import sys 4 | 5 | n = int(sys.stdin.readline().strip()) 6 | 7 | def miller_rabin(n): 8 | 9 | if n in [0, 1, 4, 6, 8, 9]: 10 | return 'NO' 11 | 12 | if n in [2, 3, 5, 7]: 13 | return 'YES' 14 | s = 0 15 | d = n - 1 16 | while d % 2 == 0: 17 | d >>= 1 18 | s += 1 19 | 20 | def check(a): 21 | if pow(a, d, n) == 1: 22 | return False 23 | for i in range(s): 24 | if pow(a, 2 ** i * d, n) == n - 1: 25 | return 'NO' 26 | return 'YES' 27 | 28 | for i in range(3): 29 | a = random.randrange(2, n) 30 | if check(a) == 'YES': 31 | return 'NO' 32 | 33 | return 'YES' 34 | 35 | for _ in range(n): 36 | i = int(sys.stdin.readline().strip()) 37 | print (miller_rabin(i)) 38 | -------------------------------------------------------------------------------- /3 - Базовая теория чисел/E.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import sys 3 | 4 | n = int(sys.stdin.readline().strip()) 5 | 6 | for i in range(n): 7 | a, b, n, m = list(map(int, sys.stdin.readline().strip().split(' '))) 8 | 9 | #a, b, n, m = 3, 2, 5, 9 10 | #a,b,n,m = 1, 0, 2, 3 11 | 12 | def gcd(a, b): 13 | global x 14 | global y 15 | if b == 0: 16 | x = 1 17 | y = 0 18 | return a 19 | g = gcd(b, a % b) 20 | tmp = y 21 | y = x - int(a / b) * y 22 | x = tmp 23 | return int(g) 24 | 25 | A = n 26 | B = m 27 | G = b - a 28 | x, y = 0, 0 29 | mod = n * m 30 | g = gcd(A, B) 31 | x *= A 32 | x %= mod 33 | x += mod 34 | x %= mod 35 | x *= G 36 | x %= mod 37 | x += mod 38 | x %= mod 39 | x += a 40 | x %= mod 41 | x += mod 42 | x %= mod 43 | print (x) 44 | -------------------------------------------------------------------------------- /15 - Персистентные структуры данных/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | struct Node { 7 | int num; 8 | long long val; 9 | }; 10 | 11 | vector p; 12 | 13 | void push(int i, long long m) { 14 | Node k; 15 | k.num = i; 16 | k.val = m; 17 | p.push_back(k); 18 | } 19 | 20 | long long pop(int i) { 21 | p.push_back(p[p[i].num]); 22 | return p[i].val; 23 | } 24 | 25 | int main() { 26 | int n; 27 | cin >> n; 28 | Node k; 29 | k.num = 0, k.val = 0; 30 | p.push_back(k); 31 | 32 | for (int i = 0; i < n; ++i) { 33 | int t; 34 | long long m; 35 | cin >> t >> m; 36 | 37 | if (m != 0) { 38 | push(t, m); 39 | } 40 | 41 | else { 42 | long long ans; 43 | ans = pop(t); 44 | cout << ans << '\n'; 45 | } 46 | } 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /2 - Продвинутое динамическое программирование/C.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | n = int(input()) 4 | tree = [] 5 | dp = [] 6 | 7 | for _ in range(n): 8 | tree.append(int(input()) - 1) 9 | 10 | for _ in range(n): 11 | dp.append([0, 1]) 12 | 13 | childs_mapping = defaultdict(list) 14 | 15 | for id, parent_id in enumerate(tree): 16 | if parent_id == -1: 17 | root_id = id 18 | else: 19 | childs_mapping[parent_id].append(id) 20 | 21 | nodes_stack = [(root_id, 0)] 22 | 23 | while nodes_stack: 24 | node, status = nodes_stack.pop() 25 | if status == 1: 26 | for child_node in childs_mapping[node]: 27 | dp[node][0] += max(dp[child_node]) 28 | dp[node][1] += dp[child_node][0] 29 | elif node in childs_mapping: 30 | nodes_stack.append((node, 1)) 31 | for child_node in childs_mapping[node]: 32 | nodes_stack.append((child_node, 0)) 33 | 34 | print(max(dp[root_id])) 35 | -------------------------------------------------------------------------------- /3 - Базовая теория чисел/D.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import sys 3 | 4 | a, b, c = list(map(int, sys.stdin.readline().strip().split(' '))) 5 | 6 | def gcd(a, b): 7 | while b != 0: 8 | a, b = b, a % b 9 | return a 10 | 11 | def gcd_2(a, b): 12 | x, xx, y, yy = 1, 0, 0, 1 13 | while b: 14 | q = a // b 15 | a, b = b, a % b 16 | x, xx = xx, x - xx*q 17 | y, yy = yy, y - yy*q 18 | return x, y 19 | 20 | u, v = gcd_2(a, b) 21 | x = u * (c // gcd(a, b)) 22 | y = v * (c // gcd(a, b)) 23 | 24 | if x * a + y * b + c == 0: 25 | print (x, y) 26 | elif -x * a + y * b + c == 0: 27 | print (-x, y) 28 | elif x * a - y * b + c == 0: 29 | print (x, -y) 30 | elif -x * a - y * b + c == 0: 31 | print (-x, -y) 32 | elif y * a + x * b + c == 0: 33 | print (y, x) 34 | elif -y * a + x * b + c == 0: 35 | print (-y, x) 36 | elif y * a - x * b + c == 0: 37 | print (y, -x) 38 | elif -y * a - x * b + c == 0: 39 | print (-y, -x) 40 | else: 41 | print (-1) 42 | -------------------------------------------------------------------------------- /1 - Базовое динамическое программирование/A.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | with open("input.txt", "r") as file: 4 | n, k = map( int, file.readline().strip().split(' ') ) 5 | costs = list( map( int, file.readline().strip().split(' ') ) ) 6 | 7 | values = [-100, 0] + costs + [0] 8 | dp = [-100] + [0] * n 9 | path = [] 10 | 11 | for i in range(2, n + 1): 12 | num_max = i - 1 13 | for j in range( max(1, i - k), i ): 14 | if dp[j] > dp[num_max]: 15 | num_max = j 16 | dp[i] = dp[num_max] + values[i] 17 | 18 | if num_max not in path: 19 | path.append(num_max) 20 | 21 | if k == 1: 22 | path = list( range(1, n + 1) ) 23 | s = n - 1 24 | 25 | path = path + [n] 26 | s = len(path) - 1 27 | 28 | if k == 1: 29 | path = list( range(1, n + 1) ) 30 | s = n - 1 31 | 32 | if n == 2: 33 | path = [1, 2] 34 | s = 1 35 | 36 | output_text = '\n'.join( [ str(dp[-1]), str(s), ' '.join(map(str, path)) ] ) 37 | 38 | with open("output.txt","w") as out: 39 | out.write(output_text) 40 | -------------------------------------------------------------------------------- /2 - Продвинутое динамическое программирование/E.py: -------------------------------------------------------------------------------- 1 | n, m = map(int, input().split()) 2 | board = [] 3 | dp = [] 4 | 5 | for _ in range(n): 6 | board.append(input() + 'X') 7 | 8 | for _ in range(n * m + 1): 9 | dp.append([0] * (1 << n)) 10 | 11 | dp[0][0] = 1 12 | 13 | for i in range(n * m): 14 | row_id, col_id = i % n, i // n 15 | for mask in range(len(dp[0])): 16 | cell = board[row_id][col_id] 17 | if (cell == 'X' and mask & 1 == 0) or (cell == '.' and mask & 1 == 1): 18 | next_mask = mask >> 1 19 | dp[i + 1][next_mask] += dp[i][mask] 20 | 21 | if cell == '.' and mask & 1 == 0: 22 | if board[row_id][col_id + 1] == '.': 23 | next_mask = (mask >> 1) + (1 << (n - 1)) 24 | dp[i + 1][next_mask] += dp[i][mask] 25 | 26 | if mask & 2 == 0 and row_id + 1 < n and board[row_id + 1][col_id] == '.': 27 | next_mask = (mask >> 1) + 1 28 | dp[i + 1][next_mask] += dp[i][mask] 29 | 30 | print(dp[-1][0]) 31 | -------------------------------------------------------------------------------- /5 - Запросы на отрезках/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int main() { 6 | 7 | int n, x, y, a0, m, z, t, b0; 8 | cin >> n >> x >> y >> a0; 9 | cin >> m >> z >> t >> b0; 10 | 11 | int* a = new int[n]; 12 | long long* pref = new long long[n]; 13 | int* b = new int[2 * m]; 14 | int* c = new int[2 * m]; 15 | a[0] = a0; 16 | pref[0] = a0; 17 | b[0] = b0; 18 | 19 | for (int i = 1; i < 2 * m; i++) { 20 | 21 | if (i < n) { 22 | a[i] = (x * a[i - 1] + y) % (1 << 16); 23 | pref[i] = a[i] + pref[i - 1]; 24 | } 25 | 26 | b[i] = (z * b[i - 1] + t) % (1 << 30); 27 | if (b[i] < 0) b[i] = (1 << 30) + b[i]; 28 | 29 | c[i] = b[i] % n; 30 | } 31 | 32 | c[0] = b[0] % n; 33 | 34 | long long out = 0; 35 | 36 | for (int i = 0; i < m; i++) { 37 | int r = max(c[2 * i], c[2 * i + 1]); 38 | int l = min(c[2 * i], c[2 * i + 1]); 39 | if (l > 0) out += pref[r] - pref[l - 1]; 40 | else out += pref[r]; 41 | } 42 | 43 | cout << out; 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /1 - Базовое динамическое программирование/B.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import sys 4 | 5 | n, m = map( int, sys.stdin.readline().strip().split(' ') ) 6 | values = [0] * n 7 | for i in range(n): 8 | values[i] = list( map( int, sys.stdin.readline().strip().split(' ') ) ) 9 | 10 | dp = [ [0] * m for i in range(n) ] 11 | 12 | for i in range(n): 13 | for j in range(m): 14 | if (i == 0) and (j == 0): 15 | dp[0][0] = values[0][0] 16 | elif i == 0: 17 | dp[0][j] = dp[0][j - 1] + values[0][j] 18 | elif j == 0: 19 | dp[i][0] = dp[i - 1][0] + values[i][0] 20 | else: 21 | dp[i][j] = max( dp[i - 1][j], dp[i][j - 1] ) + values[i][j] 22 | 23 | fin_coins = dp[n - 1][m - 1] 24 | 25 | path = '' 26 | 27 | while ((n - 1) > 0) or ((m - 1) > 0): 28 | if n - 1 == 0: 29 | path += 'R' 30 | m -= 1 31 | elif m - 1 == 0: 32 | path += 'D' 33 | n -= 1 34 | elif dp[n - 2][m - 1] > dp[n - 1][m - 2]: 35 | path += 'D' 36 | n -= 1 37 | else: 38 | path += 'R' 39 | m -= 1 40 | 41 | print (fin_coins) 42 | print (path[::-1]) 43 | -------------------------------------------------------------------------------- /2 - Продвинутое динамическое программирование/D.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -* 2 | import sys 3 | 4 | n = int(sys.stdin.readline().strip()) 5 | a = [0] * n 6 | for i in range(n): 7 | a[i] = list(map(int, sys.stdin.readline().strip().split(' '))) 8 | 9 | inf = 100000001 10 | finish_mask = 1 << n 11 | dp = [[inf] * (n) for i in range(finish_mask)] 12 | path = [[0] * (n) for i in range(finish_mask)] 13 | 14 | k = 1 15 | for i in range(1, n + 1): 16 | k *= 2 17 | ans = inf 18 | 19 | for i in range(n): 20 | dp[1 << i][i] = 0 21 | 22 | for i in range(k): 23 | for j in range(n): 24 | m = inf 25 | for l in range(n): 26 | if l != j: 27 | if (dp[(i ^ (1 << j))][l] + a[l][j]) < m: 28 | m = dp[i ^ (1 << j)][l] + a[l][j] 29 | dp[i][j] = m 30 | path[i][j] = l 31 | 32 | for i in range(n): 33 | if dp[k - 1][i] < ans: 34 | ans = dp[k - 1][i] 35 | last = i 36 | 37 | print (ans) 38 | 39 | mask = k - 1 40 | res = '' 41 | 42 | for i in range(n): 43 | res += str(last + 1) + ' ' 44 | pr, last = last, path[mask][last] 45 | mask = mask ^ (1 << pr) 46 | 47 | res = res[:-1].split(' ') 48 | print (' '.join(res[::-1]) + ' ') 49 | -------------------------------------------------------------------------------- /4 - Продвинутая теория чисел/A.py: -------------------------------------------------------------------------------- 1 | from math import sqrt 2 | import sys 3 | 4 | def prime(n): 5 | if n == 3: 6 | return True 7 | if n % 2 == 0 or n % 3 == 0: 8 | return False 9 | i = 5 10 | while(i * i <= n): 11 | if n % i == 0 or n % (i + 2) == 0: 12 | return False 13 | i = i + 6 14 | return True 15 | 16 | def power(x, y, p): 17 | res = 1 18 | x = x % p 19 | while y > 0: 20 | if y & 1: 21 | res = (res * x) % p 22 | y = y >> 1 23 | x = (x * x) % p 24 | return res 25 | 26 | def find_prime_factors(s, n): 27 | while n % 2 == 0: 28 | s.add(2) 29 | n = n // 2 30 | for i in range(3, int(sqrt(n)), 2): 31 | while n % i == 0: 32 | s.add(i) 33 | n = n // i 34 | if n > 2: 35 | s.add(n) 36 | 37 | 38 | def find_prim_root(n): 39 | s = set() 40 | if prime(n) == False: 41 | return -1 42 | phi = n - 1 43 | find_prime_factors(s, phi) 44 | for r in range(2, phi + 1): 45 | flag = False 46 | for it in s: 47 | if power(r, phi // it, n) == 1: 48 | flag = True 49 | break 50 | if flag == False: 51 | return r 52 | return -1 53 | 54 | p = int(sys.stdin.readline().strip()) 55 | #p = 2393 56 | print(find_prim_root(p)) 57 | -------------------------------------------------------------------------------- /5 - Запросы на отрезках/D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int precount(int const& x) { 8 | 9 | if (x == 1) return 0; 10 | return precount(x / 2) + 1; 11 | } 12 | 13 | int main() { 14 | 15 | int n, m, u, v; 16 | cin >> n >> m; 17 | vector logs(n + 1, 0); 18 | vector a(n + 1); 19 | cin >> a[1] >> u >> v; 20 | 21 | for (int i = 2; i <= n; i++) { 22 | a[i] = (23 * a[i - 1] + 21563) % 16714589; 23 | logs[i] = precount(i); 24 | } 25 | 26 | vector> st(n + 1, vector(logs[n] + 1)); 27 | 28 | for (int j = 0; j <= logs[n]; j++) { 29 | for (int i = 1; i <= n; i++) { 30 | if (j > logs[n - i + 1]) break; 31 | 32 | if (j) st[i][j] = min(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]); 33 | else st[i][0] = a[i]; 34 | } 35 | } 36 | 37 | int ans = 0; 38 | for (int i = 1; i <= m; i++) { 39 | 40 | int l = min(u, v); 41 | int r = max(u, v); 42 | int j = logs[r - l + 1]; 43 | 44 | ans = min(st[l][j], st[r - (1 << j) + 1][j]); 45 | 46 | if (i != m) { 47 | u = ((17 * u + 751 + ans + 2 * i) % n) + 1; 48 | v = ((13 * v + 593 + ans + 5 * i) % n) + 1; 49 | } 50 | } 51 | cout << u << " " << v << " " << ans; 52 | } 53 | -------------------------------------------------------------------------------- /2 - Продвинутое динамическое программирование/B.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import sys 3 | 4 | line = sys.stdin.readline().strip() 5 | 6 | n = len(line) 7 | dp = [[None] * n for el in range(n)] 8 | positions = [[None] * n for el in range(n)] 9 | answer = '' 10 | 11 | def searcher(l, r): 12 | global answer 13 | if dp[l][r] == r - l + 1: 14 | return 15 | if dp[l][r] == 0: 16 | answer += line[l:r + 1] 17 | return 18 | if positions[l][r] == -999: 19 | answer += line[l] 20 | searcher(l + 1, r - 1) 21 | answer += line[r] 22 | return 23 | searcher(l, positions[l][r]) 24 | searcher(positions[l][r] + 1, r) 25 | 26 | 27 | if n > 0: 28 | for i in range(n): 29 | for j in range(n): 30 | if j < i: 31 | dp[i][j] = 0 32 | if i == j: 33 | dp[i][j] = 1 34 | for r in range(n): 35 | for l in range(r, -1, -1): 36 | if l == r: 37 | dp[l][r] = 1 38 | else: 39 | minval = 999 40 | mink = -999 41 | if ((line[l] == '(') & (line[r] == ')')) | ((line[l] == '[') & (line[r] == ']')) | ((line[l] == '{') & (line[r] == '}')): 42 | minval = dp[l + 1][r - 1] 43 | for k in range(l, r): 44 | if (minval > dp[l][k] + dp[k + 1][r]): 45 | minval = dp[l][k] + dp[k + 1][r] 46 | mink = k 47 | dp[l][r] = minval 48 | positions[l][r] = mink 49 | searcher(0, n - 1) 50 | 51 | print (answer) 52 | -------------------------------------------------------------------------------- /1 - Базовое динамическое программирование/E.py: -------------------------------------------------------------------------------- 1 | INF = 300000 2 | 3 | n = int(input()) 4 | prices = [] 5 | dp = [] 6 | 7 | for _ in range(n): 8 | prices.append(int(input())) 9 | 10 | for _ in range(n + 1): 11 | dp.append([INF] * (n + 2)) 12 | 13 | dp[0][0] = 0 14 | rows, cols = len(dp), len(dp[0]) - 1 15 | 16 | for row_id in range(1, rows): 17 | price = prices[row_id - 1] 18 | for col_id in range(cols): 19 | if price > 100: 20 | min_price = min( 21 | INF if col_id == 0 else dp[row_id - 1][col_id - 1] + price, 22 | dp[row_id - 1][col_id + 1], 23 | ) 24 | else: 25 | min_price = min( 26 | dp[row_id - 1][col_id] + price, 27 | dp[row_id - 1][col_id + 1], 28 | ) 29 | dp[row_id][col_id] = min_price 30 | 31 | min_price_id = 0 32 | min_price_val = dp[-1][min_price_id] 33 | 34 | for col_id, val in enumerate(dp[-1]): 35 | if val <= min_price_val: 36 | min_price_val = val 37 | min_price_id = col_id 38 | 39 | days = [] 40 | next_sum, col_id = min_price_val, min_price_id 41 | 42 | for row_id in range(rows - 2, 0, -1): 43 | if dp[row_id][col_id + 1] == next_sum: 44 | days.append(row_id + 1) 45 | col_id += 1 46 | else: 47 | launch_price = prices[row_id] 48 | if next_sum == dp[row_id][col_id] + launch_price and launch_price <= 100: 49 | pass 50 | else: 51 | col_id -= 1 52 | next_sum -= launch_price 53 | 54 | days = list(reversed(days)) 55 | 56 | print(min_price_val) 57 | print(min_price_id, len(days)) 58 | print(*days) 59 | -------------------------------------------------------------------------------- /6 - Запросы на отрезках. Продолжение/D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int t = 0, l = 1; 7 | vector b; 8 | vector> v, up; 9 | vector tin, tout; 10 | 11 | void dfs(int u, int p = 0) { 12 | 13 | int to; 14 | tin[u] = ++t; 15 | up[u][0] = p; 16 | b[u] = true; 17 | 18 | for (int i = 1; i <= l; ++i) { 19 | up[u][i] = up[up[u][i - 1]][i - 1]; 20 | } 21 | 22 | for (int i = 0; i < v[u].size(); ++i) { 23 | 24 | to = v[u][i]; 25 | if (!b[to] && to != p) { 26 | dfs(to, u); 27 | } 28 | } 29 | tout[u] = ++t; 30 | } 31 | 32 | bool is_parent(int a, int b) { 33 | return tin[a] <= tin[b] && tout[a] >= tout[b]; 34 | } 35 | 36 | int lca(int a, int b) { 37 | 38 | if (is_parent(a, b)) return a; 39 | if (is_parent(b, a)) return b; 40 | 41 | for (int i = l; i >= 0; --i) { 42 | 43 | if (!is_parent(up[a][i], b)) 44 | a = up[a][i]; 45 | } 46 | 47 | return up[a][0]; 48 | } 49 | 50 | 51 | int main() { 52 | 53 | int n, m, a, bb; 54 | 55 | cin >> n; 56 | 57 | v.resize(n); 58 | b.resize(n, 0); 59 | tin.resize(n); 60 | tout.resize(n); 61 | up.resize(n); 62 | 63 | for (int i = 1; i < n; ++i) { 64 | 65 | cin >> a; 66 | v[--a].push_back(i); 67 | } 68 | 69 | cin >> m; 70 | 71 | while ((1 << l) <= n) ++l; 72 | 73 | for (int i = 0; i < n; ++i) { 74 | up[i].resize(l + 1); 75 | } 76 | 77 | dfs(0); 78 | 79 | for (int i = 0; i < m; ++i) { 80 | 81 | cin >> a >> bb; 82 | cout << lca(a - 1, bb - 1) + 1 << '\n'; 83 | } 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /6 - Запросы на отрезках. Продолжение/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int n; 6 | long long t[128][128][128]; 7 | 8 | long long get_sum(long long x, long long y, long long z) { 9 | 10 | if (x >= 0 && y >= 0 && z >= 0) { 11 | 12 | long long result = 0; 13 | for (long long i = x; i >= 0; i = (i & (i + 1)) - 1) { 14 | for (long long j = y; j >= 0; j = (j & (j + 1)) - 1) { 15 | for(long long k = z; k >= 0; k = (k & (k + 1)) - 1) 16 | result += t[i][j][k]; 17 | } 18 | } 19 | return result; 20 | 21 | } else 22 | return 0; 23 | } 24 | 25 | void update(int x, int y, int z, int d) { 26 | 27 | for (int i = x; i < n; i = i | (i + 1)) { 28 | for (int j = y; j < n; j = j | (j + 1)) { 29 | for (int k = z; k < n; k = k | (k + 1)) { 30 | t[i][j][k] += d; 31 | } 32 | } 33 | } 34 | } 35 | 36 | int main() { 37 | 38 | cin >> n; 39 | int m = -1; 40 | 41 | while (m != 3) { 42 | 43 | cin >> m; 44 | 45 | if (m == 2) { 46 | 47 | int x1, y1, z1, x2, y2, z2; 48 | cin >> x1 >> y1 >> z1 >> x2 >> y2 >> z2; 49 | cout << get_sum(x2, y2, z2) - get_sum(x2, y1 - 1, z2) 50 | - get_sum(x1 - 1, y2, z2) - get_sum(x2, y2, z1 - 1) 51 | + get_sum(x2, y1 - 1, z1 - 1) + get_sum(x1 - 1, y2, z1 - 1) 52 | + get_sum(x1 - 1, y1 - 1, z2) - get_sum(x1 - 1, y1 - 1, z1 - 1) << endl; 53 | continue; 54 | } 55 | 56 | if (m == 1) { 57 | 58 | int x, y, z, d; 59 | cin >> x >> y >> z >> d; 60 | update(x, y, z, d); 61 | continue; 62 | } 63 | 64 | } 65 | 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /10 - Грамматики и парсинг/hw_10.py: -------------------------------------------------------------------------------- 1 | from pyparsing import * 2 | 3 | ParserElement.enablePackrat() 4 | 5 | number = pyparsing_common.number 6 | variable = OneOrMore(Word(alphas)) 7 | operand = number | variable 8 | 9 | expop = Literal('^') 10 | multop = oneOf('* /') 11 | plusop = oneOf('+ -') 12 | 13 | expr = variable + '=' + infixNotation( 14 | operand, 15 | [(expop, 2, opAssoc.RIGHT), 16 | (multop, 2, opAssoc.LEFT), 17 | (plusop, 2, opAssoc.LEFT),] 18 | ) 19 | 20 | def acc(a, op, b): 21 | if op == '+': 22 | return a + b 23 | elif op == '-': 24 | return a - b 25 | elif op == '*': 26 | return a * b 27 | elif op == '/': 28 | if b == 0: 29 | raise ZeroDivisionError("Деление на ноль") 30 | return a / b 31 | elif op == '^': 32 | return a ** b 33 | 34 | def transform(line): 35 | if type(line)==int: 36 | return line 37 | 38 | if type(line)==float: 39 | return line 40 | 41 | if type(line) == str: 42 | if line not in variables: 43 | raise BaseException("Переменная {} неопределена".format(line)) 44 | return variables[line] 45 | 46 | out = transform(line[0]) 47 | i = 1 48 | while i < len(line): 49 | op = line[i] 50 | i += 1 51 | val = transform(line[i]) 52 | i += 1 53 | out = acc(out, op, val) 54 | return out 55 | 56 | if __name__ == "__main__": 57 | 58 | variables = {} 59 | 60 | with open("std.in", "r") as file: 61 | for i, line in enumerate(file): 62 | 63 | try: 64 | var, equal, statement = expr.parseString(line, parseAll=True) 65 | variables[var] = transform(statement) 66 | print(var, '=', variables[var]) 67 | 68 | except BaseException as e: 69 | print(e) 70 | -------------------------------------------------------------------------------- /14 - Быстрое преобразование Фурье/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | typedef long long ll; 10 | typedef complex cd; 11 | 12 | int n; 13 | string s; 14 | const double PI = 3.1415926535897932384626433832795; 15 | const int MAXN = 1 << 19; 16 | 17 | void fft(vector> &a, vector> &ans, int n, 18 | complex z, int abg, int ast, int ansbg) { 19 | 20 | if (n == 1) { 21 | ans[ansbg] = a[abg]; 22 | return; 23 | } 24 | 25 | fft(a, ans, n >> 1, z * z, abg, ast * 2, ansbg); 26 | fft(a, ans, n >> 1, z * z, abg + ast, ast * 2, ansbg + n / 2); 27 | complex x = 1; 28 | 29 | for (int i = 0; i < (n >> 1); i++) { 30 | complex ans1 = ans[ansbg + i]; 31 | complex ans2 = ans[ansbg + i + n / 2]; 32 | ans[ansbg + i] = ans1 + x * ans2; 33 | ans[ansbg + i + n / 2] = ans1 - x * ans2; 34 | x *= z; 35 | } 36 | } 37 | 38 | void fft(vector> &a, vector> &ans) { 39 | fft(a, ans, MAXN, complex(cos(2 * PI / MAXN), sin(2 * PI / MAXN)), 0, 1, 0); 40 | } 41 | 42 | void inv_fft(vector> &a, vector> &ans) { 43 | fft(a, ans, MAXN, complex(cos(-2 * PI / MAXN), sin(-2 * PI / MAXN)), 0, 1, 0); 44 | for (int i = 0; i < MAXN; i++) { 45 | ans[i] /= MAXN; 46 | } 47 | } 48 | 49 | void solve() { 50 | n = s.size(); 51 | vector q(MAXN); 52 | 53 | for (int i = 0; i < n; i++) { 54 | q[i] = cd(s[i] - '0'); 55 | } 56 | 57 | vector a(MAXN); 58 | fft(q, a); 59 | vector b(MAXN); 60 | 61 | for (int i = 0; i < MAXN; i++) { 62 | b[i] = a[i] * a[i]; 63 | } 64 | 65 | vector c(MAXN); 66 | inv_fft(b, c); 67 | ll ans = 0; 68 | 69 | for (int i = 0; i < MAXN; i += 2) { 70 | if (q[i / 2] == cd(0)) { 71 | continue; 72 | } 73 | 74 | ll cur = (int) (c[i].real() + 0.5); 75 | ans += (cur - 1) / 2; 76 | } 77 | 78 | cout << ans << '\n'; 79 | } 80 | 81 | int main() { 82 | cin >> s; 83 | solve(); 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /5 - Запросы на отрезках/E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | long long r, n, m, q, w; 9 | 10 | struct node { 11 | 12 | long long a11, a12, a21, a22; 13 | 14 | void normalize() { 15 | 16 | a11 %= r; 17 | a12 %= r; 18 | a21 %= r; 19 | a22 %= r; 20 | } 21 | }; 22 | 23 | node operator*(node m1, node m2) { 24 | 25 | node res; 26 | res.a11 = m1.a11 * m2.a11 + m1.a12 * m2.a21; 27 | res.a12 = m1.a11 * m2.a12 + m1.a12 * m2.a22; 28 | res.a21 = m1.a21 * m2.a11 + m1.a22 * m2.a21; 29 | res.a22 = m1.a21 * m2.a12 + m1.a22 * m2.a22; 30 | res.normalize(); 31 | return res; 32 | } 33 | 34 | vector a; 35 | vector t; 36 | 37 | void build(int ind, int l, int r) { 38 | 39 | if (l < r - 1) { 40 | 41 | int c = (l + r) / 2; 42 | build(2 * ind + 1, l, c); 43 | build(2 * ind + 2, c, r); 44 | t[ind] = t[2 * ind + 1] * t[2 * ind + 2]; 45 | 46 | } else { 47 | t[ind] = a[l]; 48 | } 49 | } 50 | 51 | node rmq(int ind, int li, int ri, int l, int r) { 52 | 53 | if (li == l && ri == r) return t[ind]; 54 | int c = (li + ri) / 2; 55 | if (r <= c) return rmq(2 * ind + 1, li, c, l, r); 56 | if (l >= c) return rmq(2 * ind + 2, c, ri, l, r); 57 | node m1 = rmq(2 * ind + 1, li, c, l, c), m2 = rmq(2 * ind + 2, c, ri, c, r); 58 | 59 | return m1 * m2; 60 | } 61 | 62 | int main() { 63 | ios_base::sync_with_stdio(false); 64 | freopen ("crypto.in", "r", stdin); 65 | freopen ("crypto.out", "w", stdout); 66 | cin >> r >> n >> m; 67 | a.resize(n); 68 | t.resize(4 * n); 69 | 70 | for (int i = 0; i < n; i++) { 71 | 72 | cin >> a[i].a11 >> a[i].a12 >> a[i].a21 >> a[i].a22; 73 | a[i].normalize(); 74 | } 75 | 76 | build(0, 0, n); 77 | 78 | for (int i = 0; i < m; i++) { 79 | 80 | cin >> q >> w; 81 | node t = rmq(0, 0, n, q - 1, w); 82 | cout << t.a11 << " " << t.a12 << endl << t.a21 << " " << t.a22 << "\n\n"; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /5 - Запросы на отрезках/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int get_mid(int l, int r) { 6 | return l + (r - l) / 2; 7 | } 8 | 9 | void update(long long* tree, int tl, int tr, int i, long long diff, int ind) { 10 | if (i < tl || i > tr) { 11 | return; 12 | } 13 | 14 | tree[ind] = tree[ind] + diff; 15 | if (tr != tl) { 16 | int mid = get_mid(tl, tr); 17 | update(tree, tl, mid, i, diff, 2 * ind + 1); 18 | update(tree, mid + 1, tr, i, diff, 2 * ind + 2); 19 | } 20 | } 21 | 22 | long long summa(long long* tree, int tl, int tr, int l, int r, int ind) { 23 | if (l <= tl && r >= tr) { 24 | return tree[ind]; 25 | } 26 | 27 | if (tr < l || tl > r) { 28 | return 0; 29 | } 30 | 31 | int mid = get_mid(tl, tr); 32 | 33 | return summa(tree, tl, mid, l, r, 2 * ind + 1) + summa(tree, mid + 1, tr, l, r, 2 * ind + 2); 34 | 35 | } 36 | 37 | long long build(long long* a, int tl, int tr, long long* tree, int ind) { 38 | if (tl == tr) { 39 | tree[ind] = a[tl]; 40 | return a[tl]; 41 | } 42 | 43 | int mid = get_mid(tl, tr); 44 | tree[ind] = build(a, tl, mid, tree, ind * 2 + 1) + build(a, mid + 1, tr, tree, ind * 2 + 2); 45 | 46 | return tree[ind]; 47 | } 48 | 49 | int main() { 50 | 51 | int n; 52 | cin >> n; 53 | 54 | long long a[n]; 55 | for (int i = 0; i < n; i++) { 56 | cin >> a[i]; 57 | } 58 | 59 | long long* tree = new long long[4 * n]; 60 | build(a, 0, n - 1, tree, 0); 61 | string oper; 62 | 63 | while (cin >> oper) { 64 | 65 | if (oper == "sum") { 66 | int i, j; 67 | cin >> i; 68 | cin >> j; 69 | cout << summa(tree, 0, n - 1, i - 1, j - 1, 0) << "\n"; 70 | } 71 | 72 | if (oper == "set") { 73 | int i; 74 | long long x, diff; 75 | cin >> i; 76 | cin >> x; 77 | diff = x - a[i - 1]; 78 | a[i - 1] = x; 79 | update(tree, 0, n - 1, i - 1, diff, 0); 80 | } 81 | } 82 | 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /3 - Базовая теория чисел/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int pow (int a, int n) { 7 | int res = 1; 8 | while (n) { 9 | if (n & 1) { 10 | res *= a; 11 | } 12 | a *= a; 13 | n >>= 1; 14 | } 15 | return res; 16 | } 17 | 18 | const int N = 100000000; 19 | int d[N]; 20 | vector primes; 21 | 22 | int main() { 23 | 24 | for (int i = 2; i < N; i++) { 25 | if (!d[i]) { 26 | d[i] = i; 27 | primes.push_back(i); 28 | } 29 | 30 | for (auto p : primes) { 31 | if (p > d[i] || i * p >= N) { 32 | break; 33 | } 34 | d[i * p] = p; 35 | } 36 | } 37 | 38 | d[1] = 1; 39 | int n = 0; 40 | 41 | cin >> n; 42 | 43 | long long sum_d = 0; 44 | long long sum_phi = 1; 45 | long long sum_s0 = 1; 46 | long long sum_s1 = 1; 47 | 48 | for (int i = 2; i <= n; i++) { 49 | int k = i; 50 | int prev = d[k]; 51 | int prev_count = 0; 52 | long long euler = 1; 53 | long long s0 = 1; 54 | long long s1 = 1; 55 | while (true) { 56 | if (d[k] == prev) { 57 | prev_count += 1; 58 | } 59 | 60 | if (d[k] != prev) { 61 | euler *= (pow(prev, prev_count) - pow(prev, prev_count - 1)); 62 | s0 *= prev_count + 1; 63 | long long sigma = 0; 64 | long long tmp = 1; 65 | for (int j = 0; j <= prev_count; j++) { 66 | sigma += tmp; 67 | tmp *= prev; 68 | } 69 | s1 *= sigma; 70 | prev_count = 1; 71 | prev = d[k]; 72 | } 73 | 74 | if (k == 1) { 75 | break; 76 | } 77 | 78 | k /= d[k]; 79 | } 80 | 81 | sum_phi += euler; 82 | sum_s0 += s0; 83 | sum_s1 += s1; 84 | sum_d += d[i]; 85 | } 86 | 87 | cout << sum_d << " " << sum_s0 << " " << sum_s1 << " " << sum_phi; 88 | 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /4 - Продвинутая теория чисел/E.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import sys 3 | from random import randint 4 | import random 5 | #import time 6 | 7 | n = int(sys.stdin.readline().strip()) 8 | 9 | def gcd(a, b): 10 | while b > 0: 11 | a, b = b, a % b 12 | return a 13 | 14 | def f(x, c, m): 15 | return (x ** 2) * c + m 16 | 17 | def miller_rabin(n): 18 | if n in [0, 1, 4, 6, 8, 9]: 19 | return False 20 | if n in [2, 3, 5, 7]: 21 | return True 22 | s = 0 23 | d = n - 1 24 | while d % 2 == 0: 25 | d >>= 1 26 | s += 1 27 | def check(a): 28 | if pow(a, d, n) == 1: 29 | return False 30 | for i in range(s): 31 | if pow(a, 2 ** i * d, n) == n - 1: 32 | return False 33 | return True 34 | for i in range(3): 35 | a = random.randrange(2, n) 36 | if check(a): 37 | return False 38 | return True 39 | 40 | def search_fac(n): 41 | maxiterssq = 0.5 * n 42 | x = randint(1, n-1) 43 | y = x 44 | d = 1 45 | iters = 0 46 | c = randint(1, n-1) 47 | m = randint(1, n-1) 48 | while d == 1 or d == n: 49 | if iters ** 2 > maxiterssq: 50 | c = randint(1, n-1) 51 | m = randint(1, n-1) 52 | x = randint(1, n-1) 53 | y = x 54 | iters = 0 55 | x = f(x, c, m) % n 56 | y = f(f(y, c, m), c, m) % n 57 | d = gcd(abs(x - y), n) 58 | iters += 1 59 | return d 60 | 61 | def search_prime_fac(n, factors): 62 | if miller_rabin(n): 63 | factors.append(n) 64 | else: 65 | temp = n // search_fac(n) 66 | search_prime_fac(temp, factors) 67 | 68 | def factor(n, factors): 69 | while n % 2 == 0: 70 | factors.append(2) 71 | n //= 2 72 | while n % 3 == 0: 73 | factors.append(3) 74 | n //= 3 75 | while n > 1: 76 | search_prime_fac(n, factors) 77 | n //= factors[-1] 78 | 79 | #n = 1000000000000000000001 80 | #s = time.time() 81 | factors = [] 82 | factor(n, factors) 83 | factors.sort() 84 | print(' '.join(map(str, factors))) 85 | 86 | #print (time.time()-s) 87 | -------------------------------------------------------------------------------- /8 - Максимальный поток и минимальный разрез/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int n; 7 | int m; 8 | 9 | struct Edge { 10 | 11 | int from = 0; 12 | int to = 0; 13 | int f = 0; 14 | int c = 0; 15 | Edge *rev = nullptr; 16 | 17 | Edge() = default; 18 | 19 | Edge(int from, int to, int c) : from(from), to(to), f(0), c(c) {} 20 | }; 21 | 22 | vector Edges; 23 | 24 | vector> graph; 25 | 26 | vector used; 27 | 28 | int dfs(int cur, int c) { 29 | 30 | if (cur == n - 1) { 31 | return c; 32 | } 33 | 34 | used[cur] = true; 35 | for (int i = 0; i < graph[cur].size(); ++i) { 36 | int next = graph[cur][i] -> to; 37 | Edge *e = graph[cur][i]; 38 | if (!used[next] && e -> f < e -> c) { 39 | int diff = dfs(next, min(e -> c - e -> f, c)); 40 | if (diff > 1e-5) { 41 | e -> f += diff; 42 | e -> rev -> f -= diff; 43 | return diff; 44 | } 45 | } 46 | } 47 | return 0; 48 | } 49 | 50 | int Dinic() { 51 | 52 | int ans = 0; 53 | int maxans = 0; 54 | 55 | do { 56 | 57 | ans = dfs(0, 1e9); 58 | fill(used.begin(), used.end(), false); 59 | maxans += ans; 60 | } while (ans > 1e-5); 61 | return maxans; 62 | } 63 | 64 | int main() { 65 | 66 | cin >> n; 67 | cin >> m; 68 | 69 | graph.resize(n, vector()); 70 | 71 | Edges.resize(2 * m); 72 | 73 | for (int i = 0; i < 2 * m; i += 2) { 74 | 75 | int from; 76 | int to; 77 | int c; 78 | cin >> from >> to >> c; 79 | from--; 80 | to--; 81 | Edges[i] = Edge(from, to, c); 82 | Edges[i + 1] = Edge(to, from, c); 83 | Edges[i].rev = &Edges[i + 1]; 84 | Edges[i + 1].rev = &Edges[i]; 85 | graph[from].emplace_back(&Edges[i]); 86 | graph[to].emplace_back(&Edges[i + 1]); 87 | } 88 | 89 | used.resize(n, false); 90 | cout.precision(10); 91 | cout << Dinic() << endl; 92 | 93 | for (int i = 0; i < 2 * m; i += 2) { 94 | cout << Edges[i].f << '\n'; 95 | } 96 | return 0; 97 | } 98 | -------------------------------------------------------------------------------- /6 - Запросы на отрезках. Продолжение/E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int t = 0, l = 1; 7 | vector b; 8 | vector tin, tout; 9 | vector>> v; 10 | vector> up, min_up; 11 | 12 | 13 | void dfs(int u, int p = 0, int w = 1000000) { 14 | 15 | up[u][0] = p; 16 | tin[u] = ++t; 17 | b[u] = true; 18 | min_up[u][0] = w; 19 | 20 | for (int i = 1; i <= l; ++i) { 21 | 22 | up[u][i] = up[up[u][i - 1]][i - 1]; 23 | min_up[u][i] = min(min_up[up[u][i - 1]][i - 1], min_up[u][i - 1]); 24 | } 25 | 26 | for (int i = 0; i < v[u].size(); ++i) { 27 | 28 | int to = v[u][i].first; 29 | 30 | if (!b[to] && to != p) { 31 | dfs(to, u, v[u][i].second); 32 | } 33 | 34 | } 35 | tout[u] = ++t; 36 | } 37 | bool is_parent(int a, int b) { 38 | return tin[a] <= tin[b] && tout[a] >= tout[b]; 39 | } 40 | 41 | int lca(int a, int b) { 42 | 43 | if (is_parent(a, b)) return 1000000; 44 | int to = min_up[a][0]; 45 | 46 | for (int i = l; i >= 0; --i) { 47 | 48 | if (!is_parent(up[a][i], b)) { 49 | to = min(to, min_up[a][i]); 50 | a = up[a][i]; 51 | } 52 | } 53 | 54 | return min(min_up[a][0], to); 55 | } 56 | 57 | int main() { 58 | 59 | freopen ("minonpath.in", "r", stdin); 60 | freopen ("minonpath.out", "w", stdout); 61 | 62 | int n, m, a_t, b_t; 63 | 64 | cin >> n; 65 | 66 | b.resize(n, 0); 67 | v.resize(n); 68 | tin.resize(n); 69 | tout.resize(n); 70 | up.resize(n); 71 | min_up.resize(n); 72 | 73 | for (int i = 1; i < n; ++i) { 74 | 75 | cin >> a_t >> b_t; 76 | v[a_t - 1].push_back(make_pair(i, b_t)); 77 | } 78 | 79 | cin >> m; 80 | 81 | while ((1 << l) <= n) ++l; 82 | 83 | for (int i = 0; i> a_t >> b_t; 94 | a_t -=1; 95 | b_t -=1; 96 | cout << min(lca(a_t, b_t), lca(b_t, a_t)) << '\n'; 97 | } 98 | return 0; 99 | } 100 | -------------------------------------------------------------------------------- /13 - Вычислительная геометрия/A.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import sys 3 | 4 | class Point: 5 | def __init__(self, x, y): 6 | self.x = x 7 | self.y = y 8 | self.o = (x, y) 9 | def minus(self, p): 10 | x = self.x - p.x 11 | y = self.y - p.y 12 | return Point(x, y) 13 | def plus(self, p): 14 | x = self.x + p.x 15 | y = self.y + p.y 16 | return Point(x, y) 17 | def __str__(self): 18 | return str(format(self.x, '.10f')) + ' ' + str(format(self.y, '.10f')) 19 | 20 | class Circle: 21 | def __init__(self, x, y, r): 22 | self.p = Point(x, y) 23 | self.r = r 24 | 25 | class Line: 26 | def __init__(self, a, b, c): 27 | self.a = a 28 | self.b = b 29 | self.c = c 30 | 31 | if __name__ == "__main__": 32 | 33 | n = int(sys.stdin.readline().strip()) 34 | 35 | for _ in range(n): 36 | 37 | x1, y1, r1 = list(map(int, sys.stdin.readline().strip().split(' '))) 38 | x2, y2, r2 = list(map(int, sys.stdin.readline().strip().split(' '))) 39 | 40 | c1, c2 = Circle(x1, y1, r1), Circle(x2, y2, r2) 41 | 42 | if (c1.p.o == c2.p.o): 43 | if (c1.r == c2.r): 44 | print("3") 45 | continue 46 | else: 47 | print("0") 48 | continue 49 | 50 | o1 = c1.p 51 | o2 = c2.p 52 | o2 = o2.minus(o1) 53 | line = Line(-2 * o2.x, -2 * o2.y, (o2.x) ** 2 + (o2.y) ** 2 - (c2.r) ** 2 + (c1.r) ** 2) 54 | 55 | a_kv_b_kv = (line.a) ** 2 + (line.b) ** 2 56 | c_kv = (line.c) ** 2 57 | r_kv = (c1.r) ** 2 58 | r_kv_a_kv_b_kv = r_kv * a_kv_b_kv 59 | 60 | if (c_kv > r_kv_a_kv_b_kv): 61 | print ("0") 62 | continue 63 | 64 | h = Point(-1 * line.a * line.c / a_kv_b_kv, -1 * line.b * line.c / a_kv_b_kv) 65 | 66 | if (c_kv == r_kv_a_kv_b_kv): 67 | print("1") 68 | print(h.plus(o1)) 69 | continue 70 | 71 | c_kv_a_kv_b_kv = c_kv / a_kv_b_kv 72 | len_hp_kv = r_kv - c_kv_a_kv_b_kv 73 | oh = (c_kv_a_kv_b_kv) ** 0.5 74 | len_hp = (len_hp_kv) ** 0.5 75 | mult = (len_hp_kv / a_kv_b_kv) ** 0.5 76 | hp = Point(line.b * mult, -line.a * mult) 77 | p1 = h.plus(hp) 78 | p2 = h.minus(hp) 79 | 80 | print("2") 81 | print(h.plus(o1)) 82 | print(str(format(oh, '.10f')) + " " + str(format(len_hp, '.10f'))) 83 | print(p1.plus(o1)) 84 | print(p2.plus(o1)) 85 | -------------------------------------------------------------------------------- /4 - Продвинутая теория чисел/C.py: -------------------------------------------------------------------------------- 1 | def power(x, y, p): 2 | res = 1 3 | x = x % p 4 | while y > 0: 5 | if y & 1: 6 | res = (res * x) % p 7 | y = y >> 1 8 | x = (x * x) % p 9 | return res 10 | 11 | def gcd_extend(a, b, x, y): 12 | if (a == 0): 13 | x[0] = 0 14 | y[0] = 1 15 | return b 16 | x_new = [0] 17 | y_new = [0] 18 | d = gcd_extend(b % a, a, x_new, y_new) 19 | x[0] = y_new[0] - (b // a) * x_new[0] 20 | y[0] = x_new[0] 21 | return d 22 | 23 | def LDE(a, b, c): 24 | x = [-1] 25 | y = [-1] 26 | gcd = gcd_extend(a, b, x, y) 27 | if c % gcd != 0: 28 | return -1 29 | else: 30 | c //= gcd 31 | return - x[0] * c, - y[0] * c 32 | 33 | def discrete_log(a, b, m): 34 | 35 | def create_s2(): 36 | S2 = {} 37 | tmp = (b * a) % m 38 | for s in range(1, k + 1): 39 | S2[tmp] = s 40 | tmp = (tmp * a) % m 41 | return S2 42 | 43 | def find_x(): 44 | mn = power(a, k, m) 45 | tmp = mn 46 | for r in range(1, k + 1): 47 | if tmp in S2: 48 | return (r * k - S2[tmp]) % m 49 | tmp = (tmp * mn) % m 50 | return -1 51 | 52 | k = int(m ** (1 / 2) + 1) 53 | S2 = create_s2() 54 | return find_x() 55 | 56 | def get_generator(p): 57 | 58 | def get_prime_devisors(n): 59 | prime_devisors = [] 60 | cur_div = 2 61 | while cur_div ** 2 <= n: 62 | if n % cur_div == 0: 63 | prime_devisors.append(cur_div) 64 | while n % cur_div == 0: 65 | n //= cur_div 66 | cur_div += 1 67 | if n > 1: 68 | prime_devisors.append(n) 69 | return prime_devisors 70 | 71 | def check_gen(g, p): 72 | for i in prime_div_p_min_1: 73 | if power(g, (p - 1) // i, p) == 1: 74 | return False 75 | return True 76 | 77 | prime_div_p_min_1 = get_prime_devisors(p - 1) 78 | for g in range(2, p + 1): 79 | if check_gen(g, p): 80 | return g 81 | 82 | def discr_sqrt(b, k, p): 83 | g = get_generator(p) 84 | s = discrete_log(g, b, p) 85 | if s == -1: 86 | return -1 87 | else: 88 | lde = LDE(k, p - 1, -s) 89 | if lde == -1: 90 | return -1 91 | else: 92 | return power(g, lde[0] % (p - 1), p) 93 | 94 | t = int(input()) 95 | for _ in range(t): 96 | a, b, m = list(map(int, input().split())) 97 | print(discr_sqrt(a, b, m)) 98 | -------------------------------------------------------------------------------- /15 - Персистентные структуры данных/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | struct Node { 7 | int val; 8 | Node* lchild; 9 | Node* rchild; 10 | }; 11 | 12 | void build(Node* node, int* base, int l, int r) { 13 | if (l == r) { 14 | node -> val = base[l - 1]; 15 | } 16 | 17 | else { 18 | int m = (l + r) / 2; 19 | node -> lchild = new Node(); 20 | build(node -> lchild, base, l, m); 21 | node -> rchild = new Node(); 22 | build(node -> rchild, base, m + 1, r); 23 | } 24 | } 25 | 26 | void add(Node* to, Node* from, int l, int r, int npos, int nv) { 27 | if (l == r) { 28 | to -> val = nv; 29 | } 30 | 31 | else { 32 | int m = (l + r) / 2; 33 | if (npos <= m) { 34 | to -> rchild = from -> rchild; 35 | Node* left = new Node(); 36 | add(left, from -> lchild, l, m, npos, nv); 37 | to -> lchild = left; 38 | } 39 | 40 | else { 41 | to -> lchild = from -> lchild; 42 | Node* right = new Node(); 43 | add(right, from -> rchild, m + 1, r, npos, nv); 44 | to -> rchild = right; 45 | } 46 | } 47 | } 48 | 49 | int get(Node* node, int l, int r, int pos) { 50 | if (l == r) { 51 | return node -> val; 52 | } 53 | 54 | else { 55 | int m = (l + r) / 2; 56 | if (pos <= m) { 57 | return get(node -> lchild, l, m, pos); 58 | } 59 | 60 | else { 61 | return get(node -> rchild, m + 1, r, pos); 62 | } 63 | } 64 | } 65 | 66 | int main() { 67 | int n; 68 | cin >> n; 69 | int base[n]; 70 | 71 | for (int i = 0; i < n; i++) { 72 | cin >> base[i]; 73 | } 74 | 75 | vector parray; 76 | parray.push_back(new Node()); 77 | build(parray.at(0), base, 1, n); 78 | int m; 79 | 80 | cin >> m; 81 | 82 | for (int i = 0; i < m; i++) { 83 | string s; 84 | cin >> s; 85 | 86 | if (s == "create") { 87 | int rootPos, newPos, newVal; 88 | cin >> rootPos >> newPos >> newVal; 89 | parray.push_back(new Node()); 90 | add(parray.back(), parray.at(rootPos-1), 1, n, newPos, newVal); 91 | } 92 | 93 | else { 94 | int rootPos, valPos; 95 | cin >> rootPos >> valPos; 96 | cout << get(parray.at(rootPos-1), 1, n, valPos) << '\n'; 97 | } 98 | } 99 | 100 | return 0; 101 | } 102 | -------------------------------------------------------------------------------- /14 - Быстрое преобразование Фурье/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | typedef long long ll; 11 | typedef complex cd; 12 | 13 | const double PI = 3.1415926535897932384626433832795; 14 | const int MAXN = 1 << 19; 15 | int n; 16 | string s, t; 17 | vector a; 18 | vector b; 19 | int sum[MAXN]; 20 | 21 | void fft(vector> &a, vector> &ans, int n, 22 | complex z, int abg, int ast, int ansbg) { 23 | 24 | if (n == 1) { 25 | ans[ansbg] = a[abg]; 26 | return; 27 | } 28 | 29 | fft(a, ans, n >> 1, z * z, abg, ast * 2, ansbg); 30 | fft(a, ans, n >> 1, z * z, abg + ast, ast * 2, ansbg + n / 2); 31 | complex x = 1; 32 | 33 | for (int i = 0; i < (n >> 1); i++) { 34 | complex ans1 = ans[ansbg + i]; 35 | complex ans2 = ans[ansbg + i + n / 2]; 36 | ans[ansbg + i] = ans1 + x * ans2; 37 | ans[ansbg + i + n / 2] = ans1 - x * ans2; 38 | x *= z; 39 | } 40 | } 41 | 42 | void fft(vector> &a, vector> &ans) { 43 | fft(a, ans, MAXN, complex(cos(2 * PI / MAXN), sin(2 * PI / MAXN)), 0, 1, 0); 44 | } 45 | 46 | void inv_fft(vector> &a, vector> &ans) { 47 | fft(a, ans, MAXN, complex(cos(-2 * PI / MAXN), sin(-2 * PI / MAXN)), 0, 1, 0); 48 | for (int i = 0; i < MAXN; i++) { 49 | ans[i] /= MAXN; 50 | } 51 | } 52 | 53 | void solve() { 54 | vector a_ans(MAXN), b_ans(MAXN), c(MAXN), c_ans(MAXN); 55 | fft(a, a_ans); 56 | fft(b, b_ans); 57 | 58 | for (int i = 0; i < MAXN; i++) { 59 | c[i] = a_ans[i] * b_ans[i]; 60 | } 61 | 62 | inv_fft(c, c_ans); 63 | 64 | for (int i = 0; i < MAXN; i++) { 65 | sum[i] += (int) (c_ans[i].real() + 0.5); 66 | } 67 | } 68 | 69 | int main() { 70 | cin >> n >> s >> t; 71 | set dct = {'A', 'C', 'G', 'T'}; 72 | 73 | for (char c : dct) { 74 | a.clear(); 75 | b.clear(); 76 | a.resize(MAXN); 77 | b.resize(MAXN); 78 | 79 | for (int i = 0; i < s.size(); i++) { 80 | if (s[i] == c) { 81 | a[i] = cd(1); 82 | a[i + s.size()] = cd(1); 83 | } 84 | } 85 | 86 | for (int i = 0; i < t.size(); i++) { 87 | if (t[i] == c) { 88 | b[s.size() - 1 - i] = cd(1); 89 | } 90 | } 91 | 92 | solve(); 93 | } 94 | 95 | int ans = 0; 96 | int pos = 0; 97 | 98 | for (int i = s.size() - 1; i + 1 < 2 * s.size(); i++) { 99 | if (sum[i] > ans) { 100 | ans = sum[i]; 101 | pos = i - s.size() + 1; 102 | } 103 | } 104 | 105 | cout << ans << ' ' << pos; 106 | return 0; 107 | } 108 | -------------------------------------------------------------------------------- /14 - Быстрое преобразование Фурье/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | typedef long long ll; 10 | 11 | int n; 12 | string s, t; 13 | 14 | const double PI = 3.1415926535897932384626433832795; 15 | const int MAXN = 1 << 19; 16 | 17 | void fft(vector> &a, vector> &ans, int n, 18 | complex z, int abg, int ast, int ansbg) { 19 | 20 | if (n == 1) { 21 | ans[ansbg] = a[abg]; 22 | return; 23 | } 24 | 25 | fft(a, ans, n >> 1, z * z, abg, ast * 2, ansbg); 26 | fft(a, ans, n >> 1, z * z, abg + ast, ast * 2, ansbg + n / 2); 27 | complex x = 1; 28 | 29 | for (int i = 0; i < (n >> 1); i++) { 30 | complex ans1 = ans[ansbg + i]; 31 | complex ans2 = ans[ansbg + i + n / 2]; 32 | ans[ansbg + i] = ans1 + x * ans2; 33 | ans[ansbg + i + n / 2] = ans1 - x * ans2; 34 | x *= z; 35 | } 36 | } 37 | 38 | void fft(vector> &a, vector> &ans) { 39 | fft(a, ans, MAXN, complex(cos(2 * PI / MAXN), sin(2 * PI / MAXN)), 0, 1, 0); 40 | } 41 | 42 | void inv_fft(vector> &a, vector> &ans) { 43 | fft(a, ans, MAXN, complex(cos(-2 * PI / MAXN), sin(-2 * PI / MAXN)), 0, 1, 0); 44 | for (int i = 0; i < MAXN; i++) { 45 | ans[i] /= MAXN; 46 | } 47 | } 48 | 49 | int neg = 0; 50 | 51 | void prepare(string &a) { 52 | if (a[0] == '-') { 53 | neg ^= 1; 54 | a.erase(a.begin()); 55 | } 56 | 57 | reverse(a.begin(), a.end()); 58 | 59 | while (a.size() < MAXN) { 60 | a.push_back('0'); 61 | } 62 | } 63 | 64 | void solve() { 65 | prepare(s); 66 | prepare(t); 67 | vector> a(MAXN), b(MAXN), a_ans(MAXN), b_ans(MAXN); 68 | 69 | for (int i = 0; i < MAXN; i++) { 70 | a[i] = complex(s[i] - '0'); 71 | } 72 | 73 | for (int i = 0; i < MAXN; i++) { 74 | b[i] = complex(t[i] - '0'); 75 | } 76 | 77 | fft(a, a_ans); 78 | fft(b, b_ans); 79 | vector> c(MAXN); 80 | 81 | for (int i = 0; i < MAXN; i++) { 82 | c[i] = a_ans[i] * b_ans[i]; 83 | a[i] = 0; 84 | } 85 | 86 | inv_fft(c, a); 87 | int carry = 0; 88 | string ans; 89 | 90 | for (int i = 0; i < MAXN; i++) { 91 | int cur = (int) (a[i].real() + 0.5) + carry; 92 | ans.push_back('0' + cur % 10); 93 | carry = cur / 10; 94 | } 95 | 96 | while (ans.size() > 1 && ans.back() == '0') { 97 | ans.pop_back(); 98 | } 99 | 100 | reverse(ans.begin(), ans.end()); 101 | 102 | if (neg && ans != "0") { 103 | cout << '-'; 104 | } 105 | 106 | cout << ans << '\n'; 107 | } 108 | 109 | int main() { 110 | cin >> s >> t; 111 | solve(); 112 | return 0; 113 | } 114 | -------------------------------------------------------------------------------- /6 - Запросы на отрезках. Продолжение/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | const int SIZE = 524288; 8 | const int SHIFT = 200000; 9 | 10 | struct node { 11 | int dy, ty, delta, x; 12 | }; 13 | 14 | bool cmp(node &a, node &b) { 15 | return (a.x != b.x ? a.x < b.x : a.delta > b.delta); 16 | } 17 | 18 | vector a(4 * SIZE + 1, 0), lazy(4 * SIZE + 1, 0); 19 | 20 | void push(size_t ind) { 21 | lazy[2 * ind + 1] += lazy[ind]; 22 | lazy[2 * ind + 2] += lazy[ind]; 23 | lazy[ind] = 0; 24 | } 25 | 26 | void add(size_t ind, int li, int ri, int l, int r, int delta) { 27 | 28 | if (li == l && ri == r) { 29 | lazy[ind] += delta; 30 | return; 31 | } 32 | 33 | push(ind); 34 | int c = (li + ri) / 2; 35 | if (r <= c) add(2 * ind + 1, li, c, l, r, delta); 36 | if (l >= c) add(2 * ind + 2, c, ri, l, r, delta); 37 | if (r > c && l < c) { 38 | add(2 * ind + 1, li, c, l, c, delta); 39 | add(2 * ind + 2, c, ri, c, r, delta); 40 | } 41 | 42 | int g = a[2 * ind + 1] + lazy[2 * ind + 1]; 43 | int h = a[2 * ind + 2] + lazy[2 * ind + 2]; 44 | a[ind] = max(g, h); 45 | } 46 | 47 | pair query(size_t ind, size_t li, size_t ri) { 48 | 49 | if (li + 1 == ri) { 50 | 51 | a[ind] += lazy[ind]; 52 | lazy[ind] = 0; 53 | return {a[ind], li}; 54 | } 55 | 56 | push(ind); 57 | int g = a[2 * ind + 1] + lazy[2 * ind + 1]; 58 | int h = a[2 * ind + 2] + lazy[2 * ind + 2]; 59 | a[ind] = max(g, h); 60 | 61 | size_t c = (li + ri) / 2; 62 | 63 | if (g > h) { 64 | return query(2 * ind + 1, li, c); 65 | } else { 66 | return query(2 * ind + 2, c, ri); 67 | } 68 | } 69 | 70 | int main() { 71 | 72 | size_t n; 73 | cin >> n; 74 | int x1, y1, x2, y2; 75 | vector s(2 * n); 76 | 77 | for (size_t i = 0; i < n; i++) { 78 | 79 | cin >> x1 >> y1 >> x2 >> y2; 80 | y1 += SHIFT; 81 | y2 += SHIFT; 82 | s[2 * i] = node{y1, y2, 1, x1 + SHIFT}; 83 | s[2 * i + 1] = node{y1, y2, -1, x2 + SHIFT}; 84 | } 85 | 86 | sort(s.begin(), s.end(), cmp); 87 | 88 | int max_res = -1, x = 0, y = 0; 89 | 90 | for (size_t i = 0; i < n * 2; i++) { 91 | 92 | add(0, 0, 4 * SHIFT + 1, s[i].dy, s[i].ty + 1, s[i].delta); 93 | auto tmp = query(0, 0, 4 * SHIFT + 1); 94 | 95 | if (tmp.first > max_res) { 96 | 97 | max_res = tmp.first; 98 | x = s[i].x; 99 | y = tmp.second; 100 | } 101 | } 102 | 103 | cout << max_res << endl << x - SHIFT << " " << y - SHIFT; 104 | 105 | return 0; 106 | } 107 | -------------------------------------------------------------------------------- /8 - Максимальный поток и минимальный разрез/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int n; 8 | int m; 9 | 10 | struct Edge { 11 | 12 | int from = 0; 13 | int to = 0; 14 | int f = 0; 15 | int c = 0; 16 | Edge *rev = nullptr; 17 | int index = 0; 18 | 19 | Edge() = default; 20 | 21 | Edge(int from, int to, int c, int index) : from(from), to(to), f(0), c(c), index(index) {} 22 | }; 23 | 24 | vector Edges; 25 | 26 | vector> graph; 27 | 28 | vector used; 29 | 30 | int dfs(int cur, int c) { 31 | 32 | if (cur == n - 1) { 33 | return c; 34 | } 35 | 36 | used[cur] = true; 37 | for (int i = 0; i < graph[cur].size(); ++i) { 38 | int next = graph[cur][i] -> to; 39 | Edge *e = graph[cur][i]; 40 | if (!used[next] && e -> f < e -> c) { 41 | int diff = dfs(next, min(e -> c - e -> f, c)); 42 | if (diff > 1e-5) { 43 | e -> f += diff; 44 | e -> rev -> f -= diff; 45 | return diff; 46 | } 47 | } 48 | } 49 | return 0; 50 | } 51 | 52 | int Dinic() { 53 | 54 | int ans = 0; 55 | int maxans = 0; 56 | 57 | do { 58 | 59 | ans = dfs(0, 1e9); 60 | fill(used.begin(), used.end(), false); 61 | maxans += ans; 62 | } while (ans > 1e-5); 63 | return maxans; 64 | } 65 | 66 | void draw(int cur) { 67 | 68 | used[cur] = true; 69 | 70 | for (int i = 0; i < graph[cur].size(); ++i) { 71 | 72 | Edge *e = graph[cur][i]; 73 | int next = e -> to; 74 | 75 | if (!used[next] && e -> c - e -> f > 1e-5) { 76 | draw(next); 77 | } 78 | } 79 | } 80 | 81 | vector incut; 82 | 83 | void find_edges() { 84 | 85 | for (int i = 0; i < 2 * m; i += 2) { 86 | 87 | if (used[Edges[i].from] ^ used[Edges[i].to]) { 88 | incut.emplace_back(&Edges[i]); 89 | } 90 | } 91 | } 92 | 93 | int main() { 94 | 95 | cin >> n; 96 | cin >> m; 97 | 98 | graph.resize(n, vector()); 99 | 100 | Edges.resize(2 * m); 101 | 102 | for (int i = 0; i < 2 * m; i += 2) { 103 | 104 | int from; 105 | int to; 106 | int c; 107 | cin >> from >> to >> c; 108 | from--; 109 | to--; 110 | Edges[i] = Edge(from, to, c, i); 111 | Edges[i + 1] = Edge(to, from, c, i + 1); 112 | Edges[i].rev = &Edges[i + 1]; 113 | Edges[i + 1].rev = &Edges[i]; 114 | graph[from].emplace_back(&Edges[i]); 115 | graph[to].emplace_back(&Edges[i + 1]); 116 | } 117 | 118 | used.resize(n, false); 119 | cout.precision(10); 120 | int F = Dinic(); 121 | fill(used.begin(), used.end(), false); 122 | draw(0); 123 | find_edges(); 124 | int sum = 0; 125 | sort(incut.begin(), incut.end(), [](Edge *e1, Edge *e2) { return e1->index < e2->index; }); 126 | cout << incut.size() << ' ' << F << endl; 127 | 128 | for (auto it : incut) { 129 | 130 | cout << it -> index / 2 + 1 << ' '; 131 | } 132 | return 0; 133 | } 134 | -------------------------------------------------------------------------------- /13 - Вычислительная геометрия/B.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import sys 3 | 4 | class Point: 5 | def __init__(self, x, y): 6 | self.x = x 7 | self.y = y 8 | self.o = (x, y) 9 | def dot(self, p): 10 | return self.x * p.y - self.y * p.x 11 | 12 | class Line: 13 | def __init__(self, a, b, c): 14 | self.a = a 15 | self.b = b 16 | self.c = c 17 | def get_intersection(self, l): 18 | d = self.a * l.b - self.b * l.a 19 | x = (self.b * l.c - self.c * l.b) / d 20 | y = (self.c * l.a - self.a * l.c) / d 21 | return Point(x, y) 22 | 23 | class HalfPlane(Line): 24 | def __init__(self, a, b, c): 25 | super().__init__(a, b, c) 26 | def has_point(self, p): 27 | return self.a * p.x + self.b * p.y +self.c >= 0 28 | 29 | class Poly: 30 | def __init__(self): 31 | self.max_cell = 20000 32 | self.points = [[-self.max_cell, -self.max_cell], 33 | [+self.max_cell, -self.max_cell], 34 | [+self.max_cell, +self.max_cell], 35 | [-self.max_cell, +self.max_cell]] 36 | self.lines = [[0, 1, self.max_cell], 37 | [-1, 0, self.max_cell], 38 | [0, -1, self.max_cell], 39 | [1, 0, self.max_cell]] 40 | 41 | def area(self): 42 | a = Point(self.points[0][0], self.points[0][1]) 43 | area = 0 44 | 45 | for i in range(1, len(self.points) - 1): 46 | b = Point(self.points[i][0], self.points[i][1]) 47 | c = Point(self.points[i + 1][0], self.points[i + 1][1]) 48 | area += Point(b.x - a.x, b.y - a.y).dot(Point(c.x - a.x, c.y - a.y)) 49 | 50 | area *= 0.5 51 | return area 52 | 53 | def intersec(self, hp): 54 | new_points = [] 55 | new_lines = [] 56 | size = len(self.points) 57 | 58 | for i in range(size): 59 | j = (i + 1) % size 60 | p1_belongs = hp.has_point(Point(self.points[i][0], self.points[i][1])) 61 | p2_belongs = hp.has_point(Point(self.points[j][0], self.points[j][1])) 62 | line = Line(self.lines[i][0], self.lines[i][1], self.lines[i][2]) 63 | 64 | if p1_belongs: 65 | new_points.append(self.points[i]); 66 | new_lines.append([line.a, line.b, line.c]) 67 | 68 | if not p2_belongs: 69 | intersec_point = hp.get_intersection(line) 70 | new_points.append([intersec_point.x, intersec_point.y]) 71 | new_lines.append([hp.a, hp.b, hp.c]) 72 | 73 | elif p2_belongs: 74 | intersec_point = hp.get_intersection(line); 75 | new_points.append([intersec_point.x, intersec_point.y]) 76 | new_lines.append([line.a, line.b, line.c]) 77 | 78 | self.points = new_points 79 | self.lines = new_lines 80 | 81 | if __name__ == "__main__": 82 | 83 | poly = Poly() 84 | n = int(sys.stdin.readline().strip()) 85 | 86 | for _ in range(n): 87 | a, b, c = list(map(int, sys.stdin.readline().strip().split(' '))) 88 | hp = HalfPlane(a, b, c) 89 | poly.intersec(hp) 90 | print(poly.area()) 91 | -------------------------------------------------------------------------------- /11 - Суффиксный массив/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | string s; 7 | int n; 8 | const int END = 256; 9 | const int MAX_N = 500001; 10 | 11 | vector suff(MAX_N); 12 | vector lcp(MAX_N); 13 | 14 | int get_letter_ind(char c) { 15 | return c - '$'; 16 | } 17 | 18 | vector classes(MAX_N); 19 | vector classes_temp(MAX_N); 20 | vector suff_temp(MAX_N); 21 | 22 | void build_suff_array() { 23 | 24 | vector cnt(END, 0); 25 | 26 | for (int i = 0; i < n; ++i) { 27 | ++cnt[get_letter_ind(s[i])]; 28 | } 29 | 30 | for (int i = 0; i + 1 < END; ++i) { 31 | cnt[i + 1] += cnt[i]; 32 | } 33 | 34 | for (int i = 0; i < n; ++i) { 35 | suff[--cnt[get_letter_ind(s[i])]] = i; 36 | } 37 | 38 | int count = 1; 39 | classes[suff[0]] = 0; 40 | 41 | for (int i = 1; i < n; ++i) { 42 | 43 | if (s[suff[i]] != s[suff[i - 1]]) { 44 | ++count; 45 | } 46 | 47 | classes[suff[i]] = count - 1; 48 | } 49 | 50 | for (int l = 0; (1 << l) < n; ++l) { 51 | 52 | int x = 1 << l; 53 | 54 | for (int i = 0; i < n; ++i) { 55 | 56 | suff_temp[i] = suff[i] - x; 57 | 58 | if (suff_temp[i] < 0) { 59 | suff_temp[i] += n; 60 | } 61 | } 62 | 63 | vector cnt(count, 0); 64 | 65 | for (int i = 0; i < n; ++i) { 66 | ++cnt[classes[suff_temp[i]]]; 67 | } 68 | 69 | for (int i = 0; i + 1 < count; ++i) { 70 | cnt[i + 1] += cnt[i]; 71 | } 72 | 73 | for (int i = n - 1; i > -1; --i) { 74 | suff[--cnt[classes[suff_temp[i]]]] = suff_temp[i]; 75 | } 76 | 77 | count = 1; 78 | classes[suff[0]] = 0; 79 | 80 | for (int i = 1; i < n; ++i) { 81 | 82 | if (classes[suff[i]] != classes[suff[i - 1]] || classes[(suff[i] + x) % n] != classes[(suff[i - 1] + x) % n]) { 83 | ++count; 84 | } 85 | classes_temp[suff[i]] = count - 1; 86 | } 87 | classes = classes_temp; 88 | } 89 | } 90 | 91 | vector pos(MAX_N); 92 | 93 | void count_lcp() { 94 | 95 | for (int i = 0; i < n; ++i) { 96 | pos[suff[i]] = i; 97 | } 98 | 99 | int k = 0; 100 | 101 | for (int i = 0; i < n; ++i) { 102 | 103 | if (k > 0) { 104 | --k; 105 | } 106 | 107 | if (pos[i] == n - 1) { 108 | 109 | lcp[n - 1] = -1; 110 | k = 0; 111 | 112 | } else { 113 | 114 | int cur = suff[pos[i] + 1]; 115 | 116 | while (max(i + k, cur + k) < n && s[i + k] == s[cur + k]) { 117 | ++k; 118 | } 119 | lcp[pos[i]] = k; 120 | } 121 | } 122 | } 123 | 124 | int main() { 125 | 126 | cin >> s; 127 | s += '$'; 128 | n = s.length(); 129 | 130 | build_suff_array(); 131 | count_lcp(); 132 | 133 | long long out = 0; 134 | 135 | for (int i = 1; i < n - 1; ++i) { 136 | out += n - suff[i] - 1 - lcp[i]; 137 | } 138 | 139 | cout << out + n - 1 - suff[n - 1]; 140 | 141 | return 0; 142 | } 143 | -------------------------------------------------------------------------------- /11 - Суффиксный массив/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | string s; 7 | int n; 8 | const int END = 128; 9 | const int MAX_N = 400001; 10 | 11 | vector suff(MAX_N); 12 | vector lcp(MAX_N); 13 | 14 | int get_letter_ind(char c) { 15 | return c - '$'; 16 | } 17 | 18 | vector classes(MAX_N); 19 | vector classes_temp(MAX_N); 20 | vector suff_temp(MAX_N); 21 | 22 | void build_suff_array() { 23 | 24 | vector cnt(END, 0); 25 | 26 | for (int i = 0; i < n; ++i) { 27 | ++cnt[get_letter_ind(s[i])]; 28 | } 29 | 30 | for (int i = 0; i + 1 < END; ++i) { 31 | cnt[i + 1] += cnt[i]; 32 | } 33 | 34 | for (int i = 0; i < n; ++i) { 35 | suff[--cnt[get_letter_ind(s[i])]] = i; 36 | } 37 | 38 | int count = 1; 39 | classes[suff[0]] = 0; 40 | 41 | for (int i = 1; i < n; ++i) { 42 | 43 | if (s[suff[i]] != s[suff[i - 1]]) { 44 | ++count; 45 | } 46 | 47 | classes[suff[i]] = count - 1; 48 | } 49 | 50 | for (int l = 0; (1 << l) < n; ++l) { 51 | 52 | int x = 1 << l; 53 | 54 | for (int i = 0; i < n; ++i) { 55 | 56 | suff_temp[i] = suff[i] - x; 57 | 58 | if (suff_temp[i] < 0) { 59 | suff_temp[i] += n; 60 | } 61 | } 62 | 63 | vector cnt(count, 0); 64 | 65 | for (int i = 0; i < n; ++i) { 66 | ++cnt[classes[suff_temp[i]]]; 67 | } 68 | 69 | for (int i = 0; i + 1 < count; ++i) { 70 | cnt[i + 1] += cnt[i]; 71 | } 72 | 73 | for (int i = n - 1; i > -1; --i) { 74 | suff[--cnt[classes[suff_temp[i]]]] = suff_temp[i]; 75 | } 76 | 77 | count = 1; 78 | classes[suff[0]] = 0; 79 | 80 | for (int i = 1; i < n; ++i) { 81 | 82 | if (classes[suff[i]] != classes[suff[i - 1]] || classes[(suff[i] + x) % n] != classes[(suff[i - 1] + x) % n]) { 83 | ++count; 84 | } 85 | classes_temp[suff[i]] = count - 1; 86 | } 87 | classes = classes_temp; 88 | } 89 | } 90 | 91 | vector pos(MAX_N); 92 | 93 | void count_lcp() { 94 | 95 | for (int i = 0; i < n; ++i) { 96 | pos[suff[i]] = i; 97 | } 98 | 99 | int k = 0; 100 | 101 | for (int i = 0; i < n; ++i) { 102 | 103 | if (k > 0) { 104 | --k; 105 | } 106 | 107 | if (pos[i] == n - 1) { 108 | 109 | lcp[n - 1] = -1; 110 | k = 0; 111 | 112 | } else { 113 | 114 | int cur = suff[pos[i] + 1]; 115 | 116 | while (max(i + k, cur + k) < n && s[i + k] == s[cur + k]) { 117 | ++k; 118 | } 119 | lcp[pos[i]] = k; 120 | } 121 | } 122 | } 123 | 124 | int main() { 125 | 126 | cin >> s; 127 | s += '$'; 128 | n = s.length(); 129 | 130 | build_suff_array(); 131 | count_lcp(); 132 | 133 | for (int i = 1; i < n; ++i) { 134 | cout << suff[i] + 1 << " "; 135 | } 136 | 137 | cout << "\n"; 138 | 139 | for (int i = 1; i < n - 1; ++i) { 140 | cout << lcp[i] << " "; 141 | } 142 | 143 | return 0; 144 | } 145 | -------------------------------------------------------------------------------- /13 - Вычислительная геометрия/E.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import sys 3 | from random import shuffle 4 | 5 | class Point: 6 | def __init__(self, x, y): 7 | self.x = x 8 | self.y = y 9 | self.o = (x, y) 10 | def dot(self, p): 11 | return self.x * p.y - self.y * p.x 12 | def minus(self, p): 13 | x = self.x - p.x 14 | y = self.y - p.y 15 | return Point(x, y) 16 | def plus(self, p): 17 | x = self.x + p.x 18 | y = self.y + p.y 19 | return Point(x, y) 20 | def __str__(self): 21 | return str(format(self.x, '.10f')) + ' ' + str(format(self.y, '.10f')) 22 | 23 | class Line: 24 | def __init__(self, a, b, c): 25 | self.a = a 26 | self.b = b 27 | self.c = c 28 | def get_intersection(self, l): 29 | d = self.a * l.b - self.b * l.a 30 | x = (self.b * l.c - self.c * l.b) / d 31 | y = (self.c * l.a - self.a * l.c) / d 32 | return Point(x, y) 33 | 34 | class Circle: 35 | def __init__(self, p1 = None, p2 = None, p3 = None, x = 0, y = 0, r = 0): 36 | if (p1 != None) and (p2 != None) and (p3 == None): 37 | self.p1 = p1 38 | self.p2 = p2 39 | self.p = Point((p2.x - p1.x) / 2, (p2.y - p1.y) / 2).plus(p1) 40 | self.x = self.p.x 41 | self.y = self.p.y 42 | self.r_kv = self.p.minus(p1).x ** 2 + self.p.minus(p1).y ** 2 43 | self.r = self.r_kv ** 0.5 44 | elif (p1 != None) and (p2 != None) and (p3 != None): 45 | self.p1 = p1 46 | self.p2 = p2 47 | self.p3 = p3 48 | self.line1 = self.perp_bisect(p1, p2) 49 | self.line2 = self.perp_bisect(p1, p3) 50 | self.p = self.line1.get_intersection(self.line2) 51 | self.x = self.p.x 52 | self.y = self.p.y 53 | self.r_kv = self.p.minus(p1).x ** 2 + self.p.minus(p1).y ** 2 54 | self.r = self.r_kv ** 0.5 55 | else: 56 | self.p = Point(x, y) 57 | self.r = r 58 | self.x = x 59 | self.y = y 60 | self.r_kv = r ** 2 61 | 62 | def include(self, p): 63 | help_p = Point(p.x - self.x, p.y - self.y) 64 | return self.r_kv > help_p.x ** 2 + help_p.y ** 2 65 | 66 | def perp_bisect(self, p1, p2): 67 | a = p1.x - p2.x 68 | b = p1.y - p2.y 69 | tmp = p2.minus(p1) 70 | h = p1.plus(Point(tmp.x / 2, tmp.y / 2)) 71 | c = -a * h.x - b * h.y 72 | return Line(a, b, c) 73 | 74 | def circ_by_three_points(points, i_, j_): 75 | circ = Circle(points[i_], points[j_]) 76 | for i in range(i_): 77 | if not circ.include(points[i]): 78 | circ = Circle(points[i], points[i_], points[j_]) 79 | return circ 80 | 81 | def circ_by_two_points(points, j): 82 | d = points[0:j] 83 | shuffle(d) 84 | points[0:j] = d 85 | circ = Circle(points[0], points[j]) 86 | 87 | for i in range(1, j): 88 | if not circ.include(points[i]): 89 | circ = circ_by_three_points(points, i, j) 90 | return circ 91 | 92 | if __name__ == "__main__": 93 | 94 | n = int(sys.stdin.readline().strip()) 95 | points = [] 96 | 97 | for _ in range(n): 98 | x, y = list(map(int, sys.stdin.readline().strip().split(' '))) 99 | points.append(Point(x, y)) 100 | 101 | shuffle(points) 102 | circ = Circle(points[0], points[1]) 103 | 104 | for i in range(2, len(points)): 105 | if not circ.include(points[i]): 106 | circ = circ_by_two_points(points, i) 107 | 108 | print(str(format(circ.x, '.20f')) + ' ' + str(format(circ.y, '.20f'))) 109 | print(format(circ.r, '.20f')) 110 | -------------------------------------------------------------------------------- /8 - Максимальный поток и минимальный разрез/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int n; 8 | int m; 9 | int s; 10 | int t; 11 | 12 | 13 | struct Edge { 14 | 15 | int from = 0; 16 | int to = 0; 17 | int f = 0; 18 | int c = 0; 19 | Edge *rev = nullptr; 20 | int index = 0; 21 | 22 | Edge() = default; 23 | 24 | Edge(int from, int to, int c, int index) : from(from), to(to), f(0), c(c), index(index) {} 25 | }; 26 | 27 | vector Edges; 28 | 29 | vector> graph; 30 | 31 | vector used; 32 | 33 | int dfs(int cur, int c) { 34 | 35 | if (cur == t) { 36 | return c; 37 | } 38 | 39 | used[cur] = true; 40 | for (int i = 0; i < graph[cur].size(); ++i) { 41 | int next = graph[cur][i] -> to; 42 | Edge *e = graph[cur][i]; 43 | if (!used[next] && e -> f < e -> c) { 44 | int diff = dfs(next, min(e -> c - e -> f, c)); 45 | if (diff > 1e-5) { 46 | e -> f += diff; 47 | e -> rev -> f -= diff; 48 | return diff; 49 | } 50 | } 51 | } 52 | return 0; 53 | } 54 | 55 | int Dinic() { 56 | 57 | int ans = 0; 58 | int maxans = 0; 59 | 60 | do { 61 | 62 | ans = dfs(s, 1e9); 63 | fill(used.begin(), used.end(), false); 64 | maxans += ans; 65 | } while (ans > 1e-5); 66 | return maxans; 67 | } 68 | 69 | void draw(int cur) { 70 | 71 | used[cur] = true; 72 | 73 | for (int i = 0; i < graph[cur].size(); ++i) { 74 | 75 | Edge *e = graph[cur][i]; 76 | int next = e->to; 77 | 78 | if (!used[next] && e -> c - e -> f > 1e-5) { 79 | draw(next); 80 | } 81 | } 82 | } 83 | 84 | 85 | vector incut; 86 | 87 | void find_edges() { 88 | 89 | for (int i = 0; i < 2 * m; i += 2) { 90 | 91 | if (used[Edges[i].from] ^ used[Edges[i].to]) { 92 | incut.emplace_back(&Edges[i]); 93 | } 94 | } 95 | } 96 | 97 | vector pred; 98 | 99 | void find_pred(int cur) { 100 | 101 | pred.emplace_back(cur); 102 | 103 | if (cur == t) { 104 | return; 105 | } 106 | 107 | for (auto it : graph[cur]) { 108 | int next = it -> to; 109 | 110 | if (it -> f == 1) { 111 | 112 | it -> f = 0; 113 | find_pred(next); 114 | return; 115 | } 116 | } 117 | } 118 | 119 | int main() { 120 | 121 | cin >> n; 122 | cin >> m; 123 | cin >> s; 124 | cin >> t; 125 | 126 | s--; 127 | t--; 128 | 129 | graph.resize(n, vector()); 130 | 131 | Edges.resize(2 * m); 132 | 133 | for (int i = 0; i < 2 * m; i += 2) { 134 | 135 | int from; 136 | int to; 137 | int c; 138 | 139 | cin >> from >> to; 140 | 141 | from--; 142 | to--; 143 | Edges[i] = Edge(from, to, 1, i); 144 | Edges[i + 1] = Edge(to, from, 0, i + 1); 145 | Edges[i].rev = &Edges[i + 1]; 146 | Edges[i + 1].rev = &Edges[i]; 147 | graph[from].emplace_back(&Edges[i]); 148 | graph[to].emplace_back(&Edges[i + 1]); 149 | } 150 | 151 | used.resize(n, false); 152 | cout.precision(10); 153 | int F = Dinic(); 154 | 155 | if (F < 2) { 156 | cout << "NO"; 157 | return 0; 158 | } 159 | 160 | cout << "YES\n"; 161 | find_pred(s); 162 | 163 | for (auto it : pred) { 164 | cout << it + 1 << ' '; 165 | } 166 | 167 | pred.clear(); 168 | find_pred(s); 169 | cout << endl; 170 | 171 | for (auto it : pred) { 172 | cout << it + 1 << ' '; 173 | } 174 | 175 | return 0; 176 | } 177 | -------------------------------------------------------------------------------- /11 - Суффиксный массив/D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | string s, t; 7 | int n, f; 8 | const int END = 256; 9 | const int MAX_N = 500001; 10 | 11 | vector suff(MAX_N); 12 | vector lcp(MAX_N); 13 | 14 | int get_letter_ind(char c) { 15 | return c - '#'; 16 | } 17 | 18 | vector classes(MAX_N); 19 | vector classes_temp(MAX_N); 20 | vector suff_temp(MAX_N); 21 | vector sharps(MAX_N); 22 | vector bacs(MAX_N); 23 | 24 | void build_suff_array() { 25 | 26 | vector cnt(END, 0); 27 | 28 | for (int i = 0; i < n; ++i) { 29 | ++cnt[get_letter_ind(s[i])]; 30 | } 31 | 32 | for (int i = 0; i + 1 < END; ++i) { 33 | cnt[i + 1] += cnt[i]; 34 | } 35 | 36 | for (int i = 0; i < n; ++i) { 37 | suff[--cnt[get_letter_ind(s[i])]] = i; 38 | } 39 | 40 | int count = 1; 41 | classes[suff[0]] = 0; 42 | 43 | for (int i = 1; i < n; ++i) { 44 | 45 | if (s[suff[i]] != s[suff[i - 1]]) { 46 | ++count; 47 | } 48 | 49 | classes[suff[i]] = count - 1; 50 | } 51 | 52 | for (int l = 0; (1 << l) < n; ++l) { 53 | 54 | int x = 1 << l; 55 | 56 | for (int i = 0; i < n; ++i) { 57 | 58 | suff_temp[i] = suff[i] - x; 59 | 60 | if (suff_temp[i] < 0) { 61 | suff_temp[i] += n; 62 | } 63 | } 64 | 65 | vector cnt(count, 0); 66 | 67 | for (int i = 0; i < n; ++i) { 68 | ++cnt[classes[suff_temp[i]]]; 69 | } 70 | 71 | for (int i = 0; i + 1 < count; ++i) { 72 | cnt[i + 1] += cnt[i]; 73 | } 74 | 75 | for (int i = n - 1; i > -1; --i) { 76 | suff[--cnt[classes[suff_temp[i]]]] = suff_temp[i]; 77 | } 78 | 79 | count = 1; 80 | classes[suff[0]] = 0; 81 | 82 | for (int i = 1; i < n; ++i) { 83 | 84 | if (classes[suff[i]] != classes[suff[i - 1]] || classes[(suff[i] + x) % n] != classes[(suff[i - 1] + x) % n]) { 85 | ++count; 86 | } 87 | classes_temp[suff[i]] = count - 1; 88 | } 89 | classes = classes_temp; 90 | } 91 | } 92 | 93 | vector pos(MAX_N); 94 | 95 | void count_lcp() { 96 | 97 | for (int i = 0; i < n; ++i) { 98 | pos[suff[i]] = i; 99 | } 100 | 101 | int k = 0; 102 | 103 | for (int i = 0; i < n; ++i) { 104 | 105 | if (k > 0) { 106 | --k; 107 | } 108 | 109 | if (pos[i] == n - 1) { 110 | 111 | lcp[n - 1] = -1; 112 | k = 0; 113 | 114 | } else { 115 | 116 | int cur = suff[pos[i] + 1]; 117 | 118 | while (max(i + k, cur + k) < n && s[i + k] == s[cur + k]) { 119 | ++k; 120 | } 121 | lcp[pos[i]] = k; 122 | } 123 | } 124 | } 125 | 126 | bool is_suff_of_first(int i) { 127 | 128 | int pos_bacs = bacs[i]; 129 | int pos_sharp = sharps[i]; 130 | return pos_sharp < pos_bacs; 131 | } 132 | 133 | bool is_diff(int i, int j) { 134 | 135 | return is_suff_of_first(i) != is_suff_of_first(j); 136 | } 137 | 138 | int main() { 139 | 140 | cin >> s; 141 | cin >> t; 142 | f = s.length(); 143 | s += '$' + t + '#'; 144 | n = s.length(); 145 | 146 | build_suff_array(); 147 | count_lcp(); 148 | 149 | for (int i = 0; i < n; ++i) { 150 | 151 | sharps[i] = (n - suff[i] + f) % n; 152 | bacs[i] = (n - suff[i] - 1) % n; 153 | } 154 | 155 | int out = 0; 156 | int out_suf = -1; 157 | 158 | for (int i = 1; i < n; ++i) { 159 | 160 | if (is_diff(i - 1, i) && lcp[i - 1] > out) { 161 | 162 | out = lcp[i - 1]; 163 | out_suf = i; 164 | } 165 | } 166 | 167 | if (out != 0) { 168 | 169 | for(int i = 0; i < out; ++i) { 170 | cout << s[i + suff[out_suf]]; 171 | } 172 | } 173 | 174 | return 0; 175 | } 176 | -------------------------------------------------------------------------------- /9 - Потоки со стоимостью/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | typedef long long ll; 8 | 9 | #define INF (ll)1e18 10 | 11 | struct Edge { 12 | 13 | ll from = 0; 14 | ll to = 0; 15 | ll capacity = 0; 16 | ll cost = 0; 17 | ll flow = 0; 18 | Edge *reverse = nullptr; 19 | 20 | Edge() {} 21 | 22 | Edge(ll from, ll to, ll capacity, ll cost) : from(from), to(to), capacity(capacity), cost(cost) {} 23 | }; 24 | 25 | struct Node { 26 | 27 | ll ind = 0; 28 | vector list; 29 | 30 | Node() {} 31 | 32 | Node(ll ind) : ind(ind) {} 33 | 34 | void add_edge(Edge *e) { 35 | list.push_back(e); 36 | } 37 | }; 38 | 39 | struct Graph { 40 | 41 | ll n = 0; 42 | ll m = 0; 43 | ll start = 0; 44 | ll finish = 0; 45 | vector Nodes; 46 | vector Edges; 47 | vector previous; 48 | 49 | Graph() {} 50 | 51 | Graph(ll n, ll m, ll start, ll finish) : n(n), m(m), start(start), finish(finish) {} 52 | 53 | void resize() { 54 | 55 | Nodes.resize(n); 56 | previous.resize(n); 57 | } 58 | 59 | void read() { 60 | 61 | cin >> n; 62 | cin >> m; 63 | start = 0; 64 | finish = n - 1; 65 | resize(); 66 | 67 | for (ll i = 0; i < m; ++i) { 68 | 69 | ll from, to, capacity, cost; 70 | 71 | cin >> from >> to >> capacity >> cost; 72 | 73 | --from; 74 | --to; 75 | Edges.emplace_back(from, to, capacity, cost); 76 | Edges.emplace_back(to, from, 0, -cost); 77 | } 78 | 79 | for (ll i = 0; i < m; ++i) { 80 | 81 | ll ind = 2 * i; 82 | Edges[ind].reverse = &Edges[ind + 1]; 83 | Edges[ind + 1].reverse = &Edges[ind]; 84 | } 85 | 86 | for (ll i = 0; i < m; ++i) { 87 | 88 | ll ind = 2 * i; 89 | ll from = Edges[ind].from; 90 | ll to = Edges[ind].to; 91 | Nodes[from].add_edge(&Edges[ind]); 92 | Nodes[to].add_edge(&Edges[ind + 1]); 93 | } 94 | } 95 | 96 | ll Dijkstra() { 97 | 98 | vector dist(n, INF); 99 | dist[start] = 0; 100 | set> vertexes; 101 | vertexes.insert({dist[start], start}); 102 | 103 | while (!vertexes.empty()) { 104 | 105 | auto top = vertexes.begin(); 106 | ll cur = top -> second; 107 | ll cost = top -> first; 108 | vertexes.erase(top); 109 | 110 | for(ll i = 0; i < Nodes[cur].list.size(); ++i) { 111 | 112 | Edge *e = Nodes[cur].list[i]; 113 | 114 | if (dist[cur] != INF && e -> flow < e -> capacity && dist[cur] + e -> cost < dist[e -> to]) { 115 | 116 | dist[e -> to] = dist[cur] + e -> cost; 117 | previous[e -> to] = e; 118 | vertexes.insert({dist[e -> to], e -> to}); 119 | } 120 | } 121 | } 122 | 123 | return dist[finish]; 124 | } 125 | 126 | ll find_flow() { 127 | 128 | ll cur = finish; 129 | ll cur_flow = INF; 130 | 131 | while (cur != start) { 132 | 133 | cur_flow = min(cur_flow, previous[cur] -> capacity - previous[cur] -> flow); 134 | cur = previous[cur] -> from; 135 | } 136 | 137 | return cur_flow; 138 | } 139 | 140 | void update_flow(ll &flow) { 141 | 142 | if (flow != 0) { 143 | 144 | ll cur = finish; 145 | 146 | while (cur != start) { 147 | 148 | previous[cur] -> flow += flow; 149 | previous[cur] -> reverse -> flow -= flow; 150 | cur = previous[cur] -> from; 151 | } 152 | } 153 | } 154 | 155 | ll mincost() { 156 | 157 | read(); 158 | ll distance = Dijkstra(); 159 | ll min_cost = 0; 160 | 161 | while (distance != INF) { 162 | 163 | ll flow = find_flow(); 164 | min_cost += flow * distance; 165 | update_flow(flow); 166 | distance = Dijkstra(); 167 | } 168 | 169 | return min_cost; 170 | } 171 | 172 | void accepted() { 173 | cout << mincost(); 174 | } 175 | }; 176 | 177 | int main() { 178 | 179 | Graph graph; 180 | graph.accepted(); 181 | 182 | return 0; 183 | } 184 | -------------------------------------------------------------------------------- /5 - Запросы на отрезках/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | struct Node{ 6 | int oper = 0; 7 | long long set_value; 8 | long long ans; 9 | long long add_value; 10 | }; 11 | 12 | vector tree; 13 | const long long inf = pow(10, 18); 14 | 15 | void build(vector a) { 16 | 17 | for (int i = 0; i < a.size(); i++) { 18 | tree[tree.size() / 2 + i].ans = a[i].ans; 19 | } 20 | for (int i = a.size() - 2; i >= 0; i--) { 21 | tree[i].ans = min(tree[2 * i + 1].ans, tree[2 * i + 2].ans); 22 | } 23 | } 24 | 25 | void push(int v) { 26 | 27 | if (tree[v].oper == 1 && (2 * v + 1) < tree.size()) { 28 | tree[2 * v + 1].set_value = tree[v].set_value; 29 | tree[2 * v + 1].ans = tree[v].set_value; 30 | tree[2 * v + 1].oper = 1; 31 | tree[2 * v + 2].set_value = tree[v].set_value; 32 | tree[2 * v + 2].ans = tree[v].set_value; 33 | tree[2 * v + 2].oper = 1; 34 | tree[v].oper = 0; 35 | } else if (tree[v].oper == 2 && (2 * v + 1) < tree.size()) { 36 | tree[2 * v + 1].ans += tree[v].add_value; 37 | tree[2 * v + 2].ans += tree[v].add_value; 38 | push(2 * v + 1); 39 | tree[2 * v + 1].add_value = tree[v].add_value; 40 | push(2 * v + 2); 41 | tree[2 * v + 2].add_value = tree[v].add_value; 42 | tree[2 * v + 1].oper = 2; 43 | tree[2 * v + 2].oper = 2; 44 | tree[v].oper = 0; 45 | } 46 | 47 | } 48 | 49 | void update_min(int v) { 50 | 51 | if (v == 0){ 52 | return; 53 | } 54 | if (v == (v - 1) / 2 * 2 + 1) { 55 | tree[(v - 1) / 2].ans = min(tree[v].ans, tree[((v - 1) / 2) * 2 + 2].ans); 56 | } else { 57 | tree[(v - 1) / 2].ans = min(tree[v].ans, tree[((v - 1) / 2) * 2 + 1].ans); 58 | } 59 | update_min((v - 1) / 2); 60 | } 61 | 62 | void update_add(int v, int left, int right, int a, int b, long long add_val) { 63 | 64 | if (a > b) 65 | return; 66 | if (a == left && right == b) { 67 | if (tree[v].oper == 2) { 68 | tree[v].ans += add_val; 69 | update_min(v); 70 | tree[v].add_value += add_val; 71 | } else if (tree[v].oper == 1) { 72 | push(v); 73 | tree[v].ans += add_val; 74 | update_min(v); 75 | tree[v].oper = 2; 76 | tree[v].add_value = add_val; 77 | } else { 78 | tree[v].ans += add_val; 79 | update_min(v); 80 | tree[v].oper = 2; 81 | tree[v].add_value = add_val; 82 | } 83 | 84 | } else { 85 | push(v); 86 | int tm = (left + right) / 2; 87 | update_add (2 * v + 1, left, tm, a, min(b, tm), add_val); 88 | update_add (2 * v + 2, tm + 1, right, max(a, tm + 1), b, add_val); 89 | } 90 | 91 | } 92 | 93 | void update_set(int v, int left, int right, int a, int b, long long set_val) { 94 | 95 | if (a > b) 96 | return; 97 | if (a == left && right == b) { 98 | tree[v].ans = set_val; 99 | tree[v].set_value = set_val; 100 | tree[v].oper = 1; 101 | update_min(v); 102 | } 103 | else { 104 | push (v); 105 | int tm = (left + right) / 2; 106 | update_set (2 * v + 1, left, tm, a, min(b,tm), set_val); 107 | update_set (2 * v + 2, tm + 1, right, max(a, tm + 1), b, set_val); 108 | } 109 | } 110 | 111 | long long get_min(int v, int left, int right, int a, int b) { 112 | 113 | if (a > b) return inf; 114 | if (a == left && b == right) { 115 | if (tree[v].oper == 2 && (2 * v + 1 < tree.size())) 116 | return tree[v].ans; 117 | else return tree[v].ans; 118 | } 119 | push(v); 120 | int m = (left + right) / 2; 121 | 122 | return min(get_min(2 * v + 1, left, m , a, min(b, m)), 123 | get_min(2 * v + 2, m + 1, right, max(a, m + 1), b)); 124 | 125 | } 126 | 127 | 128 | int main() 129 | { 130 | int n; 131 | cin >> n; 132 | long long p = 1; 133 | 134 | while (p < n) p *= 2; 135 | 136 | p *= 2; 137 | vector a; 138 | a.resize(p / 2); 139 | 140 | for (int i = 0; i < n; i++) { 141 | cin >> a[i].ans; 142 | } 143 | 144 | for (int i = n; i < a.size(); i++) { 145 | a[i].ans = inf; 146 | } 147 | 148 | tree.resize(p - 1); 149 | 150 | if (n == 1) { 151 | tree = a; 152 | } else { 153 | build(a); 154 | } 155 | 156 | string oper; 157 | while (cin >> oper) { 158 | 159 | if (oper == "min") { 160 | int i, j; 161 | cin >> i >> j; 162 | cout << get_min(0, 0 , a.size() - 1, --i, --j) << endl; 163 | 164 | } else if (oper == "set") { 165 | int i, j, x; 166 | cin >> i >> j >> x; 167 | update_set(0, 0, a.size() - 1, --i, --j, x); 168 | 169 | } else if (oper == "add") { 170 | int i, j, x; 171 | cin >> i >> j >> x; 172 | update_add(0, 0 , a.size() - 1, --i, --j, x); 173 | 174 | } 175 | } 176 | 177 | return 0; 178 | } 179 | -------------------------------------------------------------------------------- /12 - Суффиксное дерево/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | class SufTree { 8 | 9 | private: 10 | 11 | static const int ALPH_SIZE = 26; 12 | 13 | private: 14 | 15 | struct SufNode; 16 | 17 | struct SufEdge { 18 | 19 | SufNode *from; 20 | SufNode *to; 21 | int left; 22 | int right; 23 | 24 | SufEdge(SufNode *start, SufNode *end) 25 | : from(start), to(end), left(0), right(0) {} 26 | 27 | SufEdge(SufNode *start, SufNode *end, pair bounds) 28 | : from(start), to(end), left(bounds.first), right(bounds.second) {} 29 | 30 | void set_left(int l) { 31 | left = l; 32 | } 33 | 34 | void set_right(int r) { 35 | right = r; 36 | } 37 | 38 | void set_bounds(pair bounds) { 39 | 40 | left = bounds.first; 41 | right = bounds.second; 42 | } 43 | 44 | pair get_bounds() { 45 | return {left, right}; 46 | } 47 | 48 | int get_len() { 49 | return right - left; 50 | } 51 | }; 52 | 53 | private: 54 | 55 | struct SufNode { 56 | 57 | int id; 58 | SufNode *link; 59 | 60 | array kids{{nullptr}}; 61 | explicit SufNode(int id) : id(id), link(nullptr) {} 62 | 63 | void set_link(SufNode *node) { 64 | link = node; 65 | } 66 | 67 | SufNode *get_link() { 68 | return link; 69 | } 70 | 71 | void set_kid(int ind, SufEdge *res) { 72 | kids[ind] = res; 73 | } 74 | 75 | SufEdge *get_kid(int ind) { 76 | return kids[ind]; 77 | } 78 | }; 79 | 80 | int node_cnt = 0; 81 | int depth = 0; 82 | SufNode * const root; 83 | SufNode *pre; 84 | SufNode *cur; 85 | 86 | private: 87 | 88 | void dfs(SufNode *node, ostream &out) { 89 | 90 | if (!node) return; 91 | 92 | for (SufEdge *edge : node->kids) { 93 | 94 | if (!edge) continue; 95 | 96 | out << node -> id << ' ' 97 | << edge -> to -> id << ' ' 98 | < left + 1 << ' ' 99 | << edge -> right << '\n'; 100 | 101 | dfs(edge -> to, out); 102 | } 103 | } 104 | 105 | int get_char(char c) { 106 | return c - 'a'; 107 | } 108 | 109 | SufNode *gen_node() { 110 | return new SufNode(++node_cnt); 111 | } 112 | 113 | public: 114 | 115 | explicit SufTree(string const &s) : root(gen_node()), cur(root) { 116 | 117 | for (int i = 0; i < s.size(); i++) { 118 | 119 | pre = nullptr; 120 | depth++; 121 | 122 | while (depth > 0) { 123 | 124 | while (true) { 125 | 126 | SufEdge *edge = cur -> get_kid(get_char(s[i - depth + 1])); 127 | if (!edge) break; 128 | int len = edge -> get_len(); 129 | if (depth <= len) break; 130 | depth -= len; 131 | cur = edge -> to; 132 | } 133 | 134 | SufEdge *edge = cur->get_kid(get_char(s[i - depth + 1])); 135 | 136 | if (edge) { 137 | int next_char = edge->left + depth - 1; 138 | 139 | if (s[next_char] == s[i]) { 140 | 141 | if (pre) pre->set_link(cur); 142 | break; 143 | } 144 | 145 | else { 146 | auto *new_node = gen_node(); 147 | auto *new_node2 = gen_node(); 148 | auto *new_edge = new SufEdge(new_node, edge -> to); 149 | new_edge -> set_bounds({next_char, edge -> right}); 150 | auto *new_edge2 = new SufEdge(new_node, new_node2, {i, s.size()}); 151 | new_node -> set_kid(get_char(s[next_char]), new_edge); 152 | new_node -> set_kid(get_char(s[i]), new_edge2); 153 | edge -> right = next_char; 154 | edge -> to = new_node; 155 | if (pre) pre -> set_link(new_node); 156 | pre = new_node; 157 | } 158 | 159 | } 160 | 161 | else { 162 | auto *new_node = gen_node(); 163 | auto *new_edge = new SufEdge(cur, new_node, {i, s.size()}); 164 | cur -> set_kid(get_char(s[i]), new_edge); 165 | if (pre) pre -> set_link(cur); 166 | pre = nullptr; 167 | } 168 | 169 | if (cur == root) depth--; 170 | else cur = cur -> get_link(); 171 | } 172 | } 173 | } 174 | 175 | void dfs(ostream &out) { 176 | 177 | out << node_cnt << ' ' << node_cnt - 1 << '\n'; 178 | dfs(root, out); 179 | } 180 | }; 181 | 182 | int main() { 183 | 184 | string s; 185 | cin >> s; 186 | SufTree suf_tree(s); 187 | suf_tree.dfs(cout); 188 | 189 | return 0; 190 | } 191 | -------------------------------------------------------------------------------- /6 - Запросы на отрезках. Продолжение/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define DEPTH 10 6 | 7 | #define X_DEPTH DEPTH 8 | #define Y_DEPTH DEPTH 9 | 10 | #define MAX(x, y) ((x) > (y) ? (x) : (y)) 11 | 12 | #define X_SIZE (1 << (X_DEPTH + 1)) 13 | #define Y_SIZE (1 << (Y_DEPTH + 1)) 14 | 15 | typedef long long ll; 16 | 17 | int logs[MAX(X_SIZE, Y_SIZE)]; 18 | 19 | void init_logs() { 20 | 21 | int d = 0; 22 | int i = 0; 23 | while(d <= MAX(X_DEPTH, Y_DEPTH)) { 24 | 25 | if (i == (1 << (d + 1))) d++; 26 | logs[i] = d; 27 | i++; 28 | } 29 | } 30 | 31 | int count(int n, int depth) { 32 | return 1 << (depth - logs[n]); 33 | } 34 | 35 | int first_index(int n, int count) { 36 | return (n - (1 << logs[n])) * count; 37 | } 38 | 39 | void fill_node_set(int l, int r, int depth, int* arr, int & arr_count, int node = 1, int nl = 0, int nr = 0) { 40 | 41 | arr[arr_count++] = node; 42 | 43 | if (node == 1) nr = (1 << depth) - 1; 44 | if (nl == l && nr == r) return; 45 | 46 | int ll = nl; 47 | int lr = (nl + nr) >> 1; 48 | int rl = lr + 1; 49 | int rr = nr; 50 | 51 | if (rl <= l) fill_node_set(l, r, depth, arr, arr_count, (node << 1) + 1, rl, rr); 52 | 53 | else if (lr >= r) fill_node_set(l, r, depth, arr, arr_count, node<<1, ll, lr); 54 | 55 | else{ 56 | 57 | fill_node_set(l, lr, depth, arr, arr_count, node << 1, ll, lr); 58 | fill_node_set(rl, r, depth, arr, arr_count, (node << 1) + 1, rl, rr); 59 | } 60 | } 61 | 62 | int x_set[100], y_set[100], x_count = 0, y_count = 0; 63 | 64 | int n_intersect(int nl, int nr, int l, int r) { 65 | 66 | if (nl <= l && r <= nr) return r - l + 1; 67 | if (l <= nl && nr <=r) return nr - nl + 1; 68 | if (nr < l || r < nl) return 0; 69 | if(l <= nl) return r - nl + 1; 70 | return nr - l + 1; 71 | } 72 | 73 | struct _tree{ 74 | 75 | ll add_x[X_SIZE][Y_SIZE], add_y[X_SIZE][Y_SIZE], value[X_SIZE][Y_SIZE], add[X_SIZE][Y_SIZE]; 76 | 77 | void mod(int x1, int x2, int y1, int y2, int val) { 78 | 79 | x_count = 0, y_count = 0; 80 | fill_node_set(x1, x2, X_DEPTH, x_set, x_count); 81 | fill_node_set(y1, y2, Y_DEPTH, y_set, y_count); 82 | 83 | for (int xi=0; xi < x_count; xi++) { 84 | 85 | int _xc = count(x_set[xi], X_DEPTH); 86 | int xl = first_index(x_set[xi], _xc); 87 | int xr = xl + _xc - 1; 88 | int xc = n_intersect(xl, xr, x1, x2); 89 | 90 | for (int yi = 0; yi < y_count; yi++) { 91 | 92 | int _yc = count(y_set[yi], Y_DEPTH); 93 | int yl = first_index(y_set[yi], _yc); 94 | int yr = yl + _yc - 1; 95 | int yc = n_intersect(yl, yr, y1, y2); 96 | 97 | bool b1 = y1 <= yl && yr <= y2; 98 | bool b2 = x1 <= xl && xr <= x2; 99 | 100 | if (b1 && b2) add[x_set[xi]][y_set[yi]] += val; 101 | 102 | else { 103 | 104 | if (b1) add_x[x_set[xi]][y_set[yi]] += val * xc; 105 | if (b2) add_y[x_set[xi]][y_set[yi]] += val * yc; 106 | } 107 | 108 | if (!b1 && !b2) { 109 | value[x_set[xi]][y_set[yi]] += ((ll)xc) * yc * val; 110 | } 111 | } 112 | } 113 | } 114 | 115 | 116 | ll summ(int x1, int x2, int y1, int y2) { 117 | 118 | x_count = 0, y_count = 0; 119 | ll res = 0; 120 | fill_node_set(x1, x2, X_DEPTH, x_set, x_count); 121 | fill_node_set(y1, y2, Y_DEPTH, y_set, y_count); 122 | 123 | for (int xi = 0; xi < x_count; xi++) { 124 | 125 | int _xc = count(x_set[xi], X_DEPTH); 126 | int xl = first_index(x_set[xi], _xc); 127 | int xr = xl + _xc - 1; 128 | int xc = n_intersect(xl, xr, x1, x2); 129 | 130 | for (int yi = 0; yi < y_count; yi++) { 131 | 132 | int _yc = count(y_set[yi], Y_DEPTH); 133 | int yl = first_index(y_set[yi], _yc); 134 | int yr = yl + _yc - 1; 135 | int yc = n_intersect(yl, yr, y1, y2); 136 | 137 | int xvl = max(xl, x1), xvr = min(xr, x2), yvl = max(yl, y1), yvr = min(yr, y2); 138 | res += yc * xc * add[x_set[xi]][y_set[yi]]; 139 | 140 | if (xl == xvl && xvr == xr) res += yc * add_x[x_set[xi]][y_set[yi]]; 141 | if (yl == yvl && yvr == yr) res += xc * add_y[x_set[xi]][y_set[yi]]; 142 | if (x1 <= xl && xr <= x2 && y1 <= yl && yr <= y2) res += value[x_set[xi]][y_set[yi]]; 143 | } 144 | } 145 | return res; 146 | } 147 | 148 | } tree; 149 | 150 | 151 | int main(int argc, char** argv) { 152 | 153 | init_logs(); 154 | int __x, __y, N, x1, y1, x2, y2, op, w; 155 | 156 | cin >> __x >> __y >> N; 157 | 158 | for(int i = 0; i < N; i++) { 159 | 160 | cin >> op >> x1 >> y1 >> x2 >> y2; 161 | 162 | x1--, y1--, x2--, y2--; 163 | 164 | if (op == 1) { 165 | 166 | cin >> w; 167 | tree.mod(x1,x2,y1,y2,w); 168 | } 169 | else { 170 | cout << tree.summ(x1,x2,y1,y2) << endl; 171 | } 172 | } 173 | 174 | return 0; 175 | } 176 | -------------------------------------------------------------------------------- /9 - Потоки со стоимостью/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | typedef long long ll; 7 | 8 | #define INF (ll)1e18 9 | 10 | struct Edge { 11 | 12 | ll from = 0; 13 | ll to = 0; 14 | ll capacity = 0; 15 | ll cost = 0; 16 | ll flow = 0; 17 | Edge *reverse = nullptr; 18 | 19 | Edge() {} 20 | 21 | Edge(ll from, ll to, ll capacity, ll cost) : from(from), to(to), capacity(capacity), cost(cost) {} 22 | }; 23 | 24 | 25 | struct Node { 26 | 27 | ll ind = 0; 28 | vector list; 29 | 30 | Node() {} 31 | 32 | Node(ll ind) : ind(ind) {} 33 | 34 | void add_edge(Edge *e) { 35 | list.push_back(e); 36 | } 37 | }; 38 | 39 | struct Graph { 40 | 41 | ll n = 0; 42 | ll m = 0; 43 | ll start = 0; 44 | ll finish = 0; 45 | vector Nodes; 46 | vector Edges; 47 | vector potential; 48 | vector> w; 49 | vector previous; 50 | 51 | Graph() {} 52 | 53 | Graph(ll n, ll m, ll start, ll finish) : n(n), m(m), start(start), finish(finish) {} 54 | 55 | void resize() { 56 | 57 | Nodes.resize(2 * n + 2); 58 | previous.resize(2 * n + 2); 59 | w.resize(n, vector(n, 0)); 60 | potential.resize(2 * n + 2, INF); 61 | } 62 | 63 | void read() { 64 | 65 | cin >> n; 66 | 67 | start = 0; 68 | finish = 2 * n + 1; 69 | resize(); 70 | 71 | for (ll i = 0; i < n; ++i) { 72 | 73 | for (ll j = 0; j < n; ++j) { 74 | 75 | cin >> w[i][j]; 76 | } 77 | } 78 | 79 | for(ll i = start + 1; i < 1 + n; ++i) { 80 | 81 | Edges.emplace_back(start, i, 1, 0); 82 | Edges.emplace_back(i, start, 0, 0); 83 | } 84 | 85 | for(ll i = start + 1; i < 1 + n; ++i) { 86 | 87 | for(ll j = 1 + n; j < finish; ++j) { 88 | 89 | ll from = i; 90 | ll to = j; 91 | ll ind_from = i - 1; 92 | ll ind_to = j - 1 - n; 93 | Edges.emplace_back(from, to, 1, w[ind_from][ind_to]); 94 | Edges.emplace_back(to, from, 0, -w[ind_from][ind_to]); 95 | } 96 | } 97 | 98 | for(ll i = 1 + n; i < finish; ++i) { 99 | 100 | Edges.emplace_back(i, finish, 1, 0); 101 | Edges.emplace_back(finish, i, 0, 0); 102 | } 103 | 104 | m = Edges.size() / 2; 105 | 106 | for (ll i = 0; i < m; ++i) { 107 | 108 | ll ind = 2 * i; 109 | Edges[ind].reverse = &Edges[ind + 1]; 110 | Edges[ind + 1].reverse = &Edges[ind]; 111 | } 112 | 113 | for (ll i = 0; i < m; ++i) { 114 | 115 | ll ind = 2 * i; 116 | ll from = Edges[ind].from; 117 | ll to = Edges[ind].to; 118 | Nodes[from].add_edge(&Edges[ind]); 119 | Nodes[to].add_edge(&Edges[ind + 1]); 120 | } 121 | } 122 | 123 | void BellmanFord() { 124 | 125 | for (ll i = 0; i < 2 * n + 2; ++i) { 126 | 127 | for (ll j = 0; j < 2 * n + 2; ++j) { 128 | 129 | if (potential[j] < INF) { 130 | 131 | for (ll k = 0; k < Nodes[j].list.size(); ++k) { 132 | 133 | Edge *e = Nodes[j].list[k]; 134 | 135 | if (e -> capacity > 0 && potential[e -> to] > potential[j] + e -> cost) { 136 | potential[e -> to] = potential[j] + e -> cost; 137 | } 138 | } 139 | } 140 | } 141 | } 142 | } 143 | 144 | void init_potential() { 145 | 146 | potential[start] = 0; 147 | BellmanFord(); 148 | } 149 | 150 | ll Dijkstra() { 151 | 152 | vector dist(2 * n + 2, INF); 153 | vector used(2 * n + 2, 0); 154 | dist[start] = 0; 155 | 156 | while (true) { 157 | 158 | ll cur = -1; 159 | 160 | for (ll i = 0; i < 2 * n + 2; ++i) { 161 | 162 | if (!used[i] && dist[i] < INF && (cur == -1 || dist[i] < dist[cur])) { 163 | cur = i; 164 | } 165 | } 166 | 167 | if (cur == -1) { 168 | break; 169 | } 170 | 171 | used[cur] = 1; 172 | 173 | for(ll i = 0; i < Nodes[cur].list.size(); ++i) { 174 | 175 | Edge *e = Nodes[cur].list[i]; 176 | 177 | if (e -> flow < e -> capacity && !used[e -> to] && dist[cur] + e -> cost + potential[cur] - potential[e -> to] < dist[e -> to]) { 178 | 179 | dist[e -> to] = dist[cur] + e -> cost + potential[cur] - potential[e -> to]; 180 | previous[e -> to] = e; 181 | } 182 | } 183 | } 184 | 185 | for (ll i = 0; i < 2 * n + 2; ++i) { 186 | potential[i] += dist[i]; 187 | } 188 | 189 | return dist[finish]; 190 | } 191 | 192 | pair find_flow() { 193 | 194 | ll cur = finish; 195 | ll cur_flow = INF; 196 | ll cur_cost = 0; 197 | 198 | while (cur != start) { 199 | 200 | cur_flow = min(cur_flow, previous[cur] -> capacity - previous[cur] -> flow); 201 | cur_cost += previous[cur] -> cost; 202 | cur = previous[cur] -> from; 203 | } 204 | 205 | return {cur_flow, cur_cost}; 206 | } 207 | 208 | void update_flow(ll &flow) { 209 | 210 | if (flow != 0) { 211 | ll cur = finish; 212 | 213 | while (cur != start) { 214 | 215 | previous[cur] -> flow += flow; 216 | previous[cur] -> reverse -> flow -= flow; 217 | cur = previous[cur] -> from; 218 | } 219 | } 220 | } 221 | 222 | ll mincost() { 223 | 224 | read(); 225 | init_potential(); 226 | ll distance = Dijkstra(); 227 | ll min_cost = 0; 228 | 229 | while (distance != INF) { 230 | 231 | auto tmp = find_flow(); 232 | ll flow = tmp.first; 233 | ll cost = tmp.second; 234 | min_cost += flow * cost; 235 | update_flow(flow); 236 | distance = Dijkstra(); 237 | } 238 | 239 | return min_cost; 240 | } 241 | 242 | void accepted() { 243 | 244 | cout << mincost() << endl; 245 | 246 | for(ll i = start + 1; i < 1 + n; ++i) { 247 | 248 | for(ll j = 0; j < Nodes[i].list.size(); ++j) { 249 | 250 | Edge *e = Nodes[i].list[j]; 251 | ll from = e -> from; 252 | ll to = e -> to; 253 | ll ind_from = from - 1; 254 | ll ind_to = to - 1 - n; 255 | 256 | if (e -> flow == 1) { 257 | 258 | cout << ind_from + 1 << ' ' << ind_to + 1 << '\n'; 259 | } 260 | } 261 | } 262 | } 263 | }; 264 | 265 | int main() { 266 | 267 | Graph graph; 268 | graph.accepted(); 269 | 270 | return 0; 271 | } 272 | --------------------------------------------------------------------------------