├── term3 ├── LCA │ ├── problems.pdf │ ├── H │ │ └── main.cpp │ ├── B │ │ └── main.cpp │ ├── F │ │ └── main.cpp │ ├── D │ │ └── main.cpp │ ├── I │ │ └── main.cpp │ ├── E │ │ └── main.cpp │ ├── C │ │ └── main.cpp │ ├── A │ │ └── main.kt │ └── G │ │ └── main.cpp ├── Decomp │ ├── problems.pdf │ ├── D │ │ └── main.cpp │ └── E │ │ └── main.cpp └── Strings │ ├── problems.pdf │ ├── M │ └── main.cpp │ ├── B │ └── main.cpp │ ├── C │ └── main.cpp │ ├── E │ └── main.cpp │ ├── D │ └── main.cpp │ ├── A │ └── main.cpp │ ├── L │ └── main.cpp │ ├── F │ └── main.cpp │ ├── K │ └── main.cpp │ ├── J │ └── main.cpp │ ├── G │ └── main.cpp │ └── H │ └── main.cpp ├── term1 ├── trees │ ├── problems.pdf │ ├── A.cpp │ ├── B.cpp │ ├── D.cpp │ ├── F.cpp │ ├── K.cpp │ ├── I.cpp │ ├── H.cpp │ ├── J.cpp │ ├── E.cpp │ └── G.cpp ├── heap_sort │ ├── problems.pdf │ ├── F.cpp │ ├── A.cpp │ ├── D.py │ ├── C.cpp │ ├── E.cpp │ ├── G.cpp │ ├── H.cpp │ ├── I.cpp │ └── B.cpp └── linear_structures │ ├── problems.pdf │ ├── A.cpp │ ├── H.cpp │ ├── C.cpp │ ├── D.cpp │ ├── G.cpp │ ├── B.cpp │ ├── I.cpp │ ├── J.cpp │ ├── F.cpp │ └── E.cpp ├── term2 ├── Graphs │ ├── problems.pdf │ ├── M.cpp │ ├── C.cpp │ ├── L.cpp │ ├── D.cpp │ ├── E.cpp │ ├── K.cpp │ ├── G.cpp │ ├── H.cpp │ ├── I.cpp │ ├── F.cpp │ ├── N.cpp │ └── A.java ├── Shortest paths │ ├── problems.pdf │ ├── A.cpp │ ├── C.cpp │ ├── B.cpp │ ├── D.cpp │ ├── F.cpp │ └── E.cpp └── Dynamic programming │ ├── problems.pdf │ ├── A.py │ ├── G.cpp │ ├── D.cpp │ ├── B.py │ ├── L.cpp │ ├── J.cpp │ ├── F.cpp │ ├── K.cpp │ ├── C.cpp │ ├── M.cpp │ ├── E.cpp │ ├── H.cpp │ └── I.cpp ├── term4 ├── Crypto │ ├── problems.pdf │ ├── A.cpp │ ├── B.cpp │ ├── E.cpp │ ├── D.cpp │ ├── C.cpp │ ├── F.cpp │ └── G.cpp ├── Min cost flow │ ├── problems.pdf │ ├── D.cpp │ ├── B.cpp │ ├── A.cpp │ └── E.cpp └── Flow and Matching │ ├── problems.pdf │ ├── J.cpp │ ├── D.kt │ ├── F.kt │ └── C.kt └── README.md /term3/LCA/problems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Walingar/ITMO_ADS/HEAD/term3/LCA/problems.pdf -------------------------------------------------------------------------------- /term1/trees/problems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Walingar/ITMO_ADS/HEAD/term1/trees/problems.pdf -------------------------------------------------------------------------------- /term2/Graphs/problems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Walingar/ITMO_ADS/HEAD/term2/Graphs/problems.pdf -------------------------------------------------------------------------------- /term3/Decomp/problems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Walingar/ITMO_ADS/HEAD/term3/Decomp/problems.pdf -------------------------------------------------------------------------------- /term4/Crypto/problems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Walingar/ITMO_ADS/HEAD/term4/Crypto/problems.pdf -------------------------------------------------------------------------------- /term3/Strings/problems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Walingar/ITMO_ADS/HEAD/term3/Strings/problems.pdf -------------------------------------------------------------------------------- /term1/heap_sort/problems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Walingar/ITMO_ADS/HEAD/term1/heap_sort/problems.pdf -------------------------------------------------------------------------------- /term4/Min cost flow/problems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Walingar/ITMO_ADS/HEAD/term4/Min cost flow/problems.pdf -------------------------------------------------------------------------------- /term2/Shortest paths/problems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Walingar/ITMO_ADS/HEAD/term2/Shortest paths/problems.pdf -------------------------------------------------------------------------------- /term1/linear_structures/problems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Walingar/ITMO_ADS/HEAD/term1/linear_structures/problems.pdf -------------------------------------------------------------------------------- /term4/Flow and Matching/problems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Walingar/ITMO_ADS/HEAD/term4/Flow and Matching/problems.pdf -------------------------------------------------------------------------------- /term2/Dynamic programming/problems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Walingar/ITMO_ADS/HEAD/term2/Dynamic programming/problems.pdf -------------------------------------------------------------------------------- /term1/heap_sort/F.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | int main() 5 | { 6 | std::ifstream fin("antiqs.in"); 7 | std::ofstream fout("antiqs.out"); 8 | int n; 9 | fin >> n; 10 | std::vector a(n); 11 | for (int i=0; i 2 | 3 | using namespace std; 4 | const string file_name = "rps2"; 5 | 6 | //#define inp cin 7 | //#define out cout 8 | 9 | ifstream inp(file_name + ".in"); 10 | ofstream out(file_name + ".out"); 11 | 12 | int r1, r2, s1, s2, p1, p2; 13 | 14 | void input() { 15 | inp >> r1 >> s1 >> p1 >> r2 >> s2 >> p2; 16 | } 17 | 18 | void solve() { 19 | 20 | } 21 | 22 | void output() { 23 | out << max(0, max(p1 - p2 - s2, max(r1 - r2 - p2, s1 - s2 - r2))); 24 | // :))))))))))))))))))))))))))) 25 | // or determinative graph and search min cost flow there 26 | } 27 | 28 | 29 | int main() { 30 | input(); 31 | solve(); 32 | output(); 33 | return 0; 34 | } -------------------------------------------------------------------------------- /term1/linear_structures/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | std::ofstream out("decode.out"); 5 | std::ifstream in("decode.in"); 6 | 7 | 8 | int main() 9 | { 10 | std::stack ans; 11 | std::string s; 12 | in >> s; 13 | ans.push(s[0]); 14 | for (int i = 1; i < s.length(); i++) 15 | { 16 | if (ans.size() > 0 && ans.top() == s[i]) { 17 | ans.pop(); 18 | } 19 | else 20 | { 21 | ans.push(s[i]); 22 | } 23 | } 24 | s = ""; 25 | while (ans.size() > 0) { 26 | s += ans.top(); 27 | ans.pop(); 28 | } 29 | for (int i = s.length()-1; i >= 0; i--) 30 | { 31 | out << s[i]; 32 | } 33 | out.close(); 34 | in.close(); 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /term2/Dynamic programming/A.py: -------------------------------------------------------------------------------- 1 | import sys 2 | sys.stdin = open("lis.in") 3 | sys.stdout = open("lis.out", "w") 4 | n = input() 5 | a = list(map(int, input().split())) 6 | dp = [1] * len(a) 7 | p = [-1] * len(a) 8 | for i in range(len(a)): 9 | for j in range(i): 10 | if a[j] < a[i]: 11 | dp[i] = max(dp[i], dp[j] + 1) 12 | if dp[j] + 1 == dp[i]: 13 | p[i] = j 14 | ans = max(dp) 15 | print(ans) 16 | ansArray = [] 17 | for i in range(len(dp)): 18 | if dp[i] == ans: 19 | ansArray.append(a[i]) 20 | j = p[i] 21 | while j != -1: 22 | ansArray.append(a[j]) 23 | j = p[j] 24 | print(*ansArray[::-1]) 25 | break 26 | sys.stdin.close() 27 | sys.stdout.close() -------------------------------------------------------------------------------- /term1/heap_sort/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | std::ifstream fin("isheap.in"); 6 | int n; 7 | fin >> n; 8 | int a[n]; 9 | for(int i = 0; i < n; i++) 10 | { 11 | fin >> a[i]; 12 | } 13 | fin.close(); 14 | std::ofstream fout("isheap.out"); 15 | for(int i = 0; i < n; i++) 16 | { 17 | if (2*i+1 < n && a[i] > a[2*i+1]) 18 | { 19 | fout << "NO"; 20 | fout.close(); 21 | return 0; 22 | } 23 | else if(2*i+2 < n && a[i] > a[2*i+2]) 24 | { 25 | fout << "NO"; 26 | fout.close(); 27 | return 0; 28 | } 29 | } 30 | fout << "YES"; 31 | fout.close(); 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /term1/heap_sort/D.py: -------------------------------------------------------------------------------- 1 | import sys 2 | def kth(l,r,k): 3 | global a 4 | m = a[(l+r)//2] 5 | i = 0 6 | j = r 7 | while i <= j: 8 | while a[i] < m: i += 1 9 | while a[j] > m: j -= 1 10 | if i <= j: 11 | temp = a[i] 12 | a[i] = a[j] 13 | a[j] = temp 14 | i += 1 15 | j -= 1 16 | if l <= k and k <= j: 17 | return kth(l, j, k) 18 | if i <= k and k <= r: 19 | return kth(i, r, k) 20 | return a[k] 21 | sys.stdin = open("kth.in") 22 | sys.stdout = open("kth.out", "w") 23 | n,k = map(int,input().split()) 24 | a = [] 25 | a1,b,c,temp1,temp2 = map(int,input().split()) 26 | a.append(temp1) 27 | a.append(temp2) 28 | for i in range(2,n): 29 | a.append(a1*a[i-1] + b*a[i-2] + c) 30 | print(kth(0,n-1,k-1)) 31 | sys.stdin.close() 32 | sys.stdout.close() -------------------------------------------------------------------------------- /term1/linear_structures/H.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | std::ofstream out("hemoglobin.out"); 8 | std::ifstream in("hemoglobin.in"); 9 | int main() 10 | { 11 | std::stack a; 12 | int n; 13 | in >> n; 14 | char s; 15 | std::vector summ(n + 1); 16 | for (int i=0; i< n; i++){ 17 | in >> s; 18 | if (s == '+'){ 19 | int x; 20 | in >> x; 21 | a.push(x); 22 | summ[a.size()] = summ[a.size()-1] + x; 23 | } 24 | else if ( s == '-'){ 25 | out << a.top() << "\n"; 26 | a.pop(); 27 | } 28 | else{ 29 | int k; 30 | in >> k; 31 | out << summ[a.size()] - summ[a.size() - k] << "\n"; 32 | } 33 | } 34 | in.close(); 35 | out.close(); 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /term4/Crypto/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const string file_name = "mincost"; 5 | 6 | #define inp cin 7 | #define out cout 8 | 9 | //ifstream inp(file_name + ".in"); 10 | //ofstream out(file_name + ".out"); 11 | 12 | const int MAX_N = 1000000 + 5; 13 | int n; 14 | 15 | vector prime(static_cast(MAX_N + 1), true); 16 | 17 | void input() { 18 | 19 | n = MAX_N; 20 | prime[0] = false; 21 | prime[1] = false; 22 | for (int i = 2; i <= n; ++i) 23 | if (prime[i]) { 24 | long long sqr = i * 1ll * i; 25 | for (long long j = sqr; j <= n; j += i) 26 | prime[j] = false; 27 | } 28 | 29 | inp >> n; 30 | int val; 31 | for (int i = 0; i < n; ++i) { 32 | scanf("%d", &val); 33 | if (prime[val]) { 34 | printf("YES\n"); 35 | } else { 36 | printf("NO\n"); 37 | } 38 | } 39 | } 40 | 41 | 42 | int main() { 43 | input(); 44 | return 0; 45 | } -------------------------------------------------------------------------------- /term3/Strings/M/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | int z[1000000 + 50]; 8 | long long ans = 1; 9 | string s; 10 | ifstream in("cyclic.in"); 11 | ofstream out("cyclic.out"); 12 | 13 | void input() { 14 | in >> s; 15 | s += s; 16 | } 17 | 18 | void solve() { 19 | int left = 0, right = 0; 20 | for (int i = 1; i < s.length() / 2; ++i) { 21 | if (i <= right) 22 | z[i] = min(right - i, z[i - left]); 23 | while (i + z[i] < s.length() && s[z[i]] == s[i + z[i]]) 24 | ++z[i]; 25 | if (i + z[i] > right) { 26 | left = i; 27 | right = i + z[i] - 1; 28 | } 29 | if (i + z[i] < s.length() && s[i + z[i]] < s[z[i]]){ 30 | //cerr << i << " "; 31 | ans++; 32 | } 33 | } 34 | } 35 | 36 | void output() { 37 | out << ans; 38 | } 39 | 40 | int main() { 41 | input(); 42 | solve(); 43 | output(); 44 | return 0; 45 | } -------------------------------------------------------------------------------- /term2/Dynamic programming/G.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Walingar on 06.03.2017. 3 | // 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | int n, l; 12 | long long h[2001]; 13 | long long w[2001]; 14 | long long dp[2001]; 15 | std::string s; 16 | std::ifstream in("bookshelf.in"); 17 | std::ofstream out("bookshelf.out"); 18 | std::string ans = ""; 19 | 20 | int main() { 21 | in >> n >> l; 22 | for (int i = 0; i < n; ++i) { 23 | in >> h[i] >> w[i]; 24 | } 25 | dp[0] = h[0]; 26 | for (int i = 1; i < n; ++i) { 27 | dp[i] = dp[i - 1] + h[i]; 28 | long long hm = -1; 29 | long long len = 0; 30 | for (int j = i; len < l && j > -1; --j) { 31 | hm = std::max(h[j], hm); 32 | len += w[j]; 33 | if (len > l) break; 34 | dp[i] = std::min(dp[i], dp[j - 1] + hm); 35 | } 36 | } 37 | out << dp[n - 1]; 38 | in.close(); 39 | out.close(); 40 | return 0; 41 | } -------------------------------------------------------------------------------- /term2/Dynamic programming/D.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Walingar on 06.03.2017. 3 | // 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | int n, m; 10 | int dp[5001][5001]; 11 | int main() { 12 | std::ifstream in("levenshtein.in"); 13 | std::ofstream out("levenshtein.out"); 14 | std::string a, b; 15 | in >> a >> b; 16 | n = a.length(); 17 | m = b.length(); 18 | for (int i = 0; i <= n; ++i){ 19 | dp[i][0] = i; 20 | } 21 | for (int i = 0; i <= m; ++i){ 22 | dp[0][i] = i; 23 | } 24 | for (int i = 1; i <= n; ++i) { 25 | for (int j = 1; j <= m; ++j) { 26 | if (a[i - 1] == b[j - 1]) { 27 | dp[i][j] = dp[i - 1][j - 1]; 28 | } else { 29 | dp[i][j] = std::min(dp[i - 1][j - 1] + 1, dp[i - 1][j] + 1); 30 | dp[i][j] = std::min(dp[i][j], dp[i][j - 1] + 1); 31 | } 32 | } 33 | } 34 | out << dp[n][m]; 35 | in.close(); 36 | out.close(); 37 | return 0; 38 | } -------------------------------------------------------------------------------- /term1/linear_structures/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | std::ofstream out("postfix.out"); 6 | std::ifstream in("postfix.in"); 7 | 8 | 9 | int main() 10 | { 11 | std::stack a; 12 | std::string s; 13 | int x,y; 14 | while (in >> s) 15 | { 16 | if (s == "+"){ 17 | x = a.top(); 18 | a.pop(); 19 | y = a.top(); 20 | a.pop(); 21 | a.push(x+y); 22 | } 23 | else if (s == "-"){ 24 | x = a.top(); 25 | a.pop(); 26 | y = a.top(); 27 | a.pop(); 28 | a.push(y - x); 29 | } 30 | else if (s == "*"){ 31 | x = a.top(); 32 | a.pop(); 33 | y = a.top(); 34 | a.pop(); 35 | a.push(x*y); 36 | } 37 | else{ 38 | a.push(atoi(s.c_str())); 39 | } 40 | } 41 | out << a.top(); 42 | out.close(); 43 | in.close(); 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /term3/Strings/B/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | string s; 15 | int n, m, f; 16 | const unsigned int MAX_N = 1000000 + 50; 17 | vector pi(MAX_N, 0); 18 | #define in cin 19 | #define out cout 20 | //ifstream in("path.in"); 21 | //ofstream out("path.out"); 22 | 23 | void get_preffix_function() { 24 | int j = 0; 25 | for (int i = 1; i < s.length(); ++i) { 26 | j = pi[i - 1]; 27 | while (j > 0 && s[i] != s[j]) 28 | j = pi[j - 1]; 29 | if (s[i] == s[j]) 30 | pi[i] = ++j; 31 | } 32 | } 33 | 34 | 35 | void input() { 36 | in >> s; 37 | } 38 | 39 | 40 | void solve() { 41 | get_preffix_function(); 42 | 43 | } 44 | 45 | 46 | void output() { 47 | for (int i = 0; i < s.length(); ++i) 48 | out << pi[i] << " "; 49 | } 50 | 51 | int main() { 52 | input(); 53 | solve(); 54 | output(); 55 | return 0; 56 | } -------------------------------------------------------------------------------- /term1/heap_sort/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void merge(std::vector&a, int l1, int r1, int l2, int r2) 5 | { 6 | std::vector b; 7 | int l3 = l1; 8 | while (l1&a, int l, int r) 28 | { 29 | if (r - l>1) 30 | { 31 | sort(a, l, (l + r) / 2); 32 | sort(a, (l + r) / 2, r); 33 | merge(a, l, (l + r) / 2, (l + r) / 2, r); 34 | } 35 | } 36 | 37 | 38 | int main() 39 | { 40 | std::ifstream fin("sort.in"); 41 | std::ofstream fout("sort.out"); 42 | int n; 43 | fin >> n; 44 | std::vector a(n); 45 | for (int i = 0; i < n; i++) 46 | { 47 | fin >> a[i]; 48 | } 49 | sort(a, 0, a.size()); 50 | for (int i = 0; i < n; i++) 51 | { 52 | fout << a[i] << " "; 53 | } 54 | fin.close(); 55 | fout.close(); 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /term2/Dynamic programming/B.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | sys.stdin = open("lcs.in") 4 | sys.stdout = open("lcs.out", "w") 5 | n = int(input()) 6 | a = list(map(int, input().split())) 7 | m = int(input()) 8 | b = list(map(int, input().split())) 9 | dp = [[0] * (m + 1) for i in range(n + 1)] 10 | p = [[0] * (m + 1) for i in range(n + 1)] 11 | 12 | for i in range(1, n + 1): 13 | for j in range(1, m + 1): 14 | if a[i - 1] == b[j - 1]: 15 | dp[i][j] = dp[i - 1][j - 1] + 1 16 | p[i][j] = [i - 1, j - 1] 17 | else: 18 | if dp[i - 1][j] >= dp[i][j - 1]: 19 | dp[i][j] = dp[i - 1][j] 20 | p[i][j] = [i - 1, j] 21 | else: 22 | dp[i][j] = dp[i][j - 1] 23 | p[i][j] = [i, j - 1] 24 | i = n 25 | j = m 26 | ans = [] 27 | print(dp[n][m]) 28 | del dp 29 | while i != 0 and j != 0: 30 | if p[i][j] == [i - 1, j - 1]: 31 | ans.append(a[i - 1]) 32 | i -= 1 33 | j -= 1 34 | else: 35 | if p[i][j] == [i - 1, j]: 36 | i -= 1 37 | else: 38 | j -= 1 39 | 40 | print(*ans[::-1]) 41 | sys.stdin.close() 42 | sys.stdout.close() -------------------------------------------------------------------------------- /term1/heap_sort/E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | std::vector csort(std::vector &a, int p) 5 | { 6 | std::vector counts(256); 7 | std::vector ans(a.size()); 8 | for (int i = 0; i=0; i--) 17 | { 18 | int numb = counts[(int)a[i][p]]; 19 | ans[numb-1] = a[i]; 20 | counts[(int)a[i][p]]--; 21 | } 22 | return ans; 23 | } 24 | 25 | int main() 26 | { 27 | std::ifstream fin("radixsort.in"); 28 | std::ofstream fout("radixsort.out"); 29 | int n,k,m; 30 | fin >> n >> m >> k; 31 | std::vector a(n); 32 | for(int i = 0; i < n; i++) 33 | { 34 | fin >> a[i]; 35 | } 36 | for(int i = 0; i < k; i++) 37 | { 38 | a = csort(a,m-1-i); 39 | } 40 | for(int i = 0; i 2 | 3 | using namespace std; 4 | const string file_name = "mincost"; 5 | 6 | #define inp cin 7 | #define out cout 8 | 9 | //ifstream inp(file_name + ".in"); 10 | //ofstream out(file_name + ".out"); 11 | 12 | const int MAX_N = 1000000 + 5; 13 | int n; 14 | 15 | vector prime(static_cast(MAX_N + 1), true); 16 | 17 | void input() { 18 | n = MAX_N; 19 | for (int i = 0; i <= n; ++i) { 20 | prime[i] = i; 21 | } 22 | for (int i = 2; i <= n; ++i) 23 | if (prime[i] == i) { 24 | long long sqr = i * 1ll * i; 25 | for (long long j = sqr; j <= n; j += i) 26 | prime[j] = i; 27 | } 28 | 29 | inp >> n; 30 | int val; 31 | vector ans; 32 | for (int i = 0; i < n; ++i) { 33 | scanf("%d", &val); 34 | ans.clear(); 35 | while (val != 1) { 36 | ans.push_back(prime[val]); 37 | val /= prime[val]; 38 | } 39 | sort(ans.begin(), ans.end()); 40 | for (auto j: ans) { 41 | printf("%d ", j); 42 | } 43 | printf("\n"); 44 | } 45 | } 46 | 47 | 48 | int main() { 49 | input(); 50 | return 0; 51 | } -------------------------------------------------------------------------------- /term3/Strings/C/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | string s; 16 | int n, m, f; 17 | const unsigned int MAX_N = 1000000 + 50; 18 | vector z(MAX_N, 0); 19 | #define in cin 20 | #define out cout 21 | //ifstream in("path.in"); 22 | //ofstream out("path.out"); 23 | 24 | void get_z_function() { 25 | int l = 0, r = 0; 26 | 27 | for (int i = 1; i < s.length(); ++i) { 28 | z[i] = min(r - i, z[i - l]); 29 | if (z[i] < 0) 30 | z[i] = 0; 31 | while (i + z[i] < s.length() && s[z[i]] == s[i + z[i]]) 32 | ++z[i]; 33 | if (i + z[i] - 1> r) { 34 | l = i; 35 | r = i + z[i]; 36 | } 37 | } 38 | 39 | } 40 | 41 | 42 | void input() { 43 | in >> s; 44 | } 45 | 46 | 47 | void solve() { 48 | get_z_function(); 49 | 50 | } 51 | 52 | 53 | void output() { 54 | for (int i = 1; i < s.length(); ++i) 55 | out << z[i] << " "; 56 | } 57 | 58 | int main() { 59 | input(); 60 | solve(); 61 | output(); 62 | return 0; 63 | } -------------------------------------------------------------------------------- /term3/Strings/E/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | string p, t, s; 16 | int n, m, f; 17 | const unsigned int MAX_N = 2000000 + 50; 18 | vector pi(MAX_N, 0); 19 | #define in cin 20 | #define out cout 21 | //ifstream in("path.in"); 22 | //ofstream out("path.out"); 23 | 24 | void get_prefix_function() { 25 | int j = 0; 26 | for (int i = 1; i < s.length(); ++i) { 27 | j = pi[i - 1]; 28 | while (j > 0 && s[i] != s[j]) 29 | j = pi[j - 1]; 30 | if (s[i] == s[j]) 31 | pi[i] = ++j; 32 | } 33 | } 34 | 35 | 36 | void input() { 37 | in >> s; 38 | } 39 | 40 | 41 | void solve() { 42 | get_prefix_function(); 43 | } 44 | 45 | 46 | void output() { 47 | int k = pi[s.length() - 1]; 48 | if (k == 0) { 49 | out << s.length(); 50 | return; 51 | } 52 | if (s.length() % (s.length() - k) == 0) { 53 | out << s.length() - k; 54 | return; 55 | } 56 | out << s.length(); 57 | } 58 | 59 | int main() { 60 | input(); 61 | solve(); 62 | output(); 63 | return 0; 64 | } -------------------------------------------------------------------------------- /term2/Shortest paths/A.cpp: -------------------------------------------------------------------------------- 1 | // Created by Walingar on 06.03.2017. 2 | // 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | int n, m; 12 | const unsigned int MAX_N = 300000; 13 | using namespace std; 14 | ifstream in("pathbge1.in"); 15 | ofstream out("pathbge1.out"); 16 | int ans = 0; 17 | 18 | vector > edges(MAX_N + 2); 19 | 20 | void input() { 21 | in >> n >> m; 22 | for (int i = 0; i < m; ++i) { 23 | int from, to; 24 | in >> from >> to; 25 | edges[from].push_back(to); 26 | edges[to].push_back(from); 27 | } 28 | } 29 | vector d(MAX_N, 0); 30 | void solve() { 31 | int s = 1; 32 | queue q; 33 | q.push(s); 34 | vector was(MAX_N, false); 35 | was[s] = true; 36 | while (!q.empty()) { 37 | int v = q.front(); 38 | q.pop(); 39 | for(auto to: edges[v]) { 40 | if (!was[to]) { 41 | was[to] = true; 42 | q.push(to); 43 | d[to] = d[v] + 1; 44 | } 45 | } 46 | } 47 | } 48 | 49 | void output() { 50 | for (int i = 1; i <= n; ++i) out << d[i] << " "; 51 | } 52 | 53 | int main() { 54 | input(); 55 | solve(); 56 | output(); 57 | return 0; 58 | } -------------------------------------------------------------------------------- /term1/linear_structures/D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | std::ofstream out("stack-min.out"); 6 | std::ifstream in("stack-min.in"); 7 | 8 | struct stuck_cell 9 | { 10 | int data; 11 | int minim; 12 | stuck_cell *next; 13 | }; 14 | 15 | struct stack 16 | { 17 | stack(): head(NULL){}; 18 | stuck_cell *head; 19 | void push(int x) 20 | { 21 | stuck_cell *p = new stuck_cell; 22 | p->next = this->head; 23 | p->data = x; 24 | if (!this->head || x < this->head->minim){ 25 | p->minim = x; 26 | } 27 | else 28 | { 29 | p->minim = this->head->minim; 30 | } 31 | this->head = p; 32 | } 33 | void pop() 34 | { 35 | stuck_cell *p = this->head; 36 | this->head = p->next; 37 | delete p; 38 | } 39 | }; 40 | 41 | int main() 42 | { 43 | stack a; 44 | int com; 45 | int n; 46 | in >> n; 47 | for (int i = 0; i < n; i++){ 48 | in >> com; 49 | if (com == 1){ 50 | int temp; 51 | in >> temp; 52 | a.push(temp); 53 | } 54 | else if (com == 2){ 55 | a.pop(); 56 | } 57 | else{ 58 | out << a.head->minim << "\n"; 59 | } 60 | } 61 | in.close(); 62 | out.close(); 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /term3/Strings/D/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | string p, t, s; 16 | int n, m, f; 17 | const unsigned int MAX_N = 2000000 + 50; 18 | vector pi(MAX_N, 0); 19 | #define in cin 20 | #define out cout 21 | //ifstream in("path.in"); 22 | //ofstream out("path.out"); 23 | 24 | void get_prefix_function() { 25 | int j = 0; 26 | for (int i = 1; i < s.length(); ++i) { 27 | j = pi[i - 1]; 28 | while (j > 0 && s[i] != s[j]) 29 | j = pi[j - 1]; 30 | if (s[i] == s[j]) 31 | pi[i] = ++j; 32 | } 33 | } 34 | 35 | 36 | void input() { 37 | in >> p; 38 | in >> t; 39 | } 40 | 41 | 42 | void solve() { 43 | s = p + "#" + t; 44 | get_prefix_function(); 45 | } 46 | 47 | 48 | void output() { 49 | vector ans; 50 | for (int i = (int) p.length(); i < s.length(); ++i) { 51 | if (pi[i] == p.length()) 52 | ans.push_back(i - 2 * (int) p.length() + 1); 53 | } 54 | out << ans.size() << "\n"; 55 | for (auto i: ans) 56 | out << i << " "; 57 | } 58 | 59 | int main() { 60 | input(); 61 | solve(); 62 | output(); 63 | return 0; 64 | } -------------------------------------------------------------------------------- /term4/Crypto/E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const string file_name = "mincost"; 5 | 6 | #define inp cin 7 | #define out cout 8 | 9 | //ifstream inp(file_name + ".in"); 10 | //ofstream out(file_name + ".out"); 11 | int a_0, a_1, p_0, p_1; 12 | 13 | int EuclidAdv(int a, int m) { 14 | a = a % m; 15 | for (int x = 1; x < m; x++) 16 | if ((a * x) % m == 1) 17 | return x; 18 | } 19 | 20 | int kto(int *a, int *p, int size) { 21 | int r[size][size]; 22 | for (int i = 0; i < size; ++i) 23 | for (int j = i + 1; j < size; ++j) 24 | r[i][j] = EuclidAdv(p[i], p[j]); 25 | 26 | int result = 0; 27 | int mult_p = 1; 28 | int x[size] = {0}; 29 | for (int i = 0; i < 2; ++i) { 30 | x[i] = a[i]; 31 | for (int j = 0; j < i; ++j) { 32 | x[i] = (x[i] - x[j]) * r[j][i]; 33 | x[i] = x[i] % p[i]; 34 | if (x[i] < 0) { 35 | x[i] += p[i]; 36 | } 37 | } 38 | result += mult_p * x[i]; 39 | mult_p *= p[i]; 40 | } 41 | return result; 42 | } 43 | 44 | void input() { 45 | inp >> a_0 >> a_1 >> p_0 >> p_1; 46 | // x == a_0 mod p_0 47 | // x == a_1 mod p_1 48 | int p[] = {p_0, p_1}; 49 | int a[] = {a_0, a_1}; 50 | printf("%d", kto(a, p, 2)); 51 | } 52 | 53 | 54 | int main() { 55 | input(); 56 | return 0; 57 | } -------------------------------------------------------------------------------- /term1/heap_sort/G.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | int main() 6 | { 7 | std::ifstream fin("style.in"); 8 | std::ofstream fout("style.out"); 9 | int n; 10 | fin>> n; 11 | std::vector a(n); 12 | for(int i = 0; i < n; i++) 13 | { 14 | fin >> a[i]; 15 | } 16 | int m; 17 | fin>> m; 18 | std::vector b(m); 19 | for(int i = 0; i < m; i++) 20 | { 21 | fin >> b[i]; 22 | } 23 | int ans=std::abs(a[0]-b[0]),ansi=1,ansj=1; 24 | int i=0, j=0; 25 | while(istd::abs(a[i]-b[j])) 28 | { 29 | ans = std::abs(a[i]-b[j]); 30 | ansi=i+1; 31 | ansj=j+1; 32 | } 33 | if (a[i]std::abs(a[i]-b[j])) 48 | { 49 | ans = std::abs(a[i]-b[j]); 50 | ansi=i+1; 51 | ansj=j+1; 52 | } 53 | } 54 | //output 55 | fout << a[ansi-1] << " " << b[ansj-1]; 56 | fin.close(); 57 | fout.close(); 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /term1/linear_structures/G.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | std::ofstream out("saloon.out"); 8 | std::ifstream in("saloon.in"); 9 | int main() 10 | { 11 | std::queue ans; 12 | int n; 13 | in >> n; 14 | std::vector answer(n,0); 15 | std::queue s; 16 | for (int i = 0; i < n; i++){ 17 | int hour, minut, toler; 18 | in >> hour >> minut>> toler; 19 | int now = hour*60 + minut; 20 | while(ans.size() > 0 && ans.front() + 20 <= now){ 21 | s.push(ans.front()+20); 22 | ans.pop(); 23 | } 24 | if(ans.size() > toler) 25 | { 26 | answer[i] = now; 27 | } 28 | else{ 29 | if (ans.size() == 0){ 30 | ans.push(hour*60+minut); 31 | } 32 | else{ 33 | ans.push(ans.front()+20*ans.size()); 34 | } 35 | 36 | } 37 | } 38 | while(ans.size() > 0){ 39 | s.push(ans.front()+20); 40 | ans.pop(); 41 | } 42 | for(int i =0 ; i < n; i++){ 43 | if(answer[i] == 0){ 44 | out << s.front()/60 << " " << s.front()%60 << "\n"; 45 | s.pop(); 46 | } 47 | else{ 48 | out << answer[i]/60 << " " << answer[i]%60 << "\n"; 49 | } 50 | } 51 | in.close(); 52 | out.close(); 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /term2/Shortest paths/C.cpp: -------------------------------------------------------------------------------- 1 | // Created by Walingar on 06.03.2017. 2 | // 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | long long n, m, s, f; 13 | const unsigned long long MAX_N = 205; 14 | using namespace std; 15 | ifstream in("pathsg.in"); 16 | ofstream out("pathsg.out"); 17 | long long ans = 0; 18 | 19 | vector> d(MAX_N, vector(MAX_N, LLONG_MAX)); 20 | 21 | 22 | void input() { 23 | in >> n >> m; 24 | for (long long i = 0; i < m; ++i) { 25 | long long from, to, w; 26 | in >> from >> to >> w; 27 | --from; 28 | --to; 29 | d[from][to] = w; 30 | } 31 | } 32 | 33 | void solve() { 34 | for (long long k = 0; k < n; ++k) 35 | d[k][k] = 0; 36 | 37 | for (long long k = 0; k < n; ++k) 38 | for (long long i = 0; i < n; ++i) 39 | for (long long j = 0; j < n; ++j) 40 | if (d[i][k] < LLONG_MAX && d[k][j] < LLONG_MAX) 41 | d[i][j] = min(d[i][j], d[i][k] + d[k][j]); 42 | } 43 | 44 | void output() { 45 | for (long long k = 0; k < n; ++k) { 46 | for (long long i = 0; i < n; ++i) { 47 | if (d[k][i] != LLONG_MAX) out << d[k][i] << " "; 48 | else out << "-1" << " "; 49 | } 50 | 51 | out << "\n"; 52 | } 53 | } 54 | 55 | int main() { 56 | input(); 57 | solve(); 58 | output(); 59 | return 0; 60 | } -------------------------------------------------------------------------------- /term1/linear_structures/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | std::ofstream out("brackets.out"); 5 | std::ifstream in("brackets.in"); 6 | 7 | 8 | int main() 9 | { 10 | std::stack ans; 11 | std::string s; 12 | std::string answer = "YES"; 13 | in >> s; 14 | for (int i = 0; i < s.length(); i++) 15 | { 16 | if (s[i] == '[' || s[i] == '{' || s[i] == '('){ 17 | ans.push(s[i]); 18 | } 19 | else 20 | { 21 | if (ans.size() == 0) 22 | { 23 | answer = "NO"; 24 | break; 25 | } 26 | else 27 | { 28 | if (s[i] == '}' && ans.top() == '{'){ 29 | answer = "YES"; 30 | ans.pop(); 31 | } 32 | else if (s[i] == ']' && ans.top() == '['){ 33 | answer = "YES"; 34 | ans.pop(); 35 | } 36 | else if (s[i] == ')'&& ans.top() == '('){ 37 | answer = "YES"; 38 | ans.pop(); 39 | } 40 | else{ 41 | answer = "NO"; 42 | break; 43 | } 44 | } 45 | } 46 | } 47 | if (ans.size() == 0) 48 | { 49 | out << answer; 50 | } 51 | else{ 52 | out << "NO"; 53 | } 54 | out.close(); 55 | in.close(); 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /term2/Dynamic programming/L.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | const unsigned int MAX_N = 10000; 14 | string s; 15 | string p; 16 | vector dp(MAX_N + 2); 17 | int n, k; 18 | char S; 19 | ifstream in("selectw.in"); 20 | ofstream out("selectw.out"); 21 | vector weights(MAX_N); 22 | vector> tree(MAX_N); 23 | int root = 0; 24 | 25 | void input() { 26 | in >> n; 27 | for (int to = 0; to < n; ++to) { 28 | int from, w; 29 | in >> from >> w; 30 | --from; 31 | if (from >= 0) tree[from].push_back(to); 32 | else root = to; 33 | weights[to] = w; 34 | } 35 | } 36 | 37 | vector was(MAX_N, false); 38 | 39 | int dfs(int v) { 40 | int ans = weights[v]; 41 | for (auto to: tree[v]) 42 | for (auto toto: tree[to]) 43 | if (!was[toto]) ans += dfs(toto); 44 | else ans += dp[toto]; 45 | int temp = 0; 46 | for (auto to: tree[v]) 47 | if (!was[to]) temp += dfs(to); 48 | else temp += dp[to]; 49 | dp[v] = max(temp, ans); 50 | was[v] = true; 51 | return max(temp, ans); 52 | } 53 | 54 | void solve() { 55 | out << dfs(root); 56 | } 57 | 58 | void output() { 59 | 60 | } 61 | 62 | int main() { 63 | input(); 64 | solve(); 65 | output(); 66 | in.close(); 67 | out.close(); 68 | } -------------------------------------------------------------------------------- /term2/Dynamic programming/J.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | const unsigned int MAX_N = 10000; 14 | string s; 15 | string p; 16 | vector> dp(MAX_N + 2, vector(MAX_N + 2)); 17 | int n, k; 18 | char S; 19 | map rules; 20 | ifstream in("automaton.in"); 21 | ofstream out("automaton.out"); 22 | 23 | void input() { 24 | cin >> p; 25 | cin >> s; 26 | for (int i = 1; i < s.length() + 1; ++i) dp[i][0] = false; 27 | for (int i = 1; i < p.length() + 1; ++i) dp[0][i] = false; 28 | dp[0][0] = true; 29 | } 30 | 31 | void solve() { 32 | int j = 1; 33 | while (p.length() >= j && p[j - 1] == '*') { 34 | for (int i = 0; i < s.length() + 1; ++i) 35 | dp[i][j] = true; 36 | ++j; 37 | } 38 | for (int i = 1; i < s.length() + 1; ++i) 39 | for (int j = 1; j < p.length() + 1; ++j) { 40 | if (p[j - 1] == '?' || p[j - 1] == s[i - 1]) dp[i][j] = dp[i - 1][j - 1]; 41 | else if (p[j - 1] == '*') 42 | dp[i][j] = dp[i][j - 1] || dp[i - 1][j]; 43 | else dp[i][j] = false; 44 | } 45 | } 46 | 47 | void output() { 48 | if (dp[s.length()][p.length()]) 49 | cout << "YES"; 50 | else cout << "NO"; 51 | } 52 | 53 | int main() { 54 | input(); 55 | solve(); 56 | output(); 57 | in.close(); 58 | out.close(); 59 | } -------------------------------------------------------------------------------- /term2/Graphs/M.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | string fileName = "game"; 9 | ofstream out(fileName + ".out"); 10 | ifstream in(fileName + ".in"); 11 | int n, m, s; 12 | unsigned int MAX_N = 100000; 13 | vector> edges(MAX_N); 14 | vector color(MAX_N, 0); 15 | vector was(MAX_N, false); 16 | vector component; 17 | vector components(MAX_N, 0); 18 | vector order; 19 | int ans = 0; 20 | vector path(MAX_N, -1); 21 | int start, finish; 22 | int ans1 = 0, ans2 = 0; 23 | string as = "Second player wins"; 24 | enum token { 25 | first, second 26 | }; 27 | void input() { 28 | in >> n >> m >> s; 29 | --s; 30 | for (int i = 0; i < m; ++i) { 31 | int x, y; 32 | in >> x >> y; 33 | edges[x - 1].push_back(y - 1); 34 | } 35 | } 36 | 37 | void output() { 38 | out << as; 39 | } 40 | 41 | bool check(int to){ 42 | return edges[to].size() == 0; 43 | } 44 | 45 | void dfs(int v, token e) { 46 | //was[v] = true; 47 | for (auto to: edges[v]) { 48 | if (!was[to]) { 49 | if (e == first && check(to)) as = "First player wins"; 50 | else { 51 | if (e == first) dfs(to, second); 52 | else dfs(to, first); 53 | } 54 | } 55 | } 56 | } 57 | 58 | void solve() { 59 | if(!check(s)) dfs(s, first); 60 | else as = "Second player wins"; 61 | } 62 | 63 | int main() { 64 | input(); 65 | solve(); 66 | output(); 67 | return 0; 68 | } -------------------------------------------------------------------------------- /term1/heap_sort/H.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | int main() 8 | { 9 | vector > a; 10 | vector ans(4); 11 | vector cnt(4); 12 | vector last(4); 13 | ofstream fout("style.out"); 14 | ifstream fin("style.in"); 15 | for (int i = 0; i < 4; i++) 16 | { 17 | int l; 18 | fin >> l; 19 | for (int j = 0; j < l; j++) 20 | { 21 | int temp; 22 | fin >> temp; 23 | a.push_back(make_pair(temp, i)); 24 | } 25 | } 26 | sort(a.begin(), a.end()); 27 | 28 | int razn = 10000000, now = 0, left = 0; 29 | for (int i = 0; i < a.size(); i++) 30 | { 31 | cnt[a[i].second]++; 32 | if (cnt[a[i].second] == 1) 33 | { 34 | now++; 35 | //we need to have 4 subj in 'last' array 36 | } 37 | last[a[i].second] = a[i].first; 38 | while (cnt[a[left].second] > 1) 39 | { 40 | cnt[a[left].second]--; 41 | left++; 42 | } 43 | if (now == 4 && (a[i].first - a[left].first) < razn) 44 | { 45 | razn = a[i].first - a[left].first; 46 | for (int j = 0; j < 4; j++) 47 | ans[j] = last[j]; 48 | } 49 | } 50 | for (int i = 0; i < 4; i++) 51 | { 52 | fout << ans[i] << ' '; 53 | } 54 | fout.close(); 55 | fin.close(); 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /term3/Decomp/D/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | #define in cin 8 | #define out cout 9 | 10 | //ifstream in("input.txt"); 11 | //ofstream out("output.txt"); 12 | 13 | int n, m; 14 | int MAX_N = 2*100000 + 50; 15 | vector< vector > edges(MAX_N); 16 | vector centroidDecomp(MAX_N); 17 | vector level(MAX_N, -1); 18 | void input() { 19 | in >> n; 20 | int v, u; 21 | for (int i = 0; i < n - 1; ++i) { 22 | in >> v >> u; 23 | --v; 24 | --u; 25 | edges[v].push_back(u); 26 | edges[u].push_back(v); 27 | } 28 | } 29 | 30 | int dfsCounting(int v, int size, int ¢roid, int p = -1) { 31 | int s = 1; 32 | for (auto to: edges[v]) 33 | if (level[to] == -1 && to != p) 34 | s += dfsCounting(to, size, centroid, v); 35 | if (centroid == -1 && (2 * s >= size || p == -1)) 36 | centroid = v; 37 | return s; 38 | } 39 | 40 | void dfs(int v, int size, int depth, int last) { 41 | int centroid = -1; 42 | dfsCounting(v, size, centroid); 43 | level[centroid] = depth; 44 | centroidDecomp[centroid] = last; 45 | for (auto to: edges[centroid]) 46 | if (level[to] == -1) 47 | dfs(to, size / 2, depth + 1, centroid); 48 | } 49 | 50 | void solve() { 51 | dfs(0, n, 0, -1); 52 | } 53 | 54 | void output() { 55 | for (int i = 0; i < n; ++i) 56 | out << centroidDecomp[i] + 1<< " "; 57 | } 58 | 59 | int main() { 60 | input(); 61 | solve(); 62 | output(); 63 | return 0; 64 | } -------------------------------------------------------------------------------- /term3/Decomp/E/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | #define in cin 8 | #define out cout 9 | 10 | //ifstream in("input.txt"); 11 | //ofstream out("output.txt"); 12 | 13 | int n, m; 14 | int MAX_N = 2*100000 + 50; 15 | vector< vector > edges(MAX_N); 16 | vector centroidDecomp(MAX_N); 17 | vector level(MAX_N, -1); 18 | void input() { 19 | in >> n; 20 | int v, u; 21 | for (int i = 0; i < n - 1; ++i) { 22 | in >> v >> u; 23 | --v; 24 | --u; 25 | edges[v].push_back(u); 26 | edges[u].push_back(v); 27 | } 28 | } 29 | 30 | int dfsCounting(int v, int size, int ¢roid, int p = -1) { 31 | int s = 1; 32 | for (auto to: edges[v]) 33 | if (level[to] == -1 && to != p) 34 | s += dfsCounting(to, size, centroid, v); 35 | if (centroid == -1 && (2 * s >= size || p == -1)) 36 | centroid = v; 37 | return s; 38 | } 39 | 40 | void dfs(int v, int size, int depth, int last) { 41 | int centroid = -1; 42 | dfsCounting(v, size, centroid); 43 | level[centroid] = depth; 44 | centroidDecomp[centroid] = last; 45 | for (auto to: edges[centroid]) 46 | if (level[to] == -1) 47 | dfs(to, size / 2, depth + 1, centroid); 48 | } 49 | 50 | void solve() { 51 | dfs(0, n, 0, -1); 52 | } 53 | 54 | void output() { 55 | for (int i = 0; i < n; ++i) 56 | out << centroidDecomp[i] + 1<< " "; 57 | } 58 | 59 | int main() { 60 | input(); 61 | solve(); 62 | output(); 63 | return 0; 64 | } -------------------------------------------------------------------------------- /term2/Graphs/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | string fileName = "topsort"; 10 | ofstream out(fileName + ".out"); 11 | ifstream in(fileName + ".in"); 12 | int n, m; 13 | unsigned int MAX_N = 100 * 1000; 14 | vector> edges(MAX_N); 15 | vector color(MAX_N, 0); 16 | vector was(MAX_N, false); 17 | vector ans; 18 | 19 | void input() { 20 | in >> n >> m; 21 | for (int i = 0; i < m; ++i) { 22 | int x, y; 23 | in >> x >> y; 24 | edges[x - 1].push_back(y - 1); 25 | } 26 | } 27 | 28 | void output() { 29 | reverse(ans.begin(), ans.end()); 30 | for (auto i: ans) out << i + 1 << " "; 31 | } 32 | 33 | void dfs(int v) { 34 | was[v] = true; 35 | for (auto to: edges[v]) { 36 | if (!was[to]) 37 | dfs(to); 38 | } 39 | ans.push_back(v); 40 | } 41 | 42 | void solve() { 43 | for (int i = 0; i < n; ++i) 44 | if (!was[i]) 45 | dfs(i); 46 | output(); 47 | } 48 | 49 | 50 | bool cdfs(int v) { 51 | color[v] = 1; 52 | bool b = true; 53 | for (auto i: edges[v]) { 54 | if (color[i] == 0) 55 | b = cdfs(i); 56 | if (!b) return b; 57 | if (color[i] == 1) return false; 58 | } 59 | color[v] = 2; 60 | return b; 61 | } 62 | 63 | bool check() { 64 | for (int i = 0; i < n; ++i) 65 | if (color[i] == 0) 66 | if (!cdfs(i)) return false; 67 | return true; 68 | } 69 | 70 | int main() { 71 | input(); 72 | if (check()) solve(); 73 | else out << "-1"; 74 | return 0; 75 | } -------------------------------------------------------------------------------- /term2/Shortest paths/B.cpp: -------------------------------------------------------------------------------- 1 | // Created by Walingar on 06.03.2017. 2 | // 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | long long n, m, s, f; 13 | const unsigned long long MAX_N = 2017; 14 | using namespace std; 15 | ifstream in("pathmgep.in"); 16 | ofstream out("pathmgep.out"); 17 | long long ans = 0; 18 | 19 | vector>> edges(MAX_N); 20 | 21 | 22 | void input() { 23 | in >> n >> s >> f; 24 | --s; 25 | --f; 26 | m = 0; 27 | for (long long i = 0; i < n; ++i) 28 | for (long long j = 0; j < n; ++j) { 29 | long long temp; 30 | in >> temp; 31 | if (temp != 0 && temp != -1) { 32 | edges[i].push_back({j, temp}); 33 | } 34 | } 35 | } 36 | 37 | vector d(MAX_N, LLONG_MAX); 38 | 39 | void solve() { 40 | d[s] = 0; 41 | vector was(MAX_N, false); 42 | for (long long i = 0; i < n; ++i) { 43 | long long v = -1; 44 | for (long long j = 0; j < n; ++j) 45 | if (!was[j] && (v == -1 || d[j] < d[v])) 46 | v = j; 47 | if (d[v] == LLONG_MAX) 48 | break; 49 | was[v] = true; 50 | for (auto to: edges[v]) 51 | if (d[v] + to.second < d[to.first]) 52 | d[to.first] = d[v] + to.second; 53 | } 54 | } 55 | 56 | void output() { 57 | if (d[f] == LLONG_MAX) d[f] = -1; 58 | out << d[f]; 59 | } 60 | 61 | int main() { 62 | input(); 63 | solve(); 64 | output(); 65 | return 0; 66 | } -------------------------------------------------------------------------------- /term2/Shortest paths/D.cpp: -------------------------------------------------------------------------------- 1 | // Created by Walingar on 06.03.2017. 2 | // 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | int n, m, s, f; 13 | const unsigned int MAX_N = 30017; 14 | using namespace std; 15 | ifstream in("pathbgep.in"); 16 | ofstream out("pathbgep.out"); 17 | int ans = 0; 18 | 19 | vector>> edges(MAX_N); 20 | set> q; 21 | 22 | void input() { 23 | in >> n >> m; 24 | for (int i = 0; i < m; ++i) { 25 | int from, to, w; 26 | in >> from >> to >> w; 27 | --from; 28 | --to; 29 | edges[from].push_back({to, w}); 30 | edges[to].push_back({from, w}); 31 | } 32 | m *= 2; 33 | } 34 | 35 | vector d(MAX_N, INT_MAX); 36 | 37 | void solve() { 38 | s = 0; 39 | d[s] = 0; 40 | q.insert({0, s}); 41 | while (!q.empty()) { 42 | int v = (*q.begin()).second; 43 | int w = (*q.begin()).first; 44 | q.erase((*q.begin())); 45 | if (w != d[v]) 46 | continue; 47 | if (d[v] == INT_MAX) 48 | break; 49 | for (auto to: edges[v]) 50 | if (d[v] + to.second < d[to.first]) { 51 | d[to.first] = d[v] + to.second; 52 | q.insert({d[to.first], to.first}); 53 | } 54 | } 55 | } 56 | 57 | void output() { 58 | for (int f = 0; f < n; ++f) { 59 | if (d[f] == INT_MAX) d[f] = -1; 60 | out << d[f] << " "; 61 | } 62 | 63 | } 64 | 65 | int main() { 66 | input(); 67 | solve(); 68 | output(); 69 | return 0; 70 | } -------------------------------------------------------------------------------- /term1/linear_structures/I.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | std::ofstream out("bureaucracy.out"); 8 | std::ifstream in("bureaucracy.in"); 9 | int main() 10 | { 11 | std::queue a; 12 | int n, m; 13 | in >> n >> m; 14 | int min = INT_MAX; 15 | int minus = 0; 16 | for (int i = 0; i < n; i++) 17 | { 18 | int temp; 19 | in >> temp; 20 | a.push(temp); 21 | } 22 | while (a.size() > 0 && m/a.size() !=0 ){ 23 | int t = a.size(); 24 | int now = m/a.size(); 25 | for (int i = 0; i < t; i++){ 26 | int temp = a.front(); 27 | a.pop(); 28 | if (temp - now > 0){ 29 | a.push(temp - now); 30 | } 31 | if (temp - now < 0) m -= temp - now; 32 | } 33 | m -= now*t; 34 | } 35 | if (a.size() == 0){ 36 | out << -1; 37 | } 38 | else 39 | { 40 | for (int i = 0; i < m ; i++) 41 | { 42 | int temp = a.front(); 43 | a.pop(); 44 | if (temp - 1 >0) a.push(temp-1); 45 | } 46 | if (a.size() == 0){ 47 | out << -1; 48 | out.close(); 49 | return 0; 50 | } 51 | out << a.size() << "\n"; 52 | int t = a.size(); 53 | for (int i = 0; i < t ; i++) 54 | { 55 | int temp = a.front(); 56 | a.pop(); 57 | out << temp << " "; 58 | } 59 | } 60 | in.close(); 61 | out.close(); 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /term2/Dynamic programming/F.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Walingar on 06.03.2017. 3 | // 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | int n; 12 | int dp[2001][2001]; 13 | std::string s; 14 | std::ifstream in("palindrome.in"); 15 | std::ofstream out("palindrome.out"); 16 | std::string ans = ""; 17 | 18 | int counting(int l, int r) { 19 | if (dp[l][r] == -1) { 20 | if (s[l] == s[r]) { 21 | dp[l][r] = counting(l + 1, r - 1) + 2; 22 | //ans += s[l]; 23 | } else { 24 | dp[l][r] = std::max(counting(l + 1, r), counting(l, r - 1)); 25 | } 26 | } 27 | return dp[l][r]; 28 | } 29 | 30 | std::string getAns(int l, int r) { 31 | if (l <= r && dp[l][r] != -1) { 32 | if (s[l] == s[r]) { 33 | if (l == r) { 34 | return s[r] + std::string(); 35 | } else { 36 | return s[l] + getAns(l + 1, r - 1) + s[l]; 37 | } 38 | } 39 | if (dp[l][r] == dp[l + 1][r]) { 40 | return getAns(l + 1, r); 41 | } else { 42 | return getAns(l, r - 1); 43 | } 44 | } 45 | return ""; 46 | } 47 | 48 | int main() { 49 | in >> s; 50 | n = s.length(); 51 | for (int i = 0; i < n + 1; ++i) { 52 | for (int j = 0; j < n + 1; ++j) { 53 | dp[i][j] = -1; 54 | if (i > j) { 55 | dp[i][j] = 0; 56 | } 57 | } 58 | dp[i][i] = 1; 59 | } 60 | out << counting(0, n - 1) << "\n"; 61 | 62 | out << getAns(0, n - 1); 63 | in.close(); 64 | out.close(); 65 | return 0; 66 | } -------------------------------------------------------------------------------- /term2/Dynamic programming/K.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | struct task { 16 | int s, p, t, n; 17 | 18 | task(int x, int y, int z, int l) { 19 | s = x; 20 | p = y; 21 | t = z; 22 | n = l; 23 | } 24 | }; 25 | 26 | const unsigned int MAX_N = 1000000; 27 | const unsigned int MAX_M = 3 * 100000; 28 | string s; 29 | string p; 30 | vector dp(MAX_M, -1); 31 | vector d; 32 | vector was; 33 | vector tasks; 34 | int n, T, R0, k, m; 35 | int a, b, l, x, y, r; 36 | 37 | ifstream in("ski.in"); 38 | ofstream out("ski.out"); 39 | 40 | 41 | void input() { 42 | in >> n >> k >> m; 43 | for (int i = 0; i < m; ++i) { 44 | int temp; 45 | in >> temp; 46 | d.push_back(temp); 47 | } 48 | d.push_back(n + 1); 49 | sort(d.begin(), d.end()); 50 | dp[0] = 0; 51 | dp[m] = 0; 52 | } 53 | 54 | int ans; 55 | 56 | void solve() { 57 | for (int i = m - 1; i > -1; --i) { 58 | l = upper_bound(d.begin(), d.end() - 1, d[i] + k - 1) - d.begin(); 59 | dp[i] = max(dp[i], dp[l] + d[l] - min(d[i] + k - 1, n) - 1); 60 | } 61 | ans = (dp[0] += d[0] - 1); 62 | for (int i = 0; i < m; ++i) 63 | if (d[i] - k < 0) 64 | ans = max(ans, dp[i + 1] + d[i + 1] - d[i] - 1); 65 | } 66 | 67 | void output() { 68 | out << ans; 69 | } 70 | 71 | int main() { 72 | input(); 73 | solve(); 74 | output(); 75 | in.close(); 76 | out.close(); 77 | } -------------------------------------------------------------------------------- /term2/Graphs/L.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | string fileName = "hamiltonian"; 10 | ofstream out(fileName + ".out"); 11 | ifstream in(fileName + ".in"); 12 | int n, m; 13 | unsigned int MAX_N = 100 * 1000; 14 | vector> edges(MAX_N); 15 | vector color(MAX_N, 0); 16 | vector was(MAX_N, false); 17 | vector ans; 18 | 19 | void input() { 20 | in >> n >> m; 21 | for (int i = 0; i < m; ++i) { 22 | int x, y; 23 | in >> x >> y; 24 | edges[x - 1].push_back(y - 1); 25 | } 26 | } 27 | 28 | bool check() { 29 | reverse(ans.begin(), ans.end()); 30 | for (int i = 0; i < ans.size() - 1; ++i) { 31 | bool temp = false; 32 | for (auto j: edges[ans[i]]) { 33 | if (j == ans[i + 1]) temp = true; 34 | } 35 | if (!temp) return false; 36 | } 37 | return true; 38 | } 39 | 40 | 41 | void dfs(int v) { 42 | was[v] = true; 43 | for (auto to: edges[v]) { 44 | if (!was[to]) 45 | dfs(to); 46 | } 47 | ans.push_back(v); 48 | } 49 | 50 | void solve() { 51 | for (int i = 0; i < n; ++i) 52 | if (!was[i]) 53 | dfs(i); 54 | if (check()) out << "YES"; 55 | else out << "NO"; 56 | //output(); 57 | } 58 | 59 | 60 | bool cdfs(int v) { 61 | color[v] = 1; 62 | bool b = true; 63 | for (auto i: edges[v]) { 64 | if (color[i] == 0) 65 | b = cdfs(i); 66 | if (!b) return b; 67 | if (color[i] == 1) return false; 68 | } 69 | color[v] = 2; 70 | return b; 71 | } 72 | 73 | 74 | int main() { 75 | input(); 76 | solve(); 77 | return 0; 78 | } -------------------------------------------------------------------------------- /term2/Dynamic programming/C.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Walingar on 06.03.2017. 3 | // 4 | #include 5 | #include 6 | #include 7 | #include 8 | int n, m; 9 | 10 | int main() { 11 | std::ifstream in("knapsack.in"); 12 | std::ofstream out("knapsack.out"); 13 | in >> n; 14 | in >> m; 15 | int c[n]; 16 | int w[n]; 17 | int dp[n + 1][m + 1]; 18 | for (int i = 0; i < n; ++i) { 19 | in >> w[i]; 20 | } 21 | for (int i = 0; i < n; ++i) { 22 | in >> c[i]; 23 | } 24 | for (int i = 0; i <= m; ++i) { 25 | dp[0][i] = 0; 26 | } 27 | for (int i = 0; i <= n; ++i) { 28 | dp[i][0] = 0; 29 | } 30 | for (int i = 1; i <= n; ++i) { 31 | for (int j = 1; j <= m; ++j) { 32 | dp[i][j] = dp[i - 1][j]; 33 | if (j >= w[i - 1] && (dp[i - 1][j - w[i - 1]] + c[i - 1] > dp[i][j])) { 34 | dp[i][j] = dp[i - 1][j - w[i - 1]] + c[i - 1]; 35 | } 36 | } 37 | } 38 | //int ans = 0; 39 | /*for (int i = 0; i <= m; ++i) { 40 | if (ans < dp[n][i]) { 41 | ans = dp[n][i]; 42 | } 43 | }*/ 44 | /*for (int i = 0; i <= n; ++i) { 45 | for (int j = 0; j <= m; ++j) { 46 | out << dp[i][j] << " "; 47 | } 48 | out <<'\n'; 49 | }*/ 50 | int i = n; 51 | int j = m; 52 | std::vector ans; 53 | while (dp[i][j] != 0) { 54 | if (dp[i - 1][j] == dp[i][j]) { 55 | --i; 56 | } else { 57 | j -= w[i - 1]; 58 | ans.push_back(i--); 59 | } 60 | } 61 | out << ans.size() << '\n'; 62 | for(int i = ans.size() - 1; i > -1; --i) { 63 | out << ans[i] << " "; 64 | } 65 | in.close(); 66 | out.close(); 67 | return 0; 68 | } -------------------------------------------------------------------------------- /term2/Dynamic programming/M.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | struct task { 16 | int s, p, t, n; 17 | 18 | task(int x, int y, int z, int l) { 19 | s = x; 20 | p = y; 21 | t = z; 22 | n = l; 23 | } 24 | }; 25 | 26 | const unsigned int MAX_N = 155; 27 | string s; 28 | string p; 29 | vector> dp(MAX_N, vector(MAX_N, 0)); 30 | vector was; 31 | vector tasks; 32 | int n, T, R0; 33 | int a, b, l, x, y; 34 | int leftSide = 0, rightSide = 2 * MAX_N * MAX_N; 35 | ifstream in("bridge.in"); 36 | ofstream out("bridge.out"); 37 | 38 | 39 | void input() { 40 | in >> x >> a >> y >> b >> l; 41 | } 42 | 43 | 44 | void solve() { 45 | while (leftSide + 1 < rightSide) { 46 | dp.assign(MAX_N, vector(MAX_N, 0)); 47 | int m = (leftSide + rightSide) / 2; 48 | int p = 0; 49 | for (int i = 0; i <= x; i++) 50 | for (int j = 0; j <= y; j++) { 51 | for (int k = 0; k <= i; k++) { 52 | int t = 0; 53 | if (m - k * a + b - 1 > 0) t = m - k * a + b - 1; 54 | if (j - t / b >= 0 && dp[i][j] < dp[i - k][j - t / b] + 1) dp[i][j] = dp[i - k][j - t / b] + 1; 55 | } 56 | if (p < dp[i][j]) p = dp[i][j]; 57 | } 58 | if (p >= l) 59 | leftSide = m; 60 | else 61 | rightSide = m; 62 | } 63 | } 64 | 65 | void output() { 66 | out << leftSide; 67 | } 68 | 69 | int main() { 70 | input(); 71 | solve(); 72 | output(); 73 | in.close(); 74 | out.close(); 75 | } -------------------------------------------------------------------------------- /term2/Dynamic programming/E.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Walingar on 06.03.2017. 3 | // 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | int n; 12 | long long dp[501][501]; 13 | int a[501]; 14 | int p[501][501]; 15 | std::ifstream in("matrix.in"); 16 | std::ofstream out("matrix.out"); 17 | struct matrix { 18 | int a; 19 | int b; 20 | }; 21 | std::string ans; 22 | 23 | long long counting(int l, int r) { 24 | if (dp[l][r] == -1) { 25 | if (l == r - 1) { 26 | return 0; 27 | } else { 28 | dp[l][r] = LONG_LONG_MAX; 29 | int min = 501; 30 | for (int i = l + 1; i < r; ++i) { 31 | if (dp[l][r] > counting(l, i) + counting(i, r) + a[l] * a[i] * a[r]) { 32 | dp[l][r] = counting(l, i) + counting(i, r) + a[l] * a[i] * a[r]; 33 | p[l][r] = i; 34 | } 35 | } 36 | } 37 | } 38 | return dp[l][r]; 39 | } 40 | 41 | std::string getAns(int l, int r) { 42 | if (l == r - 1) { 43 | return "A"; 44 | } else { 45 | return ("(" + getAns(l, p[l][r]) + getAns(p[l][r], r) + ")"); 46 | } 47 | } 48 | 49 | int main() { 50 | in >> n; 51 | matrix arr[n]; 52 | for (int i = 0; i < n; ++i) { 53 | in >> arr[i].a >> arr[i].b; 54 | } 55 | for (int i = 0; i < n + 1; ++i) { 56 | for (int j = 0; j < n + 1; ++j) { 57 | dp[i][j] = -1; 58 | } 59 | dp[i][i] = 0; 60 | } 61 | a[0] = arr[0].a; 62 | //out << a[0] << " "; 63 | for (int i = 0; i < n + 1; ++i) { 64 | a[i + 1] = arr[i].b; 65 | //out << a[i] << " "; 66 | } 67 | 68 | int psdfgsdsf = counting(0, n); 69 | out << getAns(0, n); 70 | in.close(); 71 | out.close(); 72 | return 0; 73 | } -------------------------------------------------------------------------------- /term1/trees/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | int inf = 1000 * 1000 * 1000; 6 | int min(std::vector &t, int L, int R, int l, int r, int v) { 7 | if (r < L || l > R ) { 8 | return inf; 9 | } 10 | if (L == R) { 11 | return t[v]; 12 | } 13 | int m = (L + R) / 2; 14 | if (L >= l && R <= r) { 15 | return t[v]; 16 | } 17 | else { 18 | return std::min(min(t, L, m, l, r, 2 * v + 1), min(t, m + 1, R, l, r, 2 * v + 2)); 19 | } 20 | } 21 | void set(std::vector &t, int L, int R, int pos, int val, int v) { 22 | if (L == R) { 23 | t[v] = val; 24 | } 25 | else { 26 | int m = (L + R) / 2; 27 | if (L <= pos && pos <= m) { 28 | set(t, L, m, pos, val, 2 * v + 1); 29 | } 30 | else if (m+1 <= pos && pos <= R) { 31 | set(t, m+1, R, pos, val, 2 * v + 2); 32 | } 33 | t[v] = std::min(t[2 * v + 1], t[2 * v + 2]); 34 | } 35 | 36 | } 37 | void build(std::vector &a, std::vector &t, int L, int R, int v) { 38 | if (L == R) { 39 | t[v] = a[L]; 40 | } 41 | else { 42 | int m = (L + R) / 2; 43 | build(a, t, L, m, 2 * v + 1); 44 | build(a, t, m + 1, R, 2 * v + 2); 45 | t[v] = std::min(t[2 * v + 1], t[2 * v + 2]); 46 | } 47 | } 48 | int main() 49 | { 50 | std::ifstream in("rmq.in"); 51 | std::ofstream out("rmq.out"); 52 | int n; 53 | in >> n; 54 | std::vector a(n); 55 | std::vector t(4*n,inf); 56 | for (int i = 0; i < n; i++) { 57 | in >> a[i]; 58 | } 59 | build(a, t, 0, n - 1, 0); 60 | std::string s; 61 | while (in >> s) 62 | { 63 | if (s == "min") { 64 | int x, y; 65 | in >> x >> y; 66 | out << min(t, 0, n - 1, x - 1, y - 1, 0) << "\n"; 67 | } 68 | else { 69 | int x, y; 70 | in >> x >> y; 71 | set(t, 0, n - 1, x - 1, y, 0); 72 | } 73 | } 74 | in.close(); 75 | out.close(); 76 | return 0; 77 | } -------------------------------------------------------------------------------- /term4/Crypto/D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const string file_name = "mincost"; 5 | 6 | #define inp cin 7 | #define out cout 8 | 9 | //ifstream inp(file_name + ".in"); 10 | //ofstream out(file_name + ".out"); 11 | 12 | const int SQRT_MAX_N = 100000; 13 | const int S = 50000; 14 | bool first_primes[SQRT_MAX_N], block[S]; 15 | int block_primes[SQRT_MAX_N]; 16 | 17 | int mul(int a, int n) { 18 | int r = 0; 19 | while (n > 0) { 20 | if (n % 2 == 1) 21 | r = r + a; 22 | a = a + a; 23 | n /= 2; 24 | } 25 | return r; 26 | } 27 | 28 | void input() { 29 | int n, x, h = 0, count = 0; 30 | scanf("%d", &n); 31 | scanf("%d", &x); 32 | 33 | auto n_sqrt = (int) sqrt(n); 34 | for (int i = 2; i <= n_sqrt; ++i) 35 | if (!first_primes[i]) { 36 | block_primes[count++] = i; 37 | long long sqr = i * 1ll * i; 38 | if (sqr <= n_sqrt) 39 | for (long long j = sqr; j <= n_sqrt; j += i) 40 | first_primes[j] = true; 41 | } 42 | int max_k = n / S; 43 | for (int k = 0; k <= max_k; ++k) { 44 | memset(block, 0, sizeof(block)); 45 | int start = k * S; 46 | for (int i = 0; i < count; ++i) { 47 | int start_idx = (start + block_primes[i] - 1) / block_primes[i]; 48 | if (start_idx < 2) { 49 | start_idx = 2; 50 | } 51 | for (int j = start_idx * block_primes[i] - start; j < S; j += block_primes[i]) 52 | block[j] = true; 53 | } 54 | if (k == 0) 55 | block[0] = block[1] = true; 56 | for (int i = 0; i < S && start + i <= n; ++i) 57 | if (!block[i]) 58 | h = mul(h, x) + i + k * S; 59 | } 60 | 61 | printf("%d", h); 62 | } 63 | 64 | 65 | int main() { 66 | input(); 67 | return 0; 68 | } -------------------------------------------------------------------------------- /term3/LCA/H/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | string fileName = "ancestor"; 10 | ofstream out(fileName + ".out"); 11 | ifstream in(fileName + ".in"); 12 | int n, l, m; 13 | int maxN = 100000 + 50; 14 | vector tin(maxN), tout(maxN); 15 | int timer = 0; 16 | vector > up(maxN); 17 | int root = 0; 18 | 19 | vector> edges(maxN); 20 | 21 | bool upper(int v, int u) { 22 | return (tin[v] <= tin[u] && tout[v] >= tout[u]); 23 | } 24 | 25 | 26 | int lca(int v, int u) { 27 | if (upper(v, u)) return v; 28 | if (upper(u, v)) return u; 29 | for (int i = l; i >= 0; --i) 30 | if (!upper(up[v][i], u)) 31 | v = up[v][i]; 32 | return up[v][0]; 33 | } 34 | 35 | void dfs(int v, int p = 0) { 36 | tin[v] = ++timer; 37 | up[v][0] = p; 38 | for (int i = 1; i <= l; ++i) 39 | up[v][i] = up[up[v][i - 1]][i - 1]; 40 | for (auto to: edges[v]) 41 | dfs(to, v); 42 | tout[v] = ++timer; 43 | } 44 | 45 | void input() { 46 | in >> n; 47 | for (int i = 0; i < n; ++i) { 48 | int v; 49 | in >> v; 50 | if (v == 0) 51 | root = i; 52 | else { 53 | --v; 54 | edges[v].push_back(i); 55 | } 56 | } 57 | } 58 | 59 | void output() { 60 | in >> m; 61 | for (int i = 0; i < m; ++i) { 62 | int v, u; 63 | in >> v >> u; 64 | int ans = lca(v - 1, u - 1); 65 | if (upper(v - 1, u - 1)) 66 | out << 1 << "\n"; 67 | else out << 0 << "\n"; 68 | } 69 | } 70 | 71 | void solve() { 72 | l = 1; 73 | while ((1 << l) <= n) ++l; 74 | ++l; 75 | for (int i = 0; i < n; ++i) up[i].resize(l + 1); 76 | dfs(root); 77 | } 78 | 79 | 80 | int main() { 81 | input(); 82 | solve(); 83 | output(); 84 | return 0; 85 | } -------------------------------------------------------------------------------- /term1/linear_structures/J.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | std::ofstream out("kenobi.out"); 9 | std::ifstream in("kenobi.in"); 10 | std::vector > a(2); 11 | int now = 0; 12 | 13 | void add(int x){ 14 | a[now].push_front(x); 15 | if (a[now].size() - 2 == a[(now + 1) % 2].size()) { 16 | a[(now + 1) % 2].push_front(a[now].back()); 17 | a[now].pop_back(); 18 | } 19 | } 20 | 21 | void take(){ 22 | if (a[now].size() == 0) return; 23 | a[now].pop_front(); 24 | if (a[now].size() < a[(now + 1) % 2].size()) { 25 | a[now].push_back(a[(now + 1) % 2].front()); 26 | a[(now + 1) % 2].pop_front(); 27 | } 28 | } 29 | 30 | void mother(){ 31 | if (a[now].size() == 0) return; 32 | now = (now + 1) % 2; 33 | if (a[now].size() < a[(now + 1) % 2].size()) { 34 | a[now].push_back(a[(now + 1) % 2].front()); 35 | a[(now + 1) % 2].pop_front(); 36 | } 37 | } 38 | 39 | 40 | int main() 41 | { 42 | int n; 43 | in >> n; 44 | std::string s; 45 | for (int i = 0; i < n; i++){ 46 | in >> s; 47 | if (s == "add"){ 48 | int x; 49 | in >> x; 50 | add(x); 51 | } 52 | else if (s == "take"){ 53 | take(); 54 | } 55 | else{ 56 | mother(); 57 | } 58 | } 59 | out << a[0].size() + a[1].size() << "\n"; 60 | if (a[0].size() + a[1].size() == 0) return 0; 61 | while (a[(now + 1) % 2].size()!=0) { 62 | out << a[(now + 1) % 2].back() << " "; 63 | a[(now + 1) % 2].pop_back(); 64 | } 65 | while (a[now].size() > 1) { 66 | out << a[now].back() << " "; 67 | a[now].pop_back(); 68 | } 69 | out << a[now].back() << "\n"; 70 | in.close(); 71 | out.close(); 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /term2/Graphs/D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | string fileName = "cycle"; 10 | ofstream out(fileName + ".out"); 11 | ifstream in(fileName + ".in"); 12 | int n, m; 13 | unsigned int MAX_N = 100 * 1000; 14 | vector> edges(MAX_N); 15 | vector color(MAX_N, 0); 16 | vector was(MAX_N, false); 17 | vector ans; 18 | vector path(MAX_N, -1); 19 | int start, finish; 20 | 21 | void input() { 22 | in >> n >> m; 23 | for (int i = 0; i < m; ++i) { 24 | int x, y; 25 | in >> x >> y; 26 | edges[x - 1].push_back(y - 1); 27 | } 28 | } 29 | 30 | void output() { 31 | out << "YES" << "\n"; 32 | vector cycle; 33 | for (int v = finish; v != start; v = path[v]) 34 | cycle.push_back(v + 1); 35 | cycle.push_back(start + 1); 36 | reverse(cycle.begin(), cycle.end()); 37 | for(auto i:cycle) out << i << " "; 38 | } 39 | 40 | void dfs(int v) { 41 | was[v] = true; 42 | for (auto to: edges[v]) { 43 | if (!was[to]) 44 | dfs(to); 45 | } 46 | ans.push_back(v); 47 | } 48 | 49 | void solve() { 50 | for (int i = 0; i < n; ++i) 51 | if (!was[i]) 52 | dfs(i); 53 | output(); 54 | } 55 | 56 | 57 | bool cdfs(int v) { 58 | color[v] = 1; 59 | bool b = true; 60 | for (auto i: edges[v]) { 61 | if (color[i] == 0) { 62 | path[i] = v; 63 | if (!cdfs(i)) return false; 64 | } else if (color[i] == 1) { 65 | start = i; 66 | finish = v; 67 | return false; 68 | } 69 | } 70 | color[v] = 2; 71 | return true; 72 | } 73 | 74 | bool check() { 75 | for (int i = 0; i < n; ++i) 76 | if (color[i] == 0) 77 | if (!cdfs(i)) return false; 78 | return true; 79 | } 80 | 81 | int main() { 82 | input(); 83 | if (!check()) output(); 84 | else out << "NO"; 85 | return 0; 86 | } -------------------------------------------------------------------------------- /term1/trees/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | long long inf = 0; 6 | long long min(std::vector &t, long long L, long long R, long long l, long long r, long long v) { 7 | if (r < L || l > R ) { 8 | return inf; 9 | } 10 | if (L == R) { 11 | return t[v]; 12 | } 13 | long long m = (L + R) / 2; 14 | if (L >= l && R <= r) { 15 | return t[v]; 16 | } 17 | else { 18 | return min(t, L, m, l, r, 2 * v + 1) + min(t, m + 1, R, l, r, 2 * v + 2); 19 | } 20 | } 21 | void set(std::vector &t, long long L, long long R, long long pos, long long val, long long v) { 22 | if (L == R) { 23 | t[v] = val; 24 | } 25 | else { 26 | long long m = (L + R) / 2; 27 | if (L <= pos && pos <= m) { 28 | set(t, L, m, pos, val, 2 * v + 1); 29 | } 30 | else if (m+1 <= pos && pos <= R) { 31 | set(t, m+1, R, pos, val, 2 * v + 2); 32 | } 33 | t[v] = t[2 * v + 1] + t[2 * v + 2]; 34 | } 35 | 36 | } 37 | void build(std::vector &a, std::vector &t, long long L, long long R, long long v) { 38 | if (L == R) { 39 | t[v] = a[L]; 40 | } 41 | else { 42 | long long m = (L + R) / 2; 43 | build(a, t, L, m, 2 * v + 1); 44 | build(a, t, m + 1, R, 2 * v + 2); 45 | t[v] = t[2 * v + 1] + t[2 * v + 2]; 46 | } 47 | } 48 | int main() 49 | { 50 | std::ifstream in("rsq.in"); 51 | std::ofstream out("rsq.out"); 52 | long long n; 53 | in >> n; 54 | std::vector a(n); 55 | std::vector t(4*n,inf); 56 | for (long long i = 0; i < n; i++) { 57 | in >> a[i]; 58 | } 59 | build(a, t, 0, n - 1, 0); 60 | std::string s; 61 | while (in >> s) 62 | { 63 | if (s == "sum") { 64 | long long x, y; 65 | in >> x >> y; 66 | out << min(t, 0, n - 1, x - 1, y - 1, 0) << "\n"; 67 | } 68 | else { 69 | long long x, y; 70 | in >> x >> y; 71 | set(t, 0, n - 1, x - 1, y, 0); 72 | } 73 | } 74 | in.close(); 75 | out.close(); 76 | return 0; 77 | } -------------------------------------------------------------------------------- /term2/Dynamic programming/H.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Walingar on 06.03.2017. 3 | // 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | long long n, m; 12 | long long dp[1 << 19][19]; 13 | std::string s; 14 | std::ifstream in("salesman.in"); 15 | std::ofstream out("salesman.out"); 16 | long long ans = 3.5e9; 17 | 18 | struct Line { 19 | long long to; 20 | long long w; 21 | 22 | Line(long long TO, long long W) { 23 | to = TO; 24 | w = W; 25 | } 26 | }; 27 | 28 | int main() { 29 | in >> n >> m; 30 | std::vector Lines[19]; 31 | for (long long i = 0; i < m; ++i) { 32 | long long from, to; 33 | long long w; 34 | in >> from >> to >> w; 35 | Lines[--from].push_back(Line(--to, w)); 36 | Lines[to].push_back(Line(from, w)); 37 | } 38 | for (long long i = 0; i < 1 << n; ++i) { 39 | for (long long v = 0; v < n; ++v) { 40 | dp[i][v] = 3.5e9; 41 | } 42 | } 43 | for (long long i = 0; i < n; ++i) { 44 | dp[1 << i][i] = 0; 45 | } 46 | //dp[0][0] = 0; 47 | for (long long i = 0; i < 1 << n; ++i) { 48 | for (long long v = 0; v < n; ++v) { 49 | if (i & (1 << v)) { 50 | for (long long k = 0; k < Lines[v].size(); ++k) { 51 | long long nowTo = Lines[v][k].to; 52 | long long nowW = Lines[v][k].w; 53 | if (!(i & (1 << nowTo))) { 54 | if (dp[i + (1 << nowTo)][nowTo] > dp[i][v] + nowW) { 55 | dp[i + (1 << nowTo)][nowTo] = dp[i][v] + nowW; 56 | } 57 | } 58 | } 59 | } 60 | } 61 | } 62 | for (long long i = 0; i < n; ++i) { 63 | if (ans > dp[(1 << n) - 1][i]) { 64 | ans = dp[(1 << n) - 1][i]; 65 | } 66 | } 67 | if (ans == 3.5e9) ans = -1; 68 | out << ans; 69 | return 0; 70 | } -------------------------------------------------------------------------------- /term3/LCA/B/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | string fileName = "lca"; 10 | ofstream out(fileName + ".out"); 11 | ifstream in(fileName + ".in"); 12 | int n = 1, l, m; 13 | int maxN = 500000 + 50; 14 | int maxM = 500000 + 50; 15 | vector > g; 16 | vector tin, tout; 17 | int timer; 18 | vector > up; 19 | 20 | vector> edges(maxN); 21 | 22 | bool upper(int v, int u) { 23 | return (tin[v] <= tin[u] && tout[v] >= tout[u]); 24 | } 25 | 26 | 27 | int lca(int v, int u) { 28 | if (upper(v, u)) return v; 29 | if (upper(u, v)) return u; 30 | for (int i = l; i >= 0; --i) 31 | if (!upper(up[v][i], u)) 32 | v = up[v][i]; 33 | return up[v][0]; 34 | } 35 | 36 | void dfs(int v, int p = 0) { 37 | tin[v] = ++timer; 38 | up[v][0] = p; 39 | for (int i = 1; i <= l; ++i) 40 | up[v][i] = up[up[v][i - 1]][i - 1]; 41 | for (auto to: edges[v]) 42 | dfs(to, v); 43 | tout[v] = ++timer; 44 | } 45 | 46 | vector> req; 47 | 48 | void input() { 49 | in >> m; 50 | for (int i = 0; i < m; ++i) { 51 | string s; 52 | in >> s; 53 | if (s == "ADD") { 54 | n++; 55 | int v, u; 56 | in >> v >> u; 57 | --v; 58 | --u; 59 | edges[v].push_back(u); 60 | } else { 61 | int v, u; 62 | in >> v >> u; 63 | --v; 64 | --u; 65 | req.push_back({v, u}); 66 | } 67 | } 68 | } 69 | 70 | void output() { 71 | for (auto i : req) { 72 | out << lca(i.first, i.second) + 1 << "\n"; 73 | } 74 | } 75 | 76 | void solve() { 77 | tin.resize(n), tout.resize(n), up.resize(n); 78 | l = 1; 79 | while ((1 << l) <= n) ++l; 80 | for (int i = 0; i < n; ++i) up[i].resize(l + 1); 81 | dfs(0); 82 | } 83 | 84 | 85 | int main() { 86 | input(); 87 | solve(); 88 | output(); 89 | return 0; 90 | } -------------------------------------------------------------------------------- /term4/Crypto/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const string file_name = "assignment"; 5 | 6 | #define inp cin 7 | #define out cout 8 | 9 | //ifstream inp(file_name + ".in"); 10 | //ofstream out(file_name + ".out"); 11 | 12 | const long long MAX_N = 1000000000000000000 + 5; 13 | long long n; 14 | 15 | long long mul(long long a, long long n, long long m) { 16 | long long r = 0; 17 | while (n > 0) { 18 | if (n % 2 == 1) 19 | r = (r + a) % m; 20 | a = (a + a) % m; 21 | n /= 2; 22 | } 23 | return r; 24 | } 25 | 26 | long long pow(long long a, long long n, long long m) { 27 | long long res = 1; 28 | while (n > 0) { 29 | if ((n & 1) > 0) 30 | res = mul(res, a, m); 31 | a = mul(a, a, m); 32 | n >>= 1; 33 | } 34 | return res; 35 | } 36 | 37 | bool prime(long long val, long long mod) { 38 | if (val == 2 || n == 3) { 39 | return true; 40 | } 41 | 42 | if (val == 1 || val % 2 == 0) { 43 | return false; 44 | } 45 | 46 | long long p = 0, q = val - 1; 47 | 48 | while (q % 2 == 0) { 49 | ++p; 50 | q /= 2; 51 | } 52 | 53 | for (int i = 0; i < 9; i++) { 54 | long long a = (rand() % (val - 2)) + 2; 55 | long long x = pow(a, q, val); 56 | 57 | if (x == 1 || x == val - 1) 58 | continue; 59 | 60 | for (int j = 1; j < p; ++j) { 61 | x = mul(x, x, val); 62 | if (x == 1) 63 | return false; 64 | if (x == val - 1) 65 | break; 66 | } 67 | 68 | if (x != val - 1) 69 | return false; 70 | } 71 | 72 | return true; 73 | } 74 | 75 | 76 | void input() { 77 | srand(NULL); 78 | inp >> n; 79 | long long val; 80 | for (int i = 0; i < n; ++i) { 81 | scanf("%lld", &val); 82 | if (prime(val, 2)) { 83 | printf("YES\n"); 84 | } else { 85 | printf("NO\n"); 86 | } 87 | } 88 | } 89 | 90 | 91 | int main() { 92 | input(); 93 | return 0; 94 | } -------------------------------------------------------------------------------- /term2/Graphs/E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | string fileName = "strong"; 10 | ofstream out(fileName + ".out"); 11 | ifstream in(fileName + ".in"); 12 | int n, m; 13 | unsigned int MAX_N = 20000; 14 | vector> edges(MAX_N); 15 | vector> edgesBack(MAX_N); 16 | vector color(MAX_N, 0); 17 | vector was(MAX_N, false); 18 | vector component; 19 | vector components(MAX_N, 0); 20 | vector order; 21 | int ans = 0; 22 | vector path(MAX_N, -1); 23 | int start, finish; 24 | 25 | void input() { 26 | in >> n >> m; 27 | for (int i = 0; i < m; ++i) { 28 | int x, y; 29 | in >> x >> y; 30 | edges[x - 1].push_back(y - 1); 31 | edgesBack[y - 1].push_back(x - 1); 32 | } 33 | } 34 | 35 | void output() { 36 | out << ans << "\n"; 37 | for (auto i:components) if (i != 0) out << i << " "; 38 | } 39 | 40 | bool cdfs(int v) { 41 | was[v] = true; 42 | component.push_back(v); 43 | for (auto to: edgesBack[v]) { 44 | if (!was[to]) 45 | cdfs(to); 46 | } 47 | } 48 | 49 | void dfs(int v) { 50 | was[v] = true; 51 | for (auto to: edges[v]) { 52 | if (!was[to]) 53 | dfs(to); 54 | } 55 | order.push_back(v); 56 | //ans.push_back(v); 57 | } 58 | 59 | void solve() { 60 | was.assign(MAX_N, false); 61 | for (int i = 0; i < n; ++i) 62 | if (!was[i]) 63 | dfs(i); 64 | was.assign(MAX_N, false); 65 | for (int i = 0; i < n; ++i) { 66 | int v = order[n - 1 - i]; 67 | if (!was[v]) { 68 | ++ans; 69 | cdfs(v); 70 | for (auto j: component) components[j] = ans; 71 | component.clear(); 72 | } 73 | } 74 | } 75 | 76 | 77 | bool check() { 78 | for (int i = 0; i < n; ++i) 79 | if (color[i] == 0) 80 | if (!cdfs(i)) return false; 81 | return true; 82 | } 83 | 84 | int main() { 85 | input(); 86 | solve(); 87 | output(); 88 | return 0; 89 | } -------------------------------------------------------------------------------- /term2/Graphs/K.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Walingar on 06.03.2017. 3 | // 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | int n, m, fromPos, toPos; 12 | std::string s; 13 | std::ifstream in("shortpath.in"); 14 | std::ofstream out("shortpath.out"); 15 | using namespace std; 16 | 17 | struct edge { 18 | int from; 19 | int to; 20 | int w; 21 | 22 | edge(int x, int y, int z) { 23 | from = x; 24 | to = y; 25 | w = z; 26 | } 27 | }; 28 | 29 | vector> edges; 30 | vector> d; 31 | vector was; 32 | 33 | pair counting(int x) { 34 | //out.print(x + " "); 35 | was[x] = 1; 36 | if (x == fromPos) { 37 | return {0, true}; 38 | } 39 | for (int i = 0; i < edges[x].size(); i++) { 40 | if (was[edges[x][i].to] != 0) { 41 | if (d[x].first > d[edges[x][i].to].first + edges[x][i].w) { 42 | if (d[edges[x][i].to].second || !d[x].second) 43 | d[x] = {d[edges[x][i].to].first + edges[x][i].w, d[edges[x][i].to].second}; 44 | } 45 | } else { 46 | pair temp = counting(edges[x][i].to); 47 | if (temp.second) { 48 | d[x] = {min(d[x].first, temp.first + edges[x][i].w), true}; 49 | } 50 | } 51 | } 52 | was[x] = 2; 53 | return d[x]; 54 | } 55 | 56 | void input() { 57 | in >> n >> m >> fromPos >> toPos; 58 | --fromPos; 59 | --toPos; 60 | for (int i = 0; i < n; i++) { 61 | vector temp; 62 | edges.push_back(temp); 63 | d.push_back({INT_MAX, false}); 64 | was.push_back(0); 65 | } 66 | d[fromPos] = {0, true}; 67 | for (int i = 0; i < m; i++) { 68 | int x, y, z; 69 | in >> x >> y >> z; 70 | --x, --y; 71 | edges[y].push_back(edge(y, x, z)); 72 | } 73 | } 74 | 75 | int main() { 76 | int n, m; 77 | input(); 78 | pair j = counting(toPos); 79 | if (j.second) { 80 | out << j.first; 81 | } else { 82 | out << "Unreachable"; 83 | } 84 | return 0; 85 | } -------------------------------------------------------------------------------- /term1/trees/D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | struct matr{ 6 | matr():a11(1),a12(0),a21(0),a22(1){}; 7 | int a11; 8 | int a12; 9 | int a21; 10 | int a22; 11 | }; 12 | matr I0; 13 | matr mult(matr a,matr b,int r){ 14 | matr ans; 15 | ans.a11 = ((a.a11*b.a11)%r + (a.a12 * b.a21)%r)%r; 16 | ans.a12 = ((a.a11*b.a12)%r + (a.a12 * b.a22)%r) % r; 17 | ans.a21 = ((a.a21*b.a11)%r + (a.a22 * b.a21)%r) % r; 18 | ans.a22 = ((a.a21*b.a12)%r + (a.a22 * b.a22)%r) % r; 19 | return ans; 20 | } 21 | matr count(std::vector &t, int L, int R, int l, int r, int v,int mod) { 22 | if (r < L || l > R ) { 23 | return I0; 24 | } 25 | if (L == R) { 26 | return t[v]; 27 | } 28 | int m = (L + R) / 2; 29 | if (L >= l && R <= r) { 30 | return t[v]; 31 | } 32 | else { 33 | return mult(count(t, L, m, l, r, 2 * v + 1, mod), count(t, m + 1, R, l, r, 2 * v + 2, mod), mod); 34 | } 35 | } 36 | 37 | void build(std::vector &a, std::vector &t, int L, int R, int v,int r) { 38 | if (L == R) { 39 | t[v] = a[L]; 40 | } 41 | else { 42 | int m = (L + R) / 2; 43 | build(a, t, L, m, 2 * v + 1, r); 44 | build(a, t, m + 1, R, 2 * v + 2, r); 45 | t[v] = mult(t[2 * v + 1], t[2 * v + 2], r); 46 | } 47 | } 48 | 49 | int main() 50 | { 51 | std::ifstream in("crypto.in"); 52 | std::ofstream out("crypto.out"); 53 | int r, n, m; 54 | in >> r >> n >> m; 55 | std::vector a(n); 56 | std::vector t(4*n, I0); 57 | for (int i = 0; i < n; i++){ 58 | matr p; 59 | in >> p.a11 >> p.a12 >> p.a21 >> p.a22; 60 | a[i] = p; 61 | } 62 | build(a, t, 0, n-1, 0, r); 63 | for (int i = 0; i < m; i++){ 64 | int x,y; 65 | in >> x >> y; 66 | matr temp = count(t,0,n-1,x-1,y-1,0,r); 67 | out << temp.a11 << " " << temp.a12 << "\n"; 68 | out << temp.a21 << " " << temp.a22 << "\n"; 69 | out << "\n"; 70 | } 71 | in.close(); 72 | out.close(); 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /term2/Shortest paths/F.cpp: -------------------------------------------------------------------------------- 1 | // Created by Walingar on 06.03.2017. 2 | // 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | long long n, m, s, f; 10 | const unsigned long long MAX_N = 260; 11 | using namespace std; 12 | ifstream in("negcycle.in"); 13 | ofstream out("negcycle.out"); 14 | long long ans = 0; 15 | 16 | struct edge { 17 | long long from, to, w; 18 | 19 | edge(long long x, long long y, long long z) { 20 | from = x; 21 | to = y; 22 | w = z; 23 | } 24 | }; 25 | 26 | vector edges; 27 | 28 | void input() { 29 | in >> n; 30 | m = 0; 31 | for (long long i = 0; i < n; ++i) 32 | for (long long j = 0; j < n; ++j) { 33 | long long temp; 34 | in >> temp; 35 | if (temp != 1000 * 1000 * 1000) { 36 | edges.push_back(edge(i, j, temp)); 37 | ++m; 38 | } 39 | } 40 | 41 | } 42 | 43 | long long INF = LLONG_MAX / 2; 44 | 45 | vector d(MAX_N, 0); 46 | vector path(MAX_N, -1); 47 | vector p; 48 | void solve() { 49 | long long was = -1; 50 | for (long long i = 0; i < n; ++i) { 51 | was = -1; 52 | for (long long j = 0; j < m; ++j) 53 | if (d[edges[j].to] > d[edges[j].from] + edges[j].w) { 54 | d[edges[j].to] = max(-INF, d[edges[j].from] + edges[j].w); 55 | path[edges[j].to] = edges[j].from; 56 | was = edges[j].to; 57 | } 58 | } 59 | 60 | if (was == -1) { 61 | out << "NO"; 62 | exit(0); 63 | } else { 64 | long long y = was; 65 | for (long long i = 0; i < n; ++i) 66 | y = path[y]; 67 | for (long long cur = y;; cur = path[cur]) { 68 | p.push_back(cur); 69 | if (cur == y && p.size() > 1) break; 70 | } 71 | } 72 | 73 | } 74 | 75 | void output() { 76 | reverse(p.begin(), p.end()); 77 | out << "YES" << "\n"; 78 | out << p.size() << "\n"; 79 | for (auto i : p) out << i + 1 << ' '; 80 | } 81 | 82 | int main() { 83 | input(); 84 | solve(); 85 | output(); 86 | return 0; 87 | } -------------------------------------------------------------------------------- /term1/heap_sort/I.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | vector > a; 10 | double l; 11 | double res(double time) 12 | { 13 | double ans = 0; 14 | double now = 0; 15 | for (int i = 0; i < a.size(); i++) 16 | { 17 | if (now + a[i].first < time) 18 | { 19 | now += a[i].first; 20 | ans += a[i].second * a[i].first; 21 | } 22 | else 23 | { 24 | ans += (time - now)*a[i].second; 25 | break; 26 | } 27 | } 28 | return ans; 29 | } 30 | bool prov(double m) 31 | { 32 | double p = 0; 33 | double s = 0; 34 | for (int i = 0; i < a.size(); i++) 35 | { 36 | s+=a[i].first; 37 | } 38 | for (int i = 0; i < a.size(); i++) 39 | { 40 | p += a[i].first; 41 | if(p >= m) 42 | { 43 | double l1 = res(p) - res(p-m); 44 | double l2 = res(p + m) - res(p); 45 | if (p + m > s) l2 = l; 46 | if (l1 < l || l2 < l) 47 | { 48 | return false; 49 | } 50 | } 51 | } 52 | double temp1 = res(m); 53 | if (temp1 < l) 54 | { 55 | return false; 56 | } 57 | return true; 58 | } 59 | 60 | double search_ans() 61 | { 62 | double r = 0, left = 0; 63 | for (int i = 0; i < a.size(); i++) 64 | { 65 | r += a[i].first; 66 | } 67 | while (r - left>0.00001) 68 | { 69 | double m = left + (r - left) / 2; 70 | if (prov(m)) 71 | { 72 | r = m; 73 | } 74 | else 75 | { 76 | left = m; 77 | } 78 | } 79 | return r; 80 | } 81 | 82 | int main() 83 | { 84 | ofstream fout("trains.out"); 85 | ifstream fin("trains.in"); 86 | fin >> l; 87 | int n; 88 | fin >> n; 89 | for (int i = 0; i < n; i++) 90 | { 91 | double temp1, temp2; 92 | fin >> temp1 >> temp2; 93 | a.push_back(make_pair(temp1, temp2)); 94 | } 95 | fout << fixed; 96 | fout << setprecision(10) << search_ans(); 97 | fin.close(); 98 | fout.close(); 99 | return 0; 100 | } 101 | -------------------------------------------------------------------------------- /term2/Graphs/G.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | string fileName = "bridges"; 10 | ofstream out(fileName + ".out"); 11 | ifstream in(fileName + ".in"); 12 | int n, m; 13 | const unsigned int MAX_N = 20000; 14 | vector>> edges(MAX_N); 15 | vector> edgesBack(MAX_N); 16 | vector color(MAX_N, 0); 17 | vector was(MAX_N, false); 18 | vector component; 19 | vector components(MAX_N, 0); 20 | vector order; 21 | int timer, tin[MAX_N], tup[MAX_N]; 22 | int ans = 0; 23 | int ans2 = 0; 24 | vector path(MAX_N, -1); 25 | int start, finish; 26 | 27 | void input() { 28 | in >> n >> m; 29 | for (int i = 0; i < m; ++i) { 30 | int x, y; 31 | in >> x >> y; 32 | edges[x - 1].push_back({y - 1, i + 1}); 33 | edges[y - 1].push_back({x - 1, i + 1}); 34 | } 35 | } 36 | 37 | void output() { 38 | out << ans << "\n"; 39 | sort(component.begin(), component.end()); 40 | for (auto i: component) out << i << " "; 41 | } 42 | 43 | bool cdfs(int v) { 44 | was[v] = true; 45 | component.push_back(v); 46 | for (auto to: edgesBack[v]) { 47 | if (!was[to]) 48 | cdfs(to); 49 | } 50 | } 51 | 52 | void add(int v, int to) { 53 | ans++; 54 | for (auto i: edges[v]){ 55 | if (i.first == to) component.push_back(i.second); 56 | } 57 | 58 | } 59 | 60 | void dfs(int v, int p) { 61 | was[v] = true; 62 | tin[v] = tup[v] = timer++; 63 | for (auto to: edges[v]) { 64 | if (to.first == p) continue; 65 | if (was[to.first]) tup[v] = min(tin[to.first], tup[v]); 66 | else { 67 | dfs(to.first, v); 68 | tup[v] = min(tup[to.first], tup[v]); 69 | if (tup[to.first] > tin[v]) add(v, to.first); 70 | } 71 | } 72 | } 73 | 74 | void solve() { 75 | timer = 0; 76 | for (int i = 0; i < n; ++i) 77 | if (!was[i]) dfs(i, -1); 78 | } 79 | 80 | 81 | bool check() { 82 | for (int i = 0; i < n; ++i) 83 | if (color[i] == 0) 84 | if (!cdfs(i)) return false; 85 | return true; 86 | } 87 | 88 | int main() { 89 | input(); 90 | solve(); 91 | output(); 92 | return 0; 93 | } -------------------------------------------------------------------------------- /term2/Dynamic programming/I.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | struct task { 16 | int s, p, t, n; 17 | 18 | task(int x, int y, int z, int l) { 19 | s = x; 20 | p = y; 21 | t = z; 22 | n = l; 23 | } 24 | }; 25 | 26 | string s; 27 | string p; 28 | vector> dp; 29 | vector was; 30 | vector tasks; 31 | int n, T, R0; 32 | 33 | ifstream in("practice.in"); 34 | ofstream out("practice.out"); 35 | 36 | 37 | void input() { 38 | in >> n >> T >> R0; 39 | for (int i = 0; i < n; ++i) { 40 | int x, y, z; 41 | in >> x >> y >> z; 42 | task temp(x, y, z, i + 1); 43 | tasks.push_back(temp); 44 | } 45 | sort(tasks.begin(), tasks.end(), [](task &a, task &b) { return a.s < b.s; }); 46 | dp.assign(n + 2, vector(T + 2, R0)); 47 | for (int i = 0; i <= T; ++i) { 48 | dp[0][i] = R0; 49 | } 50 | for (int i = 0; i <= n; ++i) { 51 | dp[i][0] = R0; 52 | } 53 | 54 | } 55 | 56 | 57 | void solve() { 58 | for (int i = 1; i <= n; ++i) 59 | for (int j = 1; j <= T; ++j) { 60 | dp[i][j] = dp[i - 1][j]; 61 | if (j >= tasks[i - 1].t && 62 | (dp[i - 1][j - tasks[i - 1].t] + tasks[i - 1].p > dp[i][j]) && 63 | dp[i - 1][j - tasks[i - 1].t] >= tasks[i - 1].s) 64 | 65 | dp[i][j] = dp[i - 1][j - tasks[i - 1].t] + tasks[i - 1].p; 66 | } 67 | } 68 | 69 | void output() { 70 | int i = n; 71 | int j = T; 72 | std::vector ans; 73 | while (dp[i][j] != R0) { 74 | if (dp[i - 1][j] == dp[i][j]) { 75 | --i; 76 | } else { 77 | j -= tasks[i - 1].t; 78 | ans.push_back(tasks[i - 1].n); 79 | --i; 80 | } 81 | } 82 | out << dp[n][T] << '\n'; 83 | for (int i = ans.size() - 1; i > -1; --i) { 84 | out << ans[i] << " "; 85 | } 86 | } 87 | 88 | int main() { 89 | input(); 90 | solve(); 91 | output(); 92 | in.close(); 93 | out.close(); 94 | } -------------------------------------------------------------------------------- /term2/Shortest paths/E.cpp: -------------------------------------------------------------------------------- 1 | // Created by Walingar on 06.03.2017. 2 | // 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | long long n, m, s, f; 9 | const unsigned long long MAX_N = 2017; 10 | using namespace std; 11 | ifstream in("path.in"); 12 | ofstream out("path.out"); 13 | long long ans = 0; 14 | 15 | struct edge { 16 | long long from, to, w; 17 | 18 | edge(long long x, long long y, long long z) { 19 | from = x; 20 | to = y; 21 | w = z; 22 | } 23 | }; 24 | 25 | vector edges; 26 | vector> edgesDFS(MAX_N); 27 | 28 | void input() { 29 | in >> n >> m >> s; 30 | --s; 31 | for (long long i = 0; i < m; ++i) { 32 | long long from, to, w; 33 | in >> from >> to >> w; 34 | --from; 35 | --to; 36 | edges.push_back(edge(from, to, w)); 37 | edgesDFS[from].push_back(to); 38 | } 39 | } 40 | 41 | long long INF = LLONG_MAX / 2; 42 | 43 | vector d(MAX_N, INF); 44 | vector ok(MAX_N, true); 45 | vector was(MAX_N); 46 | 47 | void reset() { 48 | for (long long i = 0; i < n; ++i) { 49 | was[i] = false; 50 | } 51 | } 52 | 53 | void dfs(long long v) { 54 | was[v] = true; 55 | ok[v] = false; 56 | for (auto to: edgesDFS[v]) { 57 | if (!was[to]) 58 | dfs(to); 59 | } 60 | } 61 | 62 | 63 | 64 | void solve() { 65 | d[s] = 0; 66 | long long x; 67 | for (long long i = 0; i < n; ++i) { 68 | for (long long j = 0; j < m; ++j) 69 | if (d[edges[j].from] < INF) { 70 | if (d[edges[j].to] > d[edges[j].from] + edges[j].w) { 71 | d[edges[j].to] = max(-INF, d[edges[j].from] + edges[j].w); 72 | if (i == n - 1) { 73 | reset(); 74 | dfs(edges[j].to); 75 | } 76 | } 77 | } 78 | } 79 | } 80 | 81 | void output() { 82 | for (long long i = 0; i < n; ++i) { 83 | if (d[i] == INF) out << "*" << "\n"; 84 | else if (!ok[i]) out << "-" << "\n"; 85 | else out << d[i] << "\n"; 86 | } 87 | } 88 | 89 | int main() { 90 | input(); 91 | solve(); 92 | output(); 93 | return 0; 94 | } -------------------------------------------------------------------------------- /term2/Graphs/H.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | string fileName = "points"; 10 | ofstream out(fileName + ".out"); 11 | ifstream in(fileName + ".in"); 12 | int n, m; 13 | const unsigned int MAX_N = 20000; 14 | vector>> edges(MAX_N); 15 | vector> edgesBack(MAX_N); 16 | vector color(MAX_N, 0); 17 | vector was(MAX_N, false); 18 | vector component; 19 | vector components(MAX_N, 0); 20 | vector order; 21 | int timer, tin[MAX_N], tup[MAX_N]; 22 | int ans = 0; 23 | int ans2 = 0; 24 | vector path(MAX_N, -1); 25 | int start, finish; 26 | 27 | void input() { 28 | in >> n >> m; 29 | for (int i = 0; i < m; ++i) { 30 | int x, y; 31 | in >> x >> y; 32 | edges[x - 1].push_back({y - 1, i + 1}); 33 | edges[y - 1].push_back({x - 1, i + 1}); 34 | } 35 | } 36 | 37 | void output() { 38 | out << component.size() << "\n"; 39 | sort(component.begin(), component.end()); 40 | for (auto i: component) out << i << " "; 41 | } 42 | 43 | bool cdfs(int v) { 44 | was[v] = true; 45 | component.push_back(v); 46 | for (auto to: edgesBack[v]) { 47 | if (!was[to]) 48 | cdfs(to); 49 | } 50 | } 51 | 52 | void add(int v) { 53 | if (find(component.begin(), component.end(), v + 1) == component.end()) component.push_back(v + 1); 54 | } 55 | 56 | void dfs(int v, int p) { 57 | was[v] = true; 58 | tin[v] = tup[v] = timer++; 59 | int count = 0; 60 | for (auto to: edges[v]) { 61 | if (to.first == p) continue; 62 | if (was[to.first]) tup[v] = min(tin[to.first], tup[v]); 63 | else { 64 | dfs(to.first, v); 65 | tup[v] = min(tup[to.first], tup[v]); 66 | if (tup[to.first] >= tin[v] && p != -1) add(v); 67 | ++count; 68 | } 69 | } 70 | if (p == -1 && count > 1) 71 | add(v); 72 | } 73 | 74 | void solve() { 75 | timer = 0; 76 | for (int i = 0; i < n; ++i) 77 | if (!was[i]) dfs(i, -1); 78 | } 79 | 80 | 81 | bool check() { 82 | for (int i = 0; i < n; ++i) 83 | if (color[i] == 0) 84 | if (!cdfs(i)) return false; 85 | return true; 86 | } 87 | 88 | int main() { 89 | input(); 90 | solve(); 91 | output(); 92 | return 0; 93 | } -------------------------------------------------------------------------------- /term2/Graphs/I.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | string fileName = "fire"; 10 | ofstream out(fileName + ".out"); 11 | ifstream in(fileName + ".in"); 12 | int n, m; 13 | unsigned int MAX_N = 20000; 14 | vector> edges(MAX_N); 15 | vector> edgesBack(MAX_N); 16 | vector color(MAX_N, 0); 17 | vector was(MAX_N, false); 18 | vector component; 19 | vector components(MAX_N, 0); 20 | vector order; 21 | int ans = 0; 22 | vector path(MAX_N, -1); 23 | int start, finish; 24 | int ans1 = 0, ans2 = 0; 25 | 26 | void input() { 27 | in >> n >> m; 28 | for (int i = 0; i < m; ++i) { 29 | int x, y; 30 | in >> x >> y; 31 | edges[x - 1].push_back(y - 1); 32 | edgesBack[y - 1].push_back(x - 1); 33 | } 34 | } 35 | 36 | void output() { 37 | //vector> edges((unsigned int) ans); 38 | vector stay((unsigned int)ans, true); 39 | for (int i = 0; i < n; i++) 40 | for (auto to: edges[i]) { 41 | if (components[i] != components[to]) { 42 | if (stay[components[to] - 1]) { 43 | stay[components[i] - 1] = false; 44 | stay[components[to] - 1] = true; 45 | } else stay[components[i] - 1] = false; 46 | 47 | } 48 | } 49 | for (int i = 0; i < ans; i++) { 50 | if (stay[i]) ++ans2; 51 | } 52 | out << ans2; 53 | } 54 | 55 | bool cdfs(int v) { 56 | was[v] = true; 57 | component.push_back(v); 58 | for (auto to: edgesBack[v]) { 59 | if (!was[to]) 60 | cdfs(to); 61 | } 62 | } 63 | 64 | void dfs(int v) { 65 | was[v] = true; 66 | for (auto to: edges[v]) { 67 | if (!was[to]) 68 | dfs(to); 69 | } 70 | order.push_back(v); 71 | //ans.push_back(v); 72 | } 73 | 74 | void solve() { 75 | for (int i = 0; i < n; ++i) 76 | if (!was[i]) 77 | dfs(i); 78 | was.assign(MAX_N, false); 79 | for (int i = 0; i < n; ++i) { 80 | int v = order[n - 1 - i]; 81 | if (!was[v]) { 82 | ++ans; 83 | cdfs(v); 84 | for (auto j: component) components[j] = ans; 85 | component.clear(); 86 | } 87 | } 88 | } 89 | 90 | int main() { 91 | input(); 92 | solve(); 93 | output(); 94 | return 0; 95 | } -------------------------------------------------------------------------------- /term4/Flow and Matching/J.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define INF 10000000000 4 | 5 | using namespace std; 6 | int n, w; 7 | auto dist = vector(10000, INF); 8 | 9 | struct rect { 10 | rect() { 11 | 12 | } 13 | 14 | rect(long long x1, long long y1, long long x2, long long y2) : x1(x1), y1(y1), x2(x2), y2(y2) { 15 | 16 | } 17 | 18 | long long x1; 19 | long long x2; 20 | long long y1; 21 | long long y2; 22 | }; 23 | 24 | long long distGet(rect r1, rect r2) { 25 | long long h = (r1.x1 <= r2.x1) ? r2.x1 - r1.x2 : r1.x1 - r2.x2; 26 | long long v = (r1.y1 <= r2.y1) ? r2.y1 - r1.y2 : r1.y1 - r2.y2; 27 | long long ans = max(h, v); 28 | if (ans < 0) { 29 | ans = 0; 30 | } 31 | return ans; 32 | } 33 | 34 | auto was = vector(10000, false); 35 | 36 | void dijkstra(vector> &vertex) { 37 | dist[0] = 0; 38 | for (int i = 0; i < n + 2; ++i) { 39 | long long v = -1; 40 | for (int j = 0; j < n + 2; ++j) { 41 | if (!was[j] && (v == -1 || dist[j] < dist[v])) { 42 | v = j; 43 | } 44 | } 45 | was[v] = true; 46 | for (int u = 0; u < n + 2; ++u) { 47 | if (v != u) { 48 | long long d = vertex[v][u]; 49 | if (dist[v] + d < dist[u]) { 50 | dist[u] = dist[v] + d; 51 | } 52 | } 53 | } 54 | } 55 | } 56 | 57 | int main() { 58 | scanf("%d %d", &n, &w); 59 | auto vertex = vector>(n + 2, vector(n + 2)); 60 | auto rectangles = vector(n); 61 | for (int i = 0; i < n; ++i) { 62 | long long x1, y1, x2, y2; 63 | scanf("%lld %lld %lld %lld", &x1, &y1, &x2, &y2); 64 | rectangles[i] = rect(x1, y1, x2, y2); 65 | } 66 | vertex[0][n + 1] = w; 67 | vertex[n + 1][0] = w; 68 | for (int i = 0; i < n; ++i) { 69 | rect cur_rect = rectangles[i]; 70 | long long min_y = min(cur_rect.y1, cur_rect.y2); 71 | long long max_y = max(cur_rect.y1, cur_rect.y2); 72 | vertex[0][i + 1] = vertex[i + 1][0] = w - max_y; 73 | vertex[n + 1][i + 1] = vertex[i + 1][n + 1] = min_y; 74 | for (int j = 0; j < n; ++j) { 75 | if (i != j) { 76 | vertex[i + 1][j + 1] = vertex[j + 1][i + 1] = distGet(cur_rect, rectangles[j]); 77 | } 78 | } 79 | } 80 | dijkstra(vertex); 81 | printf("%lld", (dist[n + 1] == INF) ? 0 : dist[n + 1]); 82 | return 0; 83 | } -------------------------------------------------------------------------------- /term1/trees/F.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | int inf = 1000 * 1000 * 1000; 7 | std::vector pos(1000 * 1000); 8 | int search(std::vector &t, int L, int R, int l, int r, int v) { 9 | if (r < L || l > R) { 10 | return inf; 11 | } 12 | if (t[v] == 1) { 13 | return inf; 14 | } 15 | 16 | if (L == R) { 17 | if (t[v] == 0) { 18 | return pos[v]; 19 | } 20 | else { 21 | return inf; 22 | } 23 | } 24 | int m = (L + R) / 2; 25 | int ans = search(t, L, m, l, r, 2 * v + 1); 26 | if (ans == inf) ans = search(t, m + 1, R, l, r, 2 * v + 2); 27 | return ans; 28 | } 29 | void set(std::vector &t, int L, int R, int pos, int val, int v) { 30 | if (L == R) { 31 | t[v] = val; 32 | } 33 | else { 34 | int m = (L + R) / 2; 35 | if (L <= pos && pos <= m) { 36 | set(t, L, m, pos, val, 2 * v + 1); 37 | } 38 | else if (m + 1 <= pos && pos <= R) { 39 | set(t, m + 1, R, pos, val, 2 * v + 2); 40 | } 41 | t[v] = std::min(t[2 * v + 1], t[2 * v + 2]); 42 | } 43 | } 44 | void build(std::vector &a, std::vector &t, int L, int R, int v) { 45 | if (L == R) { 46 | t[v] = a[L]; 47 | pos[v] = L; 48 | } 49 | else { 50 | int m = (L + R) / 2; 51 | build(a, t, L, m, 2 * v + 1); 52 | build(a, t, m + 1, R, 2 * v + 2); 53 | t[v] = std::min(t[2 * v + 1], t[2 * v + 2]); 54 | } 55 | } 56 | int main() 57 | { 58 | std::ifstream in("parking.in"); 59 | std::ofstream out("parking.out"); 60 | int n, m; 61 | in >> n >> m; 62 | std::vector a(n, 0); 63 | std::vector t(4 * n, inf); 64 | build(a, t, 0, n - 1, 0); 65 | std::string s; 66 | for (int i = 0; i < m; i++) { 67 | in >> s; 68 | if (s == "enter") { 69 | int x; 70 | in >> x; 71 | int ans = search(t, 0, n - 1, x - 1, n - 1, 0); 72 | if (ans != inf) { 73 | out << ans + 1 << "\n"; 74 | } 75 | else { 76 | ans = search(t, 0, n - 1, 0, x - 1, 0); 77 | out << ans + 1 << "\n"; 78 | } 79 | set(t, 0, n - 1, ans, 1, 0); 80 | } 81 | else { 82 | int ans; 83 | in >> ans; 84 | set(t, 0, n - 1, ans - 1, 0, 0); 85 | } 86 | } 87 | in.close(); 88 | out.close(); 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /term3/Strings/A/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | string s; 15 | int n, m, f; 16 | const unsigned int MAX_N = 100000 + 50; 17 | const long long p_1 = 4; 18 | const long long p_2 = 9; 19 | vector pref_hash_1(MAX_N, 0); 20 | vector pref_hash_2(MAX_N, 0); 21 | vector pows_1(MAX_N, 1); 22 | vector pows_2(MAX_N, 1); 23 | 24 | #define in cin 25 | #define out cout 26 | //ifstream in("path.in"); 27 | //ofstream out("path.out"); 28 | 29 | 30 | void input() { 31 | in >> s; 32 | in >> m; 33 | n = (int) s.length(); 34 | } 35 | 36 | void pows() { 37 | for (int i = 1; i < n; ++i) { 38 | pows_1[i] = pows_1[i - 1] * p_1; 39 | pows_2[i] = pows_2[i - 1] * p_2; 40 | } 41 | } 42 | 43 | void get_hash_s() { 44 | for (int i = 0; i < s.length(); ++i) { 45 | if (i != 0) { 46 | pref_hash_1[i] += pref_hash_1[i - 1]; 47 | pref_hash_2[i] += pref_hash_2[i - 1]; 48 | } 49 | pref_hash_1[i] += (s[i] - 'a' + 1) * pows_1[i]; 50 | pref_hash_2[i] += (s[i] - 'a' + 1) * pows_2[i]; 51 | } 52 | } 53 | 54 | 55 | void solve() { 56 | pows(); 57 | get_hash_s(); 58 | 59 | } 60 | 61 | long long hash_1, hash_2; 62 | 63 | bool isSimilar(int a, int b, int c, int d) { 64 | if (a > c) { 65 | swap(a, c); 66 | swap(b, d); 67 | } 68 | if (b - a != d - c) 69 | return false; 70 | long long len = b - a + 1; 71 | 72 | hash_1 = pref_hash_1[a + len - 1]; 73 | if (a) hash_1 -= pref_hash_1[a - 1]; 74 | hash_2 = pref_hash_1[c + len - 1]; 75 | if (c) hash_2 -= pref_hash_1[c - 1]; 76 | 77 | bool ans_1 = hash_1 * pows_1[c - a] == hash_2; 78 | 79 | 80 | hash_1 = pref_hash_2[a + len - 1]; 81 | if (a) hash_1 -= pref_hash_2[a - 1]; 82 | hash_2 = pref_hash_2[c + len - 1]; 83 | if (c) hash_2 -= pref_hash_2[c - 1]; 84 | 85 | bool ans_2 = hash_1 * pows_2[c - a] == hash_2; 86 | 87 | return ans_1 && ans_2; 88 | } 89 | 90 | 91 | void output() { 92 | int a, b, c, d; 93 | for (int i = 0; i < m; ++i) { 94 | in >> a >> b >> c >> d; 95 | --a, --b, --c, --d; 96 | out << (isSimilar(a, b, c, d) ? "Yes" : "No") << "\n"; 97 | } 98 | } 99 | 100 | int main() { 101 | input(); 102 | solve(); 103 | output(); 104 | return 0; 105 | } -------------------------------------------------------------------------------- /term2/Graphs/F.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | string fileName = "cond"; 10 | ofstream out(fileName + ".out"); 11 | ifstream in(fileName + ".in"); 12 | int n, m; 13 | unsigned int MAX_N = 20000; 14 | vector> edges(MAX_N); 15 | vector> edgesBack(MAX_N); 16 | vector color(MAX_N, 0); 17 | vector was(MAX_N, false); 18 | vector component; 19 | vector components(MAX_N, 0); 20 | vector order; 21 | int ans = 0; 22 | int ans2 = 0; 23 | vector path(MAX_N, -1); 24 | int start, finish; 25 | 26 | void input() { 27 | in >> n >> m; 28 | for (int i = 0; i < m; ++i) { 29 | int x, y; 30 | in >> x >> y; 31 | edges[x - 1].push_back(y - 1); 32 | edgesBack[y - 1].push_back(x - 1); 33 | } 34 | } 35 | 36 | void output() { 37 | out << ans << " "; 38 | //vector> edges((unsigned int) ans); 39 | vector> a((unsigned int)ans, vector ((unsigned int)ans,0)); 40 | for (int i = 0; i < n; i++) 41 | for (auto to: edges[i]) { 42 | if (a[components[i] - 1][ components[to] - 1] == 0 && components[i] != components[to]) { 43 | ans2++; 44 | a[components[i] - 1][ components[to] - 1] = 1; 45 | } 46 | } 47 | out << ans2; 48 | //for (auto i:components) if (i != 0) out << i << " "; 49 | } 50 | 51 | bool cdfs(int v) { 52 | was[v] = true; 53 | component.push_back(v); 54 | for (auto to: edgesBack[v]) { 55 | if (!was[to]) 56 | cdfs(to); 57 | } 58 | } 59 | 60 | void dfs(int v) { 61 | was[v] = true; 62 | for (auto to: edges[v]) { 63 | if (!was[to]) 64 | dfs(to); 65 | } 66 | order.push_back(v); 67 | //ans.push_back(v); 68 | } 69 | 70 | void solve() { 71 | was.assign(MAX_N, false); 72 | for (int i = 0; i < n; ++i) 73 | if (!was[i]) 74 | dfs(i); 75 | was.assign(MAX_N, false); 76 | for (int i = 0; i < n; ++i) { 77 | int v = order[n - 1 - i]; 78 | if (!was[v]) { 79 | ++ans; 80 | cdfs(v); 81 | for (auto j: component) components[j] = ans; 82 | component.clear(); 83 | } 84 | } 85 | } 86 | 87 | 88 | bool check() { 89 | for (int i = 0; i < n; ++i) 90 | if (color[i] == 0) 91 | if (!cdfs(i)) return false; 92 | return true; 93 | } 94 | 95 | int main() { 96 | input(); 97 | solve(); 98 | output(); 99 | return 0; 100 | } -------------------------------------------------------------------------------- /term1/trees/K.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | int inf = 0; 7 | int summ(std::vector &t, int L, int R, int l, int r, int v) { 8 | if (r < L || l > R) { 9 | return inf; 10 | } 11 | if (L == R) { 12 | return t[v]; 13 | } 14 | int m = (L + R) / 2; 15 | if (L >= l && R <= r) { 16 | return t[v]; 17 | } 18 | else { 19 | return summ(t, L, m, l, r, 2 * v + 1) + summ(t, m + 1, R, l, r, 2 * v + 2); 20 | } 21 | } 22 | void set(std::vector &t, int L, int R, int pos, int val, int v) { 23 | if (L == R) { 24 | t[v] += val; 25 | return; 26 | } 27 | else { 28 | int m = (L + R) / 2; 29 | if (L <= pos && pos <= m) { 30 | set(t, L, m, pos, val, 2 * v + 1); 31 | } 32 | else if (m + 1 <= pos && pos <= R) { 33 | set(t, m + 1, R, pos, val, 2 * v + 2); 34 | } 35 | t[v] = t[2 * v + 1] + t[2 * v + 2]; 36 | } 37 | 38 | } 39 | struct man { 40 | int come; 41 | int out; 42 | int pos; 43 | }; 44 | struct WhenInOut { 45 | int when; 46 | int t; 47 | man *who; 48 | }; 49 | void rightpos(std::vector &a, std::vector &b) { 50 | for (int i = 0; i < b.size(); i++) { 51 | a.push_back(&b[i]); 52 | } 53 | std::sort(a.begin(), a.end(), [](const man *a, const man *b) { 54 | return (a->out < b->out); 55 | }); 56 | for (int i = 0; i < b.size(); i++) { 57 | a[i]->pos = i; 58 | } 59 | } 60 | int main() 61 | { 62 | std::ifstream in("taxibus.in"); 63 | std::ofstream out("taxibus.out"); 64 | int n; 65 | in >> n; 66 | std::vector < man > inp(n); 67 | std::vector wio(2 * n); 68 | long long ans = 0; 69 | for (int i = 0; i < n; i++) { 70 | in >> inp[i].come >> inp[i].out; 71 | wio[2 * i].when = inp[i].come; 72 | wio[2 * i].t = 1; 73 | wio[2 * i].who = &inp[i]; 74 | wio[2 * i + 1].when = inp[i].out; 75 | wio[2 * i + 1].t = 0; 76 | wio[2 * i + 1].who = &inp[i]; 77 | } 78 | std::vector inp1; 79 | rightpos(inp1,inp); 80 | std::string answer; 81 | for (int i = 0; i < n; i++) { 82 | answer += std::to_string(inp[i].pos + 1) + " "; 83 | } 84 | std::sort(wio.begin(), wio.end(), [](const WhenInOut& a, const WhenInOut& b) { 85 | return (a.when < b.when); 86 | }); 87 | std::vector t(4 * n, inf); 88 | for (int i = 0; i < 2 * n; i++) { 89 | if (wio[i].t == 1) { 90 | ans += summ(t, 0, n - 1, 0, wio[i].who->pos,0); 91 | set(t, 0, n - 1, wio[i].who->pos, 1, 0); 92 | } 93 | else { 94 | set(t, 0, n - 1, wio[i].who->pos, -1, 0); 95 | } 96 | } 97 | out << ans << "\n" << answer; 98 | in.close(); 99 | out.close(); 100 | return 0; 101 | } 102 | -------------------------------------------------------------------------------- /term3/LCA/F/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | string fileName = "minonpath"; 11 | ofstream out(fileName + ".out"); 12 | ifstream in(fileName + ".in"); 13 | int n, l, m; 14 | int maxN = 50000 + 50; 15 | vector tin, tout; 16 | map, int> wd; 17 | int timer; 18 | vector > up; 19 | vector > w; 20 | vector> edges(maxN); 21 | vector counter; 22 | vector d(maxN); 23 | 24 | bool upper(int v, int u) { 25 | return tin[v] <= tin[u] && tout[v] >= tout[u]; 26 | } 27 | 28 | 29 | int lca(int v, int u) { 30 | if (upper(v, u)) return v; 31 | if (upper(u, v)) return u; 32 | for (int i = l; i >= 0; --i) 33 | if (!upper(up[v][i], u)) 34 | v = up[v][i]; 35 | return up[v][0]; 36 | } 37 | 38 | int depth = 0; 39 | 40 | void dfs(int v, int p = 0) { 41 | tin[v] = ++timer; 42 | up[v][0] = p; 43 | w[v][0] = wd[{v, p}]; 44 | d[v] = depth; 45 | for (int i = 1; i <= l; ++i) { 46 | up[v][i] = up[up[v][i - 1]][i - 1]; 47 | w[v][i] = min(w[v][i - 1], w[up[v][i - 1]][i - 1]); 48 | } 49 | 50 | for (auto to: edges[v]) { 51 | ++depth; 52 | dfs(to, v); 53 | --depth; 54 | } 55 | 56 | tout[v] = ++timer; 57 | } 58 | 59 | void input() { 60 | in >> n; 61 | for (int i = 1; i < n; ++i) { 62 | int v, weight; 63 | in >> v >> weight; 64 | --v; 65 | edges[v].push_back(i); 66 | wd[{v, i}] = weight; 67 | wd[{i, v}] = weight; 68 | } 69 | } 70 | 71 | int go(int v, int u) { 72 | int res = 1000000000; 73 | for (int i = l; i >= 0; --i) { 74 | if (counter[i] <= d[v] - d[u]) { 75 | res = min(res, w[v][i]); 76 | v = up[v][i]; 77 | } 78 | } 79 | return res; 80 | } 81 | 82 | void output() { 83 | in >> m; 84 | for (int i = 0; i < m; ++i) { 85 | int v, u; 86 | in >> v >> u; 87 | --v; 88 | --u; 89 | int x = lca(v, u); 90 | out << min(go(v, x), go(u, x)) << "\n"; 91 | } 92 | } 93 | 94 | void solve() { 95 | tin.resize(n), tout.resize(n), up.resize(n); 96 | w.resize(n); 97 | l = 1; 98 | while ((1 << l) <= n) ++l; 99 | ++l; 100 | for (int i = 0; i <= l; ++i) counter.push_back(1 << i); 101 | for (int i = 0; i < n; ++i) up[i].resize(l + 1); 102 | for (int i = 0; i < n; ++i) w[i].resize(l + 1); 103 | dfs(0); 104 | } 105 | 106 | 107 | int main() { 108 | input(); 109 | solve(); 110 | output(); 111 | return 0; 112 | } -------------------------------------------------------------------------------- /term3/LCA/D/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace std; 11 | 12 | string fileName = "lca3"; 13 | ofstream out(fileName + ".out"); 14 | ifstream in(fileName + ".in"); 15 | int n = 1, l, m, N; 16 | int const maxN = 50000 + 50; 17 | vector> edges(maxN); 18 | vector > up(maxN); 19 | vector timeIn(maxN), timeOut(maxN); 20 | set roots; 21 | vector d(maxN); 22 | vector counter; 23 | 24 | void input() { 25 | in >> N; 26 | for (int i = 0; i < N; ++i) { 27 | int v; 28 | in >> v; 29 | --v; 30 | if (v == -1) 31 | roots.insert(i); 32 | else 33 | edges[v].push_back(i); 34 | } 35 | } 36 | 37 | int depth = 0; 38 | 39 | void dfs(int v, int p = 0) { 40 | up[v][0] = p; 41 | d[v] = depth; 42 | for (int i = 1; i <= l; ++i) 43 | up[v][i] = up[up[v][i - 1]][i - 1]; 44 | for (auto to: edges[v]) { 45 | ++depth; 46 | dfs(to, v); 47 | --depth; 48 | } 49 | 50 | } 51 | 52 | void merge(int v, int u) { 53 | depth = d[v]; 54 | dfs(v, up[v][0]); 55 | } 56 | 57 | int lca(int v, int u) { 58 | if (up[v][l] != up[u][l]) 59 | return -1; 60 | if (d[v] > d[u]) { 61 | int temp = v; 62 | v = u; 63 | u = temp; 64 | } 65 | for (int i = l; i >= 0; --i) 66 | if (d[u] - d[v] >= counter[i]) 67 | u = up[u][i]; 68 | if (v == u) 69 | return v; 70 | for (int i = l; i >= 0; --i) 71 | if (up[v][i] != up[u][i]) { 72 | v = up[v][i]; 73 | u = up[u][i]; 74 | } 75 | return up[v][0]; 76 | } 77 | 78 | void output() { 79 | in >> m; 80 | string s; 81 | int ans = 0, x, y; 82 | for (int i = 0; i < m; ++i) { 83 | in >> s >> x >> y; 84 | int v, u; 85 | u = (x - 1 + ans) % N; 86 | v = (y - 1 + ans) % N; 87 | if (s == "0") { 88 | ans = lca(u, v) + 1; 89 | out << ans << "\n"; 90 | } else { 91 | edges[v].push_back(u); 92 | merge(v, u); 93 | } 94 | } 95 | } 96 | 97 | 98 | void solve() { 99 | l = 1; 100 | while ((1 << l) <= maxN) ++l; 101 | ++l; 102 | for (int i = 0; i <= l; ++i) counter.push_back(1 << i); 103 | for (int i = 0; i < N; ++i) up[i].resize(l + 1); 104 | for (auto i: roots) { 105 | depth = 0; 106 | dfs(i, i); 107 | } 108 | } 109 | 110 | 111 | int main() { 112 | input(); 113 | solve(); 114 | output(); 115 | return 0; 116 | } -------------------------------------------------------------------------------- /term3/LCA/I/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | string fileName = "tree"; 11 | ofstream out(fileName + ".out"); 12 | ifstream in(fileName + ".in"); 13 | int n, l, m; 14 | int maxN = 150000 + 50; 15 | map, int> wd; 16 | vector > up(maxN); 17 | vector > w(maxN); 18 | vector> edges(maxN); 19 | vector counter; 20 | vector d(maxN); 21 | vector was(maxN, false); 22 | 23 | 24 | int lca(int v, int u) { 25 | if (d[v] > d[u]) { 26 | int temp = v; 27 | v = u; 28 | u = temp; 29 | } 30 | for (int i = l; i >= 0; --i) 31 | if (d[u] - d[v] >= counter[i]) 32 | u = up[u][i]; 33 | if (v == u) 34 | return v; 35 | for (int i = l; i >= 0; --i) 36 | if (up[v][i] != up[u][i]) { 37 | v = up[v][i]; 38 | u = up[u][i]; 39 | } 40 | return up[v][0]; 41 | } 42 | 43 | int depth = 0; 44 | 45 | void dfs(int v, int p = 0) { 46 | up[v][0] = p; 47 | was[v] = true; 48 | d[v] = depth; 49 | w[v][0] = wd[{v, p}]; 50 | for (int i = 1; i <= l; ++i) { 51 | up[v][i] = up[up[v][i - 1]][i - 1]; 52 | w[v][i] = w[v][i - 1] + w[up[v][i - 1]][i - 1]; 53 | } 54 | 55 | for (auto to: edges[v]) { 56 | ++depth; 57 | if (!was[to]) 58 | dfs(to, v); 59 | --depth; 60 | } 61 | 62 | } 63 | 64 | void input() { 65 | in >> n; 66 | for (int i = 1; i < n; ++i) { 67 | int v, u, weight; 68 | in >> v >> u >> weight; 69 | edges[v].push_back(u); 70 | edges[u].push_back(v); 71 | wd[{v, u}] = weight; 72 | wd[{u, v}] = weight; 73 | } 74 | } 75 | 76 | int go(int v, int u) { 77 | int res = 0; 78 | for (int i = l; i >= 0; --i) { 79 | if (counter[i] <= d[v] - d[u]) { 80 | res += w[v][i]; 81 | v = up[v][i]; 82 | } 83 | } 84 | return res; 85 | } 86 | 87 | void output() { 88 | in >> m; 89 | for (int i = 0; i < m; ++i) { 90 | int v, u; 91 | in >> v >> u; 92 | int x = lca(v, u); 93 | out << go(v, x) + go(u, x) << "\n"; 94 | } 95 | } 96 | 97 | void solve() { 98 | l = 1; 99 | while ((1 << l) <= n) ++l; 100 | ++l; 101 | for (int i = 0; i <= l; ++i) counter.push_back(1 << i); 102 | for (int i = 0; i < n; ++i) up[i].resize(l + 1); 103 | for (int i = 0; i < n; ++i) w[i].resize(l + 1); 104 | dfs(0); 105 | } 106 | 107 | 108 | int main() { 109 | input(); 110 | solve(); 111 | output(); 112 | return 0; 113 | } -------------------------------------------------------------------------------- /term4/Flow and Matching/D.kt: -------------------------------------------------------------------------------- 1 | import java.io.* 2 | import java.util.* 3 | import kotlin.collections.ArrayList 4 | 5 | 6 | const val fileName = "snails" 7 | const val MAX_V = 250 + 5 8 | const val MAX_E = 250 + 5 9 | const val MAX_C = 10_000 + 5 10 | 11 | class FastScanner(f: InputStream) { 12 | private lateinit var br: BufferedReader 13 | private var st: StringTokenizer? = null 14 | 15 | init { 16 | try { 17 | br = BufferedReader(InputStreamReader(f)) 18 | } catch (e: FileNotFoundException) { 19 | e.printStackTrace() 20 | } 21 | 22 | } 23 | 24 | operator fun next(): String { 25 | while (st == null || !st!!.hasMoreTokens()) { 26 | try { 27 | st = StringTokenizer(br.readLine()) 28 | } catch (e: IOException) { 29 | e.printStackTrace() 30 | } 31 | 32 | } 33 | return st!!.nextToken() 34 | } 35 | 36 | fun nextInt(): Int { 37 | return next().toInt() 38 | } 39 | 40 | fun nextDouble(): Double { 41 | return next().toDouble() 42 | } 43 | } 44 | 45 | //var inp = FastScanner(File("$fileName.in").inputStream()) 46 | //var out = File("$fileName.out").printWriter() 47 | 48 | var inp = FastScanner(System.`in`) 49 | var out = System.out 50 | 51 | val edges = Array>(MAX_V, { ArrayList() }) 52 | var n = 0 53 | var m = 0 54 | 55 | 56 | fun input() { 57 | n = inp.nextInt() 58 | m = inp.nextInt() 59 | for (v in 1..n) { 60 | var u = inp.nextInt() 61 | while (u != 0) { 62 | edges[v].add(u) 63 | u = inp.nextInt() 64 | } 65 | } 66 | } 67 | 68 | val was = Array(MAX_V, { false }) 69 | val matching = IntArray(MAX_V, { -1 }) 70 | 71 | fun kuhn(v: Int): Boolean { 72 | if (was[v]) { 73 | return false 74 | } 75 | was[v] = true 76 | 77 | for (u in edges[v]) { 78 | if (matching[u] == -1 || kuhn(matching[u])) { 79 | matching[u] = v 80 | return true 81 | } 82 | } 83 | return false 84 | } 85 | 86 | var counter = 0 87 | 88 | fun solve() { 89 | for (i in 1..n) { 90 | was.fill(false) 91 | if (kuhn(i)) { 92 | counter++ 93 | } 94 | } 95 | } 96 | 97 | fun output() { 98 | out.println(counter) 99 | for (i in 1..m) { 100 | if (matching[i] != -1) { 101 | out.println(matching[i].toString() + " " + i) 102 | } 103 | } 104 | } 105 | 106 | fun main(args: Array) { 107 | try { 108 | input() 109 | solve() 110 | output() 111 | out.close() 112 | } catch (e: IOException) { 113 | e.printStackTrace() 114 | } 115 | } -------------------------------------------------------------------------------- /term4/Crypto/F.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const string file_name = "mincost"; 5 | 6 | #define inp cin 7 | #define out cout 8 | 9 | //ifstream inp(file_name + ".in"); 10 | //ofstream out(file_name + ".out"); 11 | long long n, m, c, e; 12 | 13 | long long gcd(long long a, long long b, long long &x, long long &y) { 14 | if (a == 0) { 15 | x = 0; 16 | y = 1; 17 | return b; 18 | } 19 | long long x1 = 0, y1 = 0; 20 | long long d = gcd(b % a, a, x1, y1); 21 | x = y1 - (b / a) * x1; 22 | y = x1; 23 | return d; 24 | } 25 | 26 | long long EuclidAdv(long long a, long long m) { 27 | long long x, y; 28 | long long ans = gcd(a, m, x, y); 29 | return (x + m) % m; 30 | } 31 | 32 | int kto(int *a, int *p, int size) { 33 | int r[size][size]; 34 | for (int i = 0; i < size; ++i) 35 | for (int j = i + 1; j < size; ++j) 36 | r[i][j] = EuclidAdv(p[i], p[j]); 37 | 38 | int result = 0; 39 | int mult_p = 1; 40 | int x[size] = {0}; 41 | for (int i = 0; i < 2; ++i) { 42 | x[i] = a[i]; 43 | for (int j = 0; j < i; ++j) { 44 | x[i] = (x[i] - x[j]) * r[j][i]; 45 | x[i] = x[i] % p[i]; 46 | if (x[i] < 0) { 47 | x[i] += p[i]; 48 | } 49 | } 50 | result += mult_p * x[i]; 51 | mult_p *= p[i]; 52 | } 53 | return result; 54 | } 55 | 56 | vector factorization(long long n) { 57 | vector ans; 58 | for (long long i = 2; i <= n; ++i) { 59 | if (n % i == 0) { 60 | ans.push_back(i); 61 | ans.push_back(n / i); 62 | break; 63 | } 64 | } 65 | return ans; 66 | } 67 | 68 | long long gcd(long long a, long long b) { 69 | if (b == 0) 70 | return a; 71 | return gcd(b, a % b); 72 | } 73 | 74 | long long mul(long long a, long long n, long long m) { 75 | long long r = 0; 76 | while (n > 0) { 77 | if (n % 2 == 1) 78 | r = (r + a) % m; 79 | a = (a + a) % m; 80 | n /= 2; 81 | } 82 | return r; 83 | } 84 | 85 | long long pow(long long a, long long n, long long m) { 86 | long long res = 1; 87 | while (n > 0) { 88 | if ((n & 1) > 0) 89 | res = mul(res, a, m); 90 | a = mul(a, a, m); 91 | n >>= 1; 92 | } 93 | return res; 94 | } 95 | 96 | void input() { 97 | inp >> n >> e >> c; 98 | auto factor = factorization(n); 99 | long long phi = (factor[0] - 1) * (factor[1] - 1); 100 | // e*d = 1 mod phi -> e*d + 101 | long long d = EuclidAdv(e, phi); 102 | printf("%lld", pow(c, d, n)); 103 | } 104 | 105 | 106 | int main() { 107 | input(); 108 | return 0; 109 | } -------------------------------------------------------------------------------- /term1/trees/I.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | int inf = std::pow(10, 9) + 1; 7 | int ans = 0; 8 | std::vector d(1000 * 1000, 0); 9 | void propogate(std::vector &t, std::vector &tm, int v) { 10 | t[v * 2 + 1] += d[v]; 11 | t[v * 2 + 2] += d[v]; 12 | tm[v * 2 + 1] += d[v]; 13 | tm[v * 2 + 2] += d[v]; 14 | d[v * 2 + 1] += d[v]; 15 | d[v * 2 + 2] += d[v]; 16 | d[v] = 0; 17 | } 18 | 19 | 20 | void kick(std::vector &t, std::vector &tm, int L, int R, int l, int r, int v, int val) { 21 | if (r < L || R < l) { 22 | return ; 23 | } 24 | if (L == R) { 25 | if (t[v] >= val) { 26 | --t[v]; 27 | --tm[v]; 28 | ++ans; 29 | } 30 | return; 31 | } 32 | if (L >= l && R <= r) { 33 | if (t[v] >= val) { 34 | --t[v]; 35 | --d[v]; 36 | --tm[v]; 37 | ans += R - L + 1; 38 | return; 39 | } 40 | } 41 | propogate(t,tm, v); 42 | int m = (L + R) / 2; 43 | if (tm[2*v + 1] >= val) kick(t, tm, L, m, l, r, 2 * v + 1, val); 44 | if (tm[2*v + 2] >= val) kick(t, tm, m + 1, R, l, r, 2 * v + 2, val); 45 | t[v] = std::min(t[2 * v + 1], t[2 * v + 2]); 46 | tm[v] = std::max(tm[2 * v + 1], tm[2 * v + 2]); 47 | } 48 | void build(std::vector &a, std::vector &t, std::vector &tm, int L, int R, int v) { 49 | if (L == R) { 50 | t[v] = a[L]; 51 | tm[v] = a[L]; 52 | } 53 | else { 54 | int m = (L + R) / 2; 55 | build(a, t, tm, L, m, 2 * v + 1); 56 | build(a, t, tm, m + 1, R, 2 * v + 2); 57 | t[v] = std::min(t[2 * v + 1], t[2 * v + 2]); 58 | tm[v] = std::max(tm[2 * v + 1], tm[2 * v + 2]); 59 | } 60 | } 61 | int main() 62 | { 63 | std::ifstream in("candies.in"); 64 | std::ofstream out("candies.out"); 65 | int n; 66 | in >> n; 67 | std::vector a(n); 68 | std::vector t(4 * n, inf); 69 | std::vector tm(4 * n, 0); 70 | for (int i = 0; i < n; i++) { 71 | in >> a[i]; 72 | } 73 | std::sort(a.begin(), a.end()); 74 | build(a, t, tm, 0, n - 1, 0); 75 | int m; 76 | in >> m; 77 | //int t = 0; 78 | for (int i = 0; i < m; i++) { 79 | int val; 80 | /*++t; 81 | i (t == 1000){ 82 | for (int i = 0; i < n; i++){ 83 | propogate(t,tm,i); 84 | } 85 | build(a, t, tm, 0, n - 1, 0); 86 | }*/ 87 | in >> val; 88 | ans = 0; 89 | kick(t,tm, 0, n - 1, 0, n - 1, 0, val); 90 | out << ans << "\n"; 91 | } 92 | in.close(); 93 | out.close(); 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /term3/Strings/L/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | string t, s; 16 | int n, m, f; 17 | const int END = 256; 18 | const unsigned int MAX_N = 400000 + 50; 19 | vector suff(MAX_N); 20 | vector lcp(MAX_N); 21 | //#define in cin 22 | //#define out cout 23 | ifstream in("shifts.in"); 24 | ofstream out("shifts.out"); 25 | 26 | int get_letter_ind(char ch) { 27 | return ch; 28 | } 29 | 30 | vector classes(MAX_N); 31 | vector classes_temp(MAX_N); 32 | vector suff_temp(MAX_N); 33 | 34 | void build_suff_array() { 35 | vector cnt(END, 0); 36 | for (int i = 0; i < n; ++i) 37 | ++cnt[get_letter_ind(s[i])]; 38 | for (int i = 0; i + 1 < END; ++i) 39 | cnt[i + 1] += cnt[i]; 40 | 41 | for (int i = 0; i < n; ++i) 42 | suff[--cnt[get_letter_ind(s[i])]] = i; 43 | int count = 1; 44 | classes[suff[0]] = 0; 45 | 46 | for (int i = 1; i < n; ++i) { 47 | if (s[suff[i]] != s[suff[i - 1]]) 48 | ++count; 49 | classes[suff[i]] = count - 1; 50 | } 51 | 52 | for (int l = 0; (1 << l) < n; ++l) { 53 | int x = 1 << l; 54 | for (int i = 0; i < n; ++i) { 55 | suff_temp[i] = suff[i] - x; 56 | if (suff_temp[i] < 0) 57 | suff_temp[i] += n; 58 | } 59 | 60 | vector cnt(count, 0); 61 | for (int i = 0; i < n; ++i) 62 | ++cnt[classes[suff_temp[i]]]; 63 | for (int i = 0; i + 1 < count; ++i) 64 | cnt[i + 1] += cnt[i]; 65 | for (int i = n - 1; i > -1; --i) 66 | suff[--cnt[classes[suff_temp[i]]]] = suff_temp[i]; 67 | 68 | count = 1; 69 | classes[suff[0]] = 0; 70 | for (int i = 1; i < n; ++i) { 71 | if (classes[suff[i]] != classes[suff[i - 1]] || 72 | classes[(suff[i] + x) % n] != classes[(suff[i - 1] + x) % n]) 73 | ++count; 74 | classes_temp[suff[i]] = count - 1; 75 | } 76 | classes = classes_temp; 77 | } 78 | for (int i = 0; i < n; ++i) 79 | if (classes[i] == m - 1) { 80 | for (int j = 0; j < n; ++j) 81 | out << s[(j + i) % n]; 82 | exit(0); 83 | } 84 | } 85 | 86 | void input() { 87 | in >> s; 88 | n = (int) s.length(); 89 | in >> m; 90 | } 91 | 92 | void solve() { 93 | build_suff_array(); 94 | } 95 | 96 | void output() { 97 | out << "IMPOSSIBLE"; 98 | 99 | } 100 | 101 | int main() { 102 | input(); 103 | solve(); 104 | output(); 105 | return 0; 106 | } -------------------------------------------------------------------------------- /term3/Strings/F/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | vector strings; 16 | string t, s; 17 | int n, m, f; 18 | string ans_s = ""; 19 | const long long p = 37; 20 | const unsigned int MAX_N = 10000 + 50; 21 | vector pm(MAX_N); 22 | //#define in cin 23 | //#define out cout 24 | ifstream in("substr3.in"); 25 | ofstream out("substr3.out"); 26 | 27 | void input() { 28 | in >> n; 29 | s = ""; 30 | for (int i = 0; i < n; ++i) { 31 | in >> s; 32 | strings.push_back(s); 33 | } 34 | } 35 | 36 | long long get_hash(string &st, int l, int len) { 37 | long long ans = 0; 38 | 39 | for (int i = l; i < l + len; ++i) 40 | ans += (st[i] - 'a' + 1) * pm[i - l]; 41 | 42 | return ans; 43 | } 44 | 45 | set &get_hashes(string &st, int len) { 46 | auto *ans = new set; 47 | for (int i = 0; i <= (int) st.length() - len; ++i) 48 | (*ans).insert(get_hash(st, i, len)); 49 | return *ans; 50 | } 51 | 52 | void GCS() { 53 | int l = 0, r = MAX_N; 54 | for (int i = 0; i < n; ++i) 55 | if (r > strings[i].length()) 56 | r = (int) strings[i].length(); 57 | ++r; 58 | long long ans = 0; 59 | while (r - l > 1) { 60 | int m = (l + r) / 2; 61 | set hashes1 = get_hashes(strings[0], m); 62 | for (int i = 1; i < n; ++i) { 63 | set hashes2 = get_hashes(strings[i], m); 64 | vector temp; 65 | for (auto &hash: hashes1) 66 | if (hashes2.count(hash) == 0) 67 | temp.push_back(hash); 68 | for (auto &hash: temp) 69 | hashes1.erase(hash); 70 | } 71 | if (hashes1.size() == 0) { 72 | r = m; 73 | } else { 74 | l = m; 75 | ans = *hashes1.begin(); 76 | } 77 | } 78 | if (l == 0) { 79 | ans_s = ""; 80 | return; 81 | } 82 | for (int i = 0; i <= strings[0].length() - l; ++i) { 83 | long long hash = get_hash(strings[0], i, l); 84 | if (hash == ans) { 85 | ans_s = strings[0].substr(i, l); 86 | return; 87 | } 88 | } 89 | 90 | } 91 | 92 | void pre_calc() { 93 | pm[0] = 1; 94 | for (int i = 1; i < MAX_N; ++i) 95 | pm[i] = pm[i - 1] * p; 96 | } 97 | 98 | void solve() { 99 | pre_calc(); 100 | } 101 | 102 | void output() { 103 | GCS(); 104 | out << ans_s; 105 | } 106 | 107 | int main() { 108 | input(); 109 | solve(); 110 | output(); 111 | return 0; 112 | } -------------------------------------------------------------------------------- /term4/Min cost flow/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const string file_name = "assignment"; 5 | 6 | //#define inp cin 7 | //#define out cout 8 | 9 | ifstream inp(file_name + ".in"); 10 | ofstream out(file_name + ".out"); 11 | 12 | const int MAX_N = 300 + 5; 13 | const int MAX_M = 300 + 5; 14 | int INF = INT_MAX; 15 | 16 | int n, m; 17 | 18 | vector> table(MAX_N, vector(MAX_N, 0)); 19 | 20 | void input() { 21 | inp >> n; 22 | int value; 23 | m = n; 24 | 25 | for (int i = 1; i <= n; ++i) 26 | for (int j = 1; j <= m; ++j) { 27 | inp >> value; 28 | table[i][j] = value; 29 | } 30 | } 31 | 32 | pair> hungry(vector> &table, int n, int m) { 33 | vector u(n + 1); 34 | vector v(m + 1); 35 | vector matching(m + 1); 36 | vector way(m + 1); 37 | vector ans(n + 1); 38 | 39 | for (int row = 1; row <= n; ++row) { 40 | matching[0] = row; 41 | int column = 0; 42 | 43 | vector min_v(m + 1, INF); 44 | vector was(m + 1, false); 45 | 46 | do { 47 | was[column] = true; 48 | int cur_row = matching[column]; 49 | int delta = INF; 50 | int cur_column = 0; 51 | 52 | for (int j = 1; j <= m; ++j) { 53 | if (!was[j]) { 54 | int cur = table[cur_row][j] - u[cur_row] - v[j]; 55 | if (cur < min_v[j]) { 56 | min_v[j] = cur; 57 | way[j] = column; 58 | } 59 | if (min_v[j] < delta) { 60 | delta = min_v[j]; 61 | cur_column = j; 62 | } 63 | } 64 | } 65 | 66 | for (int j = 0; j <= m; ++j) { 67 | if (was[j]) { 68 | u[matching[j]] += delta; 69 | v[j] -= delta; 70 | } else { 71 | min_v[j] -= delta; 72 | } 73 | } 74 | 75 | column = cur_column; 76 | } while (matching[column] != 0); 77 | 78 | do { 79 | int j1 = way[column]; 80 | matching[column] = matching[j1]; 81 | column = j1; 82 | } while (column); 83 | } 84 | 85 | for (int j = 1; j <= m; ++j) { 86 | ans[matching[j]] = j; 87 | } 88 | 89 | return {-v[0], ans}; 90 | } 91 | 92 | void solve() { 93 | } 94 | 95 | void output() { 96 | pair> ans = hungry(table, n, m); 97 | out << ans.first << "\n"; 98 | for (int i = 1; i <= n; ++i) { 99 | out << i << " " << ans.second[i] << "\n"; 100 | } 101 | } 102 | 103 | 104 | int main() { 105 | input(); 106 | solve(); 107 | output(); 108 | return 0; 109 | } -------------------------------------------------------------------------------- /term1/heap_sort/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | std::vector b; 5 | struct leaf 6 | { 7 | int data; 8 | int pos; 9 | int numb; 10 | }; 11 | 12 | void SiftUp(std::vector& a, int i) 13 | { 14 | leaf temp; 15 | while ((i - 1) / 2 >= 0 && a[i].data < a[(i - 1) / 2].data) 16 | { 17 | temp = a[(i - 1) / 2]; 18 | a[(i - 1) / 2] = a[i]; 19 | a[i] = temp; 20 | a[i].pos = i; 21 | b[a[i].numb] = i; 22 | i = (i - 1) / 2; 23 | a[i].pos = i; 24 | b[a[i].numb] = i; 25 | } 26 | } 27 | 28 | void SiftDown(std::vector& a, int i) 29 | { 30 | leaf temp; 31 | long long p = a.size(); 32 | while (2 * i + 2 < p && (a[i].data >= a[2 * i + 1].data || a[i].data >= a[2 * i + 2].data)) 33 | { 34 | if (a[2 * i + 1].data < a[2 * i + 2].data) 35 | { 36 | temp = a[2 * i + 1]; 37 | a[2 * i + 1] = a[i]; 38 | a[i] = temp; 39 | a[i].pos = i; 40 | b[a[i].numb] = i; 41 | i = 2 * i + 1; 42 | a[i].pos = i; 43 | b[a[i].numb] = i; 44 | 45 | } 46 | else 47 | { 48 | temp = a[2 * i + 2]; 49 | a[2 * i + 2] = a[i]; 50 | a[i] = temp; 51 | a[i].pos = i; 52 | b[a[i].numb] = i; 53 | i = 2 * i + 2; 54 | a[i].pos = i; 55 | b[a[i].numb] = i; 56 | } 57 | } 58 | if (2 * i + 2 >= p && 2 * i + 1 < p && a[i].data > a[2 * i + 1].data) 59 | { 60 | temp = a[2 * i + 1]; 61 | a[2 * i + 1] = a[i]; 62 | a[i] = temp; 63 | a[i].pos = i; 64 | b[a[i].numb] = i; 65 | i = 2 * i + 1; 66 | a[i].pos = i; 67 | b[a[i].numb] = i; 68 | } 69 | } 70 | 71 | 72 | 73 | 74 | void push(std::vector& a, leaf& x) 75 | { 76 | a.push_back(x); 77 | SiftUp(a, a.size() - 1); 78 | } 79 | 80 | 81 | int extractMin(std::vector& a) 82 | { 83 | int ans = a[0].data; 84 | a[0] = a[a.size() - 1]; 85 | a[0].pos = 0; 86 | b[a[0].numb] = 0; 87 | a.pop_back(); 88 | SiftDown(a, 0); 89 | return ans; 90 | } 91 | 92 | void decrease(std::vector& a, int x, int y) 93 | { 94 | a[x].data = y; 95 | SiftUp(a, x); 96 | } 97 | 98 | 99 | int main() 100 | { 101 | std::vector a; 102 | std::string s; 103 | std::ifstream fin("priorityqueue.in"); 104 | std::ofstream fout("priorityqueue.out"); 105 | int t = -1; 106 | while (fin >> s) 107 | { 108 | int temp1, temp2, temp; 109 | b.push_back(-1); 110 | ++t; 111 | if (s == "push") 112 | { 113 | leaf p; 114 | fin >> temp; 115 | p.data = temp; 116 | p.numb = t; 117 | b[t] = a.size() ; 118 | push(a, p); 119 | } 120 | else if (s == "extract-min") 121 | { 122 | if (a.size() > 0) 123 | { 124 | fout << extractMin(a) << "\n"; 125 | } 126 | else 127 | { 128 | fout << "*" << "\n"; 129 | } 130 | } 131 | else 132 | { 133 | fin >> temp1 >> temp2; 134 | decrease(a, b[temp1 - 1], temp2); 135 | } 136 | } 137 | fin.close(); 138 | fout.close(); 139 | return 0; 140 | } 141 | -------------------------------------------------------------------------------- /term3/LCA/E/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace std; 11 | 12 | string fileName = "dynamic"; 13 | ofstream out(fileName + ".out"); 14 | ifstream in(fileName + ".in"); 15 | //ofstream out("output.txt"); 16 | //ifstream in("input.txt"); 17 | int l, m, N; 18 | int const maxN = 100000 + 50; 19 | vector> edges(maxN); 20 | vector > up(maxN); 21 | vector d(maxN); 22 | vector counter; 23 | int root = 0; 24 | int depth = 0; 25 | vector was(maxN, false); 26 | 27 | void input() { 28 | edges.assign(maxN, vector()); 29 | d.assign(maxN, 0); 30 | up.assign(maxN, vector()); 31 | was.assign(maxN, false); 32 | root = 0; 33 | depth = 0; 34 | for (int i = 0; i < N - 1; ++i) { 35 | int v, u; 36 | in >> v >> u; 37 | --v; 38 | --u; 39 | edges[v].push_back(u); 40 | edges[u].push_back(v); 41 | } 42 | } 43 | 44 | void dfs(int v, int p = 0) { 45 | up[v][0] = p; 46 | was[v] = true; 47 | d[v] = depth; 48 | for (int i = 1; i <= l; ++i) 49 | up[v][i] = up[up[v][i - 1]][i - 1]; 50 | for (auto to: edges[v]) { 51 | ++depth; 52 | if (!was[to]) 53 | dfs(to, v); 54 | --depth; 55 | } 56 | 57 | } 58 | 59 | int lca(int v, int u) { 60 | if (d[v] > d[u]) { 61 | int temp = v; 62 | v = u; 63 | u = temp; 64 | } 65 | for (int i = l; i >= 0; --i) 66 | if (d[u] - d[v] >= counter[i]) 67 | u = up[u][i]; 68 | if (v == u) 69 | return v; 70 | for (int i = l; i >= 0; --i) 71 | if (up[v][i] != up[u][i]) { 72 | v = up[v][i]; 73 | u = up[u][i]; 74 | } 75 | return up[v][0]; 76 | } 77 | 78 | int answer(int v, int u) { 79 | int a1 = lca(v, root); 80 | int a2 = lca(root, u); 81 | int a3 = lca(v, u); 82 | int ans = max(d[a1], d[a2]); 83 | ans = max(ans, d[a3]); 84 | if (ans == d[a1]) 85 | return a1; 86 | if (ans == d[a2]) 87 | return a2; 88 | return a3; 89 | } 90 | 91 | void output() { 92 | in >> m; 93 | string s; 94 | for (int i = 0; i < m; ++i) { 95 | in >> s; 96 | if (s == "!") { 97 | in >> root; 98 | --root; 99 | } else { 100 | int v, u; 101 | in >> v >> u; 102 | --v, --u; 103 | out << answer(u, v) + 1 << "\n"; 104 | } 105 | } 106 | } 107 | 108 | 109 | void solve() { 110 | l = 1; 111 | while ((1 << l) <= maxN) ++l; 112 | ++l; 113 | for (int i = 0; i < N; ++i) up[i].resize(l + 1); 114 | dfs(0); 115 | } 116 | 117 | 118 | int main() { 119 | for (int i = 0; i <= 20; ++i) counter.push_back(1 << i); 120 | in >> N; 121 | while (N != 0) { 122 | input(); 123 | solve(); 124 | output(); 125 | in >> N; 126 | } 127 | return 0; 128 | } -------------------------------------------------------------------------------- /term1/linear_structures/F.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | std::ofstream out("hospital.out"); 7 | std::ifstream in("hospital.in"); 8 | 9 | 10 | struct queue_cell 11 | { 12 | queue_cell() : next(NULL),prev(NULL),data(1) {}; 13 | int data; 14 | queue_cell *next; 15 | queue_cell *prev; 16 | }; 17 | 18 | queue_cell *middle = new queue_cell; 19 | 20 | struct queue 21 | { 22 | queue() :head(NULL), tail(NULL), size(0) {}; 23 | queue_cell *head; 24 | queue_cell *tail; 25 | int size; 26 | void push(int x){ 27 | this->size += 1; 28 | queue_cell *p = new queue_cell; 29 | p->next = tail; 30 | if (this->tail) 31 | { 32 | this->tail->prev = p; 33 | } 34 | this->tail = p; 35 | p->data = x; 36 | if (this->head == NULL) 37 | { 38 | this->head = p; 39 | middle = p; 40 | } 41 | if (middle->prev){ 42 | if(this->size % 2 != 0){ 43 | middle = middle->prev; 44 | } 45 | } 46 | } 47 | int pop(){ 48 | int ans = this->head->data; 49 | if (this->head->prev) 50 | { 51 | this->head->prev->next = NULL; 52 | queue_cell *p = this->head; 53 | this->head = this->head->prev; 54 | delete p; 55 | this->size -= 1; 56 | if (size > 0 && middle->prev){ 57 | if(this->size % 2 != 0){ 58 | middle = middle->prev; 59 | } 60 | } 61 | return ans; 62 | } 63 | else 64 | { 65 | this->head = NULL; 66 | this->size = 0; 67 | middle = NULL; 68 | return ans; 69 | } 70 | } 71 | void push_mid(int x){ 72 | if (this->size <= 1){ 73 | this->push(x); 74 | return; 75 | } 76 | queue_cell *p = new queue_cell(); 77 | p->data = x; 78 | this->size++; 79 | if (middle->prev){ 80 | middle->prev->next = p; 81 | p->next = middle; 82 | p->prev = middle->prev; 83 | middle->prev = p; 84 | } 85 | else{ 86 | middle->prev = p; 87 | p->next = middle; 88 | } 89 | if (this->size % 2 != 0) 90 | { 91 | middle = p; 92 | } 93 | } 94 | 95 | }; 96 | int main() 97 | { 98 | queue a; 99 | std::string s; 100 | int n; 101 | in >> n; 102 | for (int i = 0; i < n; i++){ 103 | in >> s; 104 | if (s == "+"){ 105 | int x; 106 | in >> x; 107 | a.push(x); 108 | } 109 | else if (s == "*"){ 110 | int x; 111 | in >> x; 112 | a.push_mid(x); 113 | } 114 | else{ 115 | out << a.pop() << "\n"; 116 | } 117 | } 118 | in.close(); 119 | out.close(); 120 | return 0; 121 | } 122 | -------------------------------------------------------------------------------- /term1/linear_structures/E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | std::ofstream out("formation.out"); 7 | std::ifstream in("formation.in"); 8 | struct queue_cell 9 | { 10 | queue_cell() : next(NULL),prev(NULL),data(1) {}; 11 | int data; 12 | queue_cell *next; 13 | queue_cell *prev; 14 | }; 15 | queue_cell *first = new queue_cell(); 16 | 17 | struct queue 18 | { 19 | queue() :head(first){}; 20 | queue_cell *head; 21 | void left(int i, int j, std::vector & path){ 22 | queue_cell *srch = path[j]; 23 | queue_cell *p = new queue_cell(); 24 | p->data = i; 25 | if (srch->prev){ 26 | srch->prev->next = p; 27 | p->prev = srch->prev; 28 | p->next = srch; 29 | srch->prev = p; 30 | } 31 | else{ 32 | srch->prev = p; 33 | p->next = srch; 34 | this->head = p; 35 | } 36 | path[i] = p; 37 | } 38 | void right(int i, int j, std::vector & path){ 39 | queue_cell *srch = path[j]; 40 | queue_cell *p = new queue_cell(); 41 | p->data = i; 42 | if (srch->next){ 43 | srch->next->prev = p; 44 | p->prev = srch; 45 | p->next = srch->next; 46 | srch->next = p; 47 | } 48 | else{ 49 | srch->next = p; 50 | p->prev = srch; 51 | } 52 | path[i] = p; 53 | 54 | } 55 | void leave(int i, std::vector &path){ 56 | queue_cell *p = path[i]; 57 | if (p == this->head){ 58 | this->head = p->next; 59 | this->head->prev = NULL; 60 | } 61 | else if (!p->next){ 62 | p->prev->next = NULL; 63 | } 64 | else{ 65 | p->next->prev = p->prev; 66 | p->prev->next = p->next; 67 | } 68 | } 69 | void name(int i, std::vector & path){ 70 | queue_cell *p = path[i]; 71 | if (p->prev) out << p->prev->data; 72 | else out << 0; 73 | out << " "; 74 | if (p->next) out << p->next->data; 75 | else out << 0; 76 | out << "\n"; 77 | } 78 | }; 79 | int main() 80 | { 81 | queue a; 82 | int n,m; 83 | in >> n >> m; 84 | std::string s; 85 | std::vector path(n+1); 86 | path[1] = first; 87 | for (int i = 0; i < m; i++){ 88 | in >> s; 89 | if (s == "left"){ 90 | int x,y; 91 | in >> x >> y; 92 | a.left(x,y,path); 93 | } 94 | if (s=="right"){ 95 | int x,y; 96 | in >> x >> y; 97 | a.right(x,y,path); 98 | } 99 | if (s=="name"){ 100 | int x; 101 | in >> x; 102 | a.name(x,path); 103 | } 104 | if (s=="leave"){ 105 | int x; 106 | in >> x; 107 | a.leave(x,path); 108 | } 109 | } 110 | in.close(); 111 | out.close(); 112 | return 0; 113 | } 114 | -------------------------------------------------------------------------------- /term1/trees/H.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | int N = 1000 * 1000 * 1000 + 7; 9 | struct rect { 10 | int x1, x2, y1, y2; 11 | rect(int x1 = -1000001, int y1 = -1000001, int x2 = 1000001, int y2 = 1000001) :x1(x1), y1(y1), x2(x2), y2(y2) {}; 12 | int s() { 13 | return(((long long)(this->x2 - this->x1)*(long long)(this->y2 - this->y1)) % N); 14 | } 15 | bool is0() { 16 | if (this->x2 == this->x1 || this->y2 == this->y1) { 17 | return true; 18 | } 19 | return false; 20 | } 21 | }; 22 | rect merge(rect a, rect b) { 23 | if (a.y2 < b.y1 || a.y1 > b.y2 || a.x1 > b.x2 || a.x2 < b.x1) 24 | { 25 | rect ans(0, 0, 0, 0); 26 | return ans; 27 | } 28 | else { 29 | rect ans; 30 | ans.y1 = max(a.y1, b.y1); 31 | ans.x1 = max(a.x1, b.x1); 32 | ans.y2 = min(a.y2, b.y2); 33 | ans.x2 = min(a.x2, b.x2); 34 | return ans; 35 | } 36 | } 37 | rect a[128][128]; 38 | rect t[128][128][8][8]; 39 | int logs[128]; 40 | void create_logs() { 41 | for (int i = 0; i < 128; i++) { 42 | logs[i] = floor(log2(i)); 43 | } 44 | } 45 | int n, m; 46 | rect I0(0, 0, 0, 0); 47 | rect I; 48 | int ans = 0; 49 | void build() { 50 | for (int a = 0; a < 8; a++) { 51 | for (int b = 0; b < 8; b++) { 52 | for (int i = 0; i <= n - (1 << a); i++) { 53 | for (int j = 0; j <= m - (1 << b); j++) { 54 | if (a > 0) { 55 | t[i][j][a][b] = merge(t[i][j][a - 1][b], t[i + (1 << (a - 1))][j][a - 1][b]); 56 | } 57 | else if (b > 0){ 58 | t[i][j][a][b] = merge(t[i][j][a][b - 1], t[i][j + (1 << (b - 1))][a][b - 1]); 59 | } 60 | } 61 | } 62 | } 63 | } 64 | } 65 | 66 | int get(int x1, int y1, int x2, int y2) { 67 | int la = logs[x2 - x1]; 68 | int lb = logs[y2 - y1]; 69 | rect ans = merge(t[x1][y1][la][lb], t[x2 - (1 << la) + 1][y2 - (1 << lb) + 1][la][lb]); 70 | ans = merge(ans, t[x1][y2 - (1 << lb) + 1][la][lb]); 71 | ans = merge(t[x2 - (1 << la) + 1][y1][la][lb], ans); 72 | return ans.s(); 73 | } 74 | int main() { 75 | create_logs(); 76 | ofstream out("pail.out"); 77 | ifstream in("pail.in"); 78 | in >> n >> m; 79 | for (int i = 0; i < n; i++) { 80 | for (int j = 0; j < m; j++) { 81 | int x1, x2, y1, y2; 82 | in >> x1 >> y1 >> x2 >> y2; 83 | a[i][j].x1 = min(x1, x2); 84 | a[i][j].y1 = min(y1, y2); 85 | a[i][j].x2 = max(x1, x2); 86 | a[i][j].y2 = max(y1, y2); 87 | t[i][j][0][0] = a[i][j]; 88 | } 89 | } 90 | build(); 91 | int q; 92 | in >> q; 93 | int ans = 0; 94 | vector rq(4 * q + 1); 95 | int A, B, v; 96 | in >> A >> B >> v; 97 | rq[0] = v; 98 | for (int i = 1; i <= 4 * q; i++) { 99 | rq[i] = ((long long)A*rq[i - 1] + B) % N; 100 | if (i % 4 == 0) { 101 | int x1, x2, y1, y2; 102 | x1 = min(rq[i - 3] % n, rq[i - 1] % n); 103 | y1 = min(rq[i - 2] % m, rq[i] % m); 104 | x2 = max(rq[i - 3] % n, rq[i - 1] % n); 105 | y2 = max(rq[i - 2] % m, rq[i] % m); 106 | ans = ((long long)ans + get(x1, y1, x2, y2))%N; 107 | } 108 | } 109 | out << ans; 110 | in.close(); 111 | out.close(); 112 | return 0; 113 | } -------------------------------------------------------------------------------- /term1/trees/J.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | struct leaf { 9 | long long max; 10 | long long suff; 11 | long long preff; 12 | leaf() : max(0), suff(0), preff(0) {}; 13 | }; 14 | vector t(2 * 1000000); 15 | vector a(10000000); 16 | void update(long long L, long long R, long long v) { 17 | t[v].max = std::max(t[2 * v + 1].max, t[2 * v + 2].max); 18 | t[v].max = std::max(t[v].max, t[2 * v + 1].suff + t[2 * v + 2].preff); 19 | long long m = (L + R) / 2; 20 | if (t[2 * v + 1].preff == m - L) { 21 | t[v].preff = t[2 * v + 1].preff + t[2 * v + 2].preff; 22 | } 23 | else { 24 | t[v].preff = t[2 * v + 1].preff; 25 | } 26 | if (t[2 * v + 2].suff == R - m) { 27 | t[v].suff = t[2 * v + 1].suff + t[2 * v + 2].suff; 28 | } 29 | else { 30 | t[v].suff = t[2 * v + 2].suff; 31 | } 32 | } 33 | void build(long long L, long long R, long long v) { 34 | if (R - L == 1) { 35 | if (a[L] == 1) { 36 | t[v].max = 1; 37 | t[v].preff = 1; 38 | t[v].suff = 1; 39 | } 40 | return; 41 | } 42 | long long m = (L + R) / 2; 43 | build(L, m, v * 2 + 1); 44 | build(m, R, v * 2 + 2); 45 | update(L, R, v); 46 | } 47 | long long getMax(long long L, long long R, long long l, long long r, long long v) { 48 | if (L >= r || l >= R) { 49 | return 0; 50 | } 51 | if (l <= L && R <= r) { 52 | return t[v].max; 53 | } 54 | long long m = (L + R) / 2; 55 | long long tmp1 = getMax(L, m, l, r, 2 * v + 1); 56 | long long tmp2 = getMax(m, R, l, r, 2 * v + 2); 57 | //----------------------------------------- 58 | long long preff = t[2 * v + 2].preff; 59 | preff = min((int)preff, (int)r - (int)m); 60 | long long suff = t[2 * v + 1].suff; 61 | suff = min((int)suff,(int)m - (int)l); 62 | return max(max(tmp1, tmp2), preff + suff); 63 | 64 | } 65 | void add(long long L, long long R, long long pos, long long val, long long v) { 66 | if (R - L == 1) { 67 | a[L] += val; 68 | if (a[L] == 1) { 69 | t[v].max = 1; 70 | t[v].preff = 1; 71 | t[v].suff = 1; 72 | } 73 | else { 74 | t[v].max = 0; 75 | t[v].preff = 0; 76 | t[v].suff = 0; 77 | } 78 | return; 79 | } 80 | long long m = (R + L) / 2; 81 | if (pos < m) add(L, m, pos, val, 2 * v + 1); 82 | else add(m, R, pos, val, 2 * v + 2); 83 | update(L, R, v); 84 | } 85 | int main() 86 | { 87 | ifstream in("atoms.in"); 88 | ofstream out("atoms.out"); 89 | long long n; 90 | in >> n; 91 | vector input(n); 92 | for (long long i = 0; i < n; i++) { 93 | in >> input[i]; 94 | } 95 | for (long long i = 1; i < n; i++) { 96 | a[i] = input[i] - input[i - 1]; 97 | } 98 | a[0] = 0; 99 | build(0, n, 0); 100 | long long m; 101 | string s; 102 | in >> m; 103 | for (long long i = 0; i < m; i++) { 104 | in >> s; 105 | if (s == "+") { 106 | long long x, y, z; 107 | in >> x >> y >> z; 108 | --x; 109 | add(0, n, x, z, 0); 110 | if (y < n) { 111 | add(0, n, y, -z, 0); 112 | } 113 | } 114 | else { 115 | long long x, y; 116 | in >> x >> y; 117 | out << getMax(0, n, x, y, 0) + 1 << "\n"; 118 | } 119 | } 120 | return 0; 121 | } -------------------------------------------------------------------------------- /term3/LCA/C/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | string fileName = "lca_rmq"; 12 | ofstream out(fileName + ".out"); 13 | ifstream in(fileName + ".in"); 14 | int n = 1, l, m, N; 15 | int const maxN = 100000 + 50; 16 | int const maxM = 10000000 + 50; 17 | vector depth(maxN); 18 | vector> edges(maxN); 19 | vector order; 20 | vector first(maxN, -1); 21 | int const maxLog = 20; 22 | int sparse[2 * maxN][2 * maxLog]; 23 | int pows[2 * maxLog]; 24 | int lens[2 * maxN]; 25 | 26 | void input() { 27 | in >> N >> m; 28 | for (int i = 1; i < N; ++i) { 29 | int v; 30 | in >> v; 31 | edges[v].push_back(i); 32 | } 33 | } 34 | 35 | 36 | void dfs(int v, int p) { 37 | depth[v] = p; 38 | order.push_back(v); 39 | for (auto to: edges[v]) { 40 | dfs(to, p + 1); 41 | order.push_back(v); 42 | } 43 | } 44 | 45 | int mins(int v, int u) { 46 | return depth[v] < depth[u] ? v : u; 47 | } 48 | 49 | int getAnswer(int left, int right) { 50 | int j = lens[right - left + 1]; 51 | return mins(sparse[left][j], sparse[right - pows[j] + 1][j]); 52 | } 53 | 54 | int lca(int v, int u) { 55 | v = first[v]; 56 | u = first[u]; 57 | if (u < v) { 58 | int temp = u; 59 | u = v; 60 | v = temp; 61 | } 62 | //out << " " << v << " " << u; 63 | return getAnswer(v, u); 64 | } 65 | 66 | long long a1, a2, x, y, z; 67 | 68 | void outSparse() { 69 | for (int i = 0; i < l; ++i) { 70 | for (int j = 0; j < n - pows[i]; ++j) 71 | out << sparse[j][i] << " "; 72 | out << "\n"; 73 | } 74 | 75 | } 76 | 77 | void output() { 78 | //outSparse(); 79 | in >> a1 >> a2; 80 | in >> x >> y >> z; 81 | int v = 0; 82 | long long ai, aj; 83 | long long s = 0; 84 | for (int i = 1; i <= m; ++i) { 85 | //out << (a1 + v) % N << " " << a2; 86 | v = lca((a1 + v) % N, a2); 87 | //out << " " << v << "\n"; 88 | s += v; 89 | ai = (x * a1 + y * a2 + z) % N; 90 | aj = (x * a2 + y * ai + z) % N; 91 | a1 = ai; 92 | a2 = aj; 93 | } 94 | out << s; 95 | } 96 | 97 | 98 | int fl(int len) { 99 | if (len == 1) 100 | return 0; 101 | else 102 | return fl(len / 2) + 1; 103 | } 104 | 105 | 106 | void solve() { 107 | dfs(0, 1); 108 | for (int i = 0; i < order.size(); ++i) { 109 | int v = order[i]; 110 | if (first[v] == -1) 111 | first[v] = i; 112 | } 113 | n = order.size(); 114 | l = (int) (log(n) / log(2)) + 1; 115 | for (int i = 0; i <= l; ++i) 116 | pows[i] = 1 << i; 117 | for (int i = 1; i <= n; ++i) 118 | lens[i] = fl(i); 119 | 120 | for (int i = 0; i < l; ++i) 121 | for (int j = 0; j < n - pows[i]; ++j) 122 | if (i == 0) 123 | sparse[j][i] = order[j]; 124 | else 125 | sparse[j][i] = mins(sparse[j][i - 1], sparse[j + pows[i - 1]][i - 1]); 126 | } 127 | 128 | 129 | int main() { 130 | input(); 131 | solve(); 132 | output(); 133 | return 0; 134 | } -------------------------------------------------------------------------------- /term4/Min cost flow/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const string file_name = "mincost"; 5 | 6 | //#define inp cin 7 | //#define out cout 8 | 9 | ifstream inp(file_name + ".in"); 10 | ofstream out(file_name + ".out"); 11 | 12 | struct Edge { 13 | int from; 14 | int to; 15 | long long flow; 16 | long long capacity; 17 | long long cost; 18 | int rev_id = -1; 19 | 20 | Edge() { 21 | 22 | } 23 | 24 | Edge(int from, int to, long long flow, long long capacity, long long cost) : from(from), to(to), flow(flow), 25 | capacity(capacity), cost(cost) { 26 | } 27 | }; 28 | 29 | const int MAX_N = 100 + 5; 30 | const int MAX_M = 1000 + 5; 31 | long long INF = LONG_LONG_MAX; 32 | 33 | int s, t; 34 | int n, m; 35 | long long max_flow = 0; 36 | long long min_cost = 0; 37 | vector> edges(MAX_N, vector()); 38 | vector d(MAX_N, INF); 39 | vector id(MAX_N, 0); 40 | vector path(MAX_N); 41 | 42 | 43 | void input() { 44 | inp >> n >> m; 45 | s = 1; 46 | t = n; 47 | int from, to; 48 | long long capacity, cost; 49 | for (int i = 0; i < m; ++i) { 50 | inp >> from >> to >> capacity >> cost; 51 | 52 | edges[from].push_back(Edge(from, to, 0, capacity, cost)); 53 | edges[to].push_back(Edge(to, from, 0, 0, -cost)); 54 | 55 | edges[from].back().rev_id = (int) edges[to].size() - 1; 56 | edges[to].back().rev_id = (int) edges[from].size() - 1; 57 | } 58 | } 59 | 60 | void levit() { 61 | deque q; 62 | id.assign(n + 1, 0); 63 | d.assign(n + 1, INF); 64 | path.assign(n + 1, nullptr); 65 | 66 | d[s] = 0; 67 | q.push_back(s); 68 | 69 | while (!q.empty()) { 70 | int v = q.front(); 71 | q.pop_front(); 72 | id[v] = 2; 73 | 74 | for (auto &edge: edges[v]) { 75 | if (edge.flow < edge.capacity && d[edge.to] > d[edge.from] + edge.cost) { 76 | d[edge.to] = d[edge.from] + edge.cost; 77 | if (id[edge.to] == 0) { 78 | q.push_back(edge.to); 79 | } else if (id[edge.to] == 2) { 80 | q.push_front(edge.to); 81 | } 82 | path[edge.to] = &edge; 83 | id[edge.to] = 1; 84 | } 85 | } 86 | } 87 | } 88 | 89 | void solve() { 90 | while (true) { 91 | levit(); 92 | if (d[t] == INF) { 93 | break; 94 | } 95 | 96 | long long delta = INF; 97 | for (int v = t; v != s; v = path[v]->from) { 98 | Edge* e = path[v]; 99 | delta = min(delta, e->capacity - e->flow); 100 | } 101 | 102 | for (int v = t; v != s; v = path[v]->from) { 103 | Edge* e = path[v]; 104 | Edge* e_rev = &edges[e->to][e->rev_id]; 105 | 106 | e->flow += delta; 107 | e_rev->flow -= delta; 108 | 109 | min_cost += e->cost * delta; 110 | } 111 | 112 | max_flow += delta; 113 | } 114 | } 115 | 116 | void output() { 117 | out << min_cost; 118 | } 119 | 120 | 121 | int main() { 122 | input(); 123 | solve(); 124 | output(); 125 | return 0; 126 | } -------------------------------------------------------------------------------- /term3/Strings/K/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | string t, s; 16 | int n, m, f; 17 | const int END = 256; 18 | const unsigned int MAX_N = 400000 + 50; 19 | vector suff(MAX_N); 20 | vector lcp(MAX_N); 21 | //#define in cin 22 | //#define out cout 23 | ifstream in("count.in"); 24 | ofstream out("count.out"); 25 | 26 | int get_letter_ind(char ch) { 27 | return ch - '#'; 28 | } 29 | 30 | vector classes(MAX_N); 31 | vector classes_temp(MAX_N); 32 | vector suff_temp(MAX_N); 33 | 34 | void build_suff_array() { 35 | vector cnt(END, 0); 36 | for (int i = 0; i < n; ++i) 37 | ++cnt[get_letter_ind(s[i])]; 38 | for (int i = 0; i + 1 < END; ++i) 39 | cnt[i + 1] += cnt[i]; 40 | 41 | for (int i = 0; i < n; ++i) 42 | suff[--cnt[get_letter_ind(s[i])]] = i; 43 | int count = 1; 44 | classes[suff[0]] = 0; 45 | 46 | for (int i = 1; i < n; ++i) { 47 | if (s[suff[i]] != s[suff[i - 1]]) 48 | ++count; 49 | classes[suff[i]] = count - 1; 50 | } 51 | 52 | for (int l = 0; (1 << l) < n; ++l) { 53 | int x = 1 << l; 54 | for (int i = 0; i < n; ++i) { 55 | suff_temp[i] = suff[i] - x; 56 | if (suff_temp[i] < 0) 57 | suff_temp[i] += n; 58 | } 59 | 60 | vector cnt(count, 0); 61 | for (int i = 0; i < n; ++i) 62 | ++cnt[classes[suff_temp[i]]]; 63 | for (int i = 0; i + 1 < count; ++i) 64 | cnt[i + 1] += cnt[i]; 65 | for (int i = n - 1; i > -1; --i) 66 | suff[--cnt[classes[suff_temp[i]]]] = suff_temp[i]; 67 | 68 | count = 1; 69 | classes[suff[0]] = 0; 70 | for (int i = 1; i < n; ++i) { 71 | if (classes[suff[i]] != classes[suff[i - 1]] || 72 | classes[(suff[i] + x) % n] != classes[(suff[i - 1] + x) % n]) 73 | ++count; 74 | classes_temp[suff[i]] = count - 1; 75 | } 76 | classes = classes_temp; 77 | } 78 | } 79 | 80 | vector pos(MAX_N); 81 | 82 | void build_lcp() { 83 | for (int i = 0; i < n; ++i) 84 | pos[suff[i]] = i; 85 | int k = 0; 86 | for (int i = 0; i < n; ++i) { 87 | if (k > 0) 88 | --k; 89 | if (pos[i] == n - 1) { 90 | lcp[n - 1] = -1; 91 | k = 0; 92 | } else { 93 | int cur = suff[pos[i] + 1]; 94 | while (max(i + k, cur + k) < n && s[i + k] == s[cur + k]) 95 | ++k; 96 | lcp[pos[i]] = k; 97 | } 98 | } 99 | } 100 | 101 | void input() { 102 | in >> s; 103 | s += '#'; 104 | n = (int) s.length(); 105 | } 106 | 107 | void solve() { 108 | build_suff_array(); 109 | build_lcp(); 110 | } 111 | 112 | void output() { 113 | long long ans = 0; 114 | for (int i = 1; i < n - 1; ++i) 115 | ans += n - suff[i] - 1 - lcp[i]; 116 | out << ans + n - 1 - suff[n - 1]; 117 | } 118 | 119 | int main() { 120 | input(); 121 | solve(); 122 | output(); 123 | return 0; 124 | } -------------------------------------------------------------------------------- /term3/Strings/J/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | string t, s; 16 | int n, m, f; 17 | const int END = 256; 18 | const unsigned int MAX_N = 400000 + 50; 19 | vector suff(MAX_N); 20 | vector lcp(MAX_N); 21 | //#define in cin 22 | //#define out cout 23 | ifstream in("array.in"); 24 | ofstream out("array.out"); 25 | 26 | int get_letter_ind(char ch) { 27 | return ch - '#'; 28 | } 29 | 30 | vector classes(MAX_N); 31 | vector classes_temp(MAX_N); 32 | vector suff_temp(MAX_N); 33 | 34 | void build_suff_array() { 35 | vector cnt(END, 0); 36 | for (int i = 0; i < n; ++i) 37 | ++cnt[get_letter_ind(s[i])]; 38 | for (int i = 0; i + 1 < END; ++i) 39 | cnt[i + 1] += cnt[i]; 40 | 41 | for (int i = 0; i < n; ++i) 42 | suff[--cnt[get_letter_ind(s[i])]] = i; 43 | int count = 1; 44 | classes[suff[0]] = 0; 45 | 46 | for (int i = 1; i < n; ++i) { 47 | if (s[suff[i]] != s[suff[i - 1]]) 48 | ++count; 49 | classes[suff[i]] = count - 1; 50 | } 51 | 52 | for (int l = 0; (1 << l) < n; ++l) { 53 | int x = 1 << l; 54 | for (int i = 0; i < n; ++i) { 55 | suff_temp[i] = suff[i] - x; 56 | if (suff_temp[i] < 0) 57 | suff_temp[i] += n; 58 | } 59 | 60 | vector cnt(count, 0); 61 | for (int i = 0; i < n; ++i) 62 | ++cnt[classes[suff_temp[i]]]; 63 | for (int i = 0; i + 1 < count; ++i) 64 | cnt[i + 1] += cnt[i]; 65 | for (int i = n - 1; i > -1; --i) 66 | suff[--cnt[classes[suff_temp[i]]]] = suff_temp[i]; 67 | 68 | count = 1; 69 | classes[suff[0]] = 0; 70 | for (int i = 1; i < n; ++i) { 71 | if (classes[suff[i]] != classes[suff[i - 1]] || 72 | classes[(suff[i] + x) % n] != classes[(suff[i - 1] + x) % n]) 73 | ++count; 74 | classes_temp[suff[i]] = count - 1; 75 | } 76 | classes = classes_temp; 77 | } 78 | } 79 | 80 | vector pos(MAX_N); 81 | 82 | void build_lcp() { 83 | for (int i = 0; i < n; ++i) 84 | pos[suff[i]] = i; 85 | int k = 0; 86 | for (int i = 0; i < n; ++i) { 87 | if (k > 0) 88 | --k; 89 | if (pos[i] == n - 1) { 90 | lcp[n - 1] = -1; 91 | k = 0; 92 | } else { 93 | int cur = suff[pos[i] + 1]; 94 | while (max(i + k, cur + k) < n && s[i + k] == s[cur + k]) 95 | ++k; 96 | lcp[pos[i]] = k; 97 | } 98 | } 99 | } 100 | 101 | void input() { 102 | in >> s; 103 | s += '#'; 104 | n = (int) s.length(); 105 | } 106 | 107 | void solve() { 108 | build_suff_array(); 109 | build_lcp(); 110 | } 111 | 112 | void output() { 113 | for (int i = 1; i < n; ++i) 114 | out << suff[i] + 1 << " "; 115 | out << "\n"; 116 | for (int i = 1; i < n - 1; ++i) 117 | out << lcp[i] << " "; 118 | } 119 | 120 | int main() { 121 | input(); 122 | solve(); 123 | output(); 124 | return 0; 125 | } -------------------------------------------------------------------------------- /term2/Graphs/N.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | string fileName = "fire"; 11 | ofstream out(fileName + ".out"); 12 | ifstream in(fileName + ".in"); 13 | int n, m; 14 | unsigned int MAX_N = 1000; 15 | vector> edges(2 * MAX_N); 16 | vector> backEdges(2 * MAX_N); 17 | vector color(MAX_N, 0); 18 | vector was(MAX_N, false); 19 | vector order; 20 | vector components; 21 | int ans = 0; 22 | vector st; 23 | int ans1 = 0, ans2 = 0; 24 | map a; 25 | 26 | void input() { 27 | cin >> n >> m; 28 | for (int i = 0; i < 2 * n; i++) { 29 | string x; 30 | cin >> x; 31 | a["+" + x] = i++; 32 | a["-" + x] = i; 33 | st.push_back(x); 34 | st.push_back(x); 35 | } 36 | for (int i = 0; i < m; ++i) { 37 | string x, y, z; 38 | cin >> x >> y >> z; 39 | edges[a[x]].push_back(a[z]); 40 | backEdges[a[z]].push_back(a[x]); 41 | if (x[0] == '+' && z[0] == '+') { 42 | edges[a["-" + z.substr(1, z.length())]].push_back(a["-" + x.substr(1, x.length())]); 43 | backEdges[a["-" + x.substr(1, x.length())]].push_back(a["-" + z.substr(1, z.length())]); 44 | } else if (x[0] == '+' && z[0] == '-') { 45 | edges[a["+" + z.substr(1, z.length())]].push_back(a["-" + x.substr(1, x.length())]); 46 | backEdges[a["-" + x.substr(1, x.length())]].push_back(a["+" + z.substr(1, z.length())]); 47 | } else if (x[0] == '-' && z[0] == '+') { 48 | edges[a["-" + z.substr(1, z.length())]].push_back(a["+" + x.substr(1, x.length())]); 49 | backEdges[a["+" + x.substr(1, x.length())]].push_back(a["-" + z.substr(1, z.length())]); 50 | } else { 51 | edges[a["+" + z.substr(1, z.length())]].push_back(a["+" + x.substr(1, x.length())]); 52 | backEdges[a["+" + x.substr(1, x.length())]].push_back(a["+" + z.substr(1, z.length())]); 53 | } 54 | } 55 | } 56 | 57 | 58 | set b; 59 | int start = 0; 60 | 61 | void dfs1(int v) { 62 | was[v] = true; 63 | for (auto to: edges[v]) 64 | if (!was[to]) 65 | dfs1(to); 66 | order.push_back(v); 67 | } 68 | 69 | void dfs2(int v, int cl) { 70 | components[v] = cl; 71 | for (auto to: backEdges[v]) 72 | if (components[to] == -1) 73 | dfs2(to, cl); 74 | 75 | } 76 | 77 | void output() { 78 | for (int i = 0; i < 2 * n; ++i) 79 | if (components[i] == components[++i]) { 80 | cout << "-1"; 81 | return; 82 | } 83 | for (int i = 0; i < 2 * n; ++i) { 84 | if (components[i] > components[++i]) { 85 | b.insert(st[i]); 86 | } 87 | } 88 | cout << b.size() << "\n"; 89 | for (auto i:b) cout << i << "\n"; 90 | } 91 | 92 | void solve() { 93 | was.assign(2 * n, false); 94 | for (int i = 0; i < 2*n; ++i) 95 | if (!was[i]) 96 | dfs1(i); 97 | 98 | components.assign(2 * n, -1); 99 | for (int i = 0, j = 0; i < 2 * n; ++i) { 100 | int v = order[2*n - i - 1]; 101 | if (components[v] == -1) 102 | dfs2(v, j++); 103 | } 104 | 105 | 106 | } 107 | 108 | int main() { 109 | input(); 110 | solve(); 111 | output(); 112 | return 0; 113 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Алгоритмы и структуры данных ИТМО 2 | 3 | 4 | ## Лабораторные работы 5 | 6 | Если какое-то решение неправильное с вашей точки зрения, пишите. 7 | ### 1 семестр 8 | - Куча, сортировки, двоичный поиск: 9 | [условия](term1/heap_sort/problems.pdf), 10 | [решения](term1/heap_sort) 11 | - Линейные структуры данных: 12 | [условия](term1/linear_structures/problems.pdf), 13 | [решения](term1/linear_structures) 14 | - Деревья (RMQ etc.): 15 | [условия](term1/trees/problems.pdf), 16 | [решения](term1/trees) 17 | 18 | ### 2 семестр 19 | - Динамическое программирование: 20 | [условия](term2/Dynamic%20programming/problems.pdf), 21 | [решения](term2/Dynamic%20programming) 22 | - Теория графов. Начало: 23 | [условия](term2/Graphs/problems.pdf), 24 | [решения](term2/Graphs) 25 | - Кратчайшие пути: 26 | [условия](term2/Shortest%20paths/problems.pdf), 27 | [решения](term2/Shortest%20paths) 28 | 29 | ### 3 семестр 30 | - Наименьший общий предок: 31 | [условия](term3/LCA/problems.pdf), 32 | [решения](term3/LCA) 33 | - Декомпозиция графов: 34 | [условия](term3/Decomp/problems.pdf), 35 | [решения](term3/Decomp) 36 | - Задачи на строки: 37 | [условия](term3/Strings/problems.pdf), 38 | [решения](term3/Strings) 39 | 40 | ### 4 семестр 41 | - Максимальный поток и паросочетания: 42 | [условия](term4/Flow%20and%20Matching/problems.pdf), 43 | [решения](term4/Flow%20and%20Matching) 44 | - Поток минимальной стоимости: 45 | [условия](term4/Min%20cost%20flow/problems.pdf), 46 | [решения](term4/Min%20cost%20flow) 47 | - Математика, криптография: 48 | [условия](term4/Crypto/problems.pdf), 49 | [решения](term4/Crypto) 50 | 51 | ## Темы 52 | 53 | ### 1 семестр 54 | - Сортировка слиянием 55 | - Куча, сортировка кучей 56 | - Быстрая Сортировка. Поиск k-й порядковой статистики 57 | - Сортировка подсчетом. Цифровая Сортировка 58 | - Двоичный поиск 59 | - Связный список. Стек. Очередь 60 | - Амортизационный анализ 61 | - Дерево отрезков 62 | - Разреженная таблица 63 | - Дерево поиска 64 | - Система непересекающихся множеств 65 | - Хеширование 66 | - Проверка простоты, факторизация, НОД 67 | 68 | ### 2 семестр 69 | - Динамическое программирование 70 | - Жадные алгоритмы 71 | - Минимальное остовное дерево, алгоритм Краскала 72 | - Обход в ширину 73 | - Обход в глубину 74 | - Компоненты сильной связности, эйлеров цикл, 2-SAT 75 | - Мосты, точки сочленения 76 | - Кратчайшие пути. Алгоритмы Дейкстры, Форда-Беллмана, Флойда 77 | - Игры на графах 78 | 79 | ### 3 семестр 80 | - Левосторонняя куча. Биномиальная куча 81 | - Фибоначчиева куча 82 | - Двоичные подъемы, LCA 83 | - LCA, RMQ, Фарах-Колтон-Бендер 84 | - Heavy-Light, Link-cut 85 | - Splay-дерево 86 | - Euler-Tour дерево 87 | - Центроидная декомпозиция 88 | - Строки. Хеши. КМП 89 | - Z-функция. Бор 90 | - Ахо-Корасик 91 | - Суффиксное дерево 92 | - Суффиксный массив 93 | - Касаи. Бойер-Мур 94 | - Приближенные алгоритмы 95 | 96 | ### 4 семестр 97 | - Поток. Разрез. Остаточная сеть. 98 | - Алгоритм Форда-Фалкерсона. 99 | - Алгоритм Эдмонса-Карпа. 100 | - Алгоритм Диница. Масштабирование потока 101 | - Алгоритм проталкивания предпотока (push-relabel) 102 | - Паросочетание. Алгоритм Куна. Алгоритм Хопкрофта — Карпа. 103 | - Теорема Холла. Вершинное покрытие 104 | - Паросочетание в недвудольном графе 105 | - Поток минимальной стоимости 106 | - Взвешенные паросочетания 107 | - Глобальный разрез 108 | - Теория чисел 109 | - Криптография(RSA etc.) 110 | - Быстрое преобразование Фурье 111 | -------------------------------------------------------------------------------- /term1/trees/E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | long long inf = std::pow(10,18)-1; 7 | std::vector d(1000 * 1000, 0); 8 | std::vector pr(1000 * 1000, inf); 9 | void propogate(std::vector &t,long long L, long long R, long long v) { 10 | if (pr[v] != inf) { 11 | pr[v * 2 + 1] = pr[v * 2 + 2] = pr[v]; 12 | t[v * 2 + 1] = pr[v] + d[v]; 13 | t[v * 2 + 2] = pr[v] + d[v]; 14 | pr[v] = inf; 15 | d[v * 2 + 1] = d[v]; 16 | d[v * 2 + 2] = d[v]; 17 | d[v] = 0; 18 | } 19 | else { 20 | t[v * 2 + 1] += d[v]; 21 | t[v * 2 + 2] += d[v]; 22 | d[v * 2 + 1] += d[v]; 23 | d[v * 2 + 2] += d[v]; 24 | d[v] = 0; 25 | } 26 | } 27 | long long min(std::vector &t, long long L, long long R, long long l, long long r, long long v) { 28 | if (r < L || R < l) { 29 | return inf; 30 | } 31 | if (L == R) { 32 | return t[v]; 33 | } 34 | if (L >= l && R <= r) { 35 | return t[v]; 36 | } 37 | else { 38 | propogate(t, L, R, v); 39 | long long m = (L + R) / 2; 40 | return std::min(min(t, L, m, l, r, 2 * v + 1), min(t, m + 1, R, l, r, 2 * v + 2)); 41 | } 42 | } 43 | void set(std::vector &t, long long L, long long R, long long l, long long r, long long v, long long val) { 44 | if (r < L || R < l) { 45 | return; 46 | } 47 | if (L == R) { 48 | d[v] = 0; 49 | pr[v] = inf; 50 | t[v] = val; 51 | return; 52 | } 53 | if (L >= l && R <= r) { 54 | d[v] = 0; 55 | t[v] = val; 56 | pr[v] = val; 57 | } 58 | else { 59 | propogate(t, L, R, v); 60 | long long m = (L + R) / 2; 61 | set(t, L, m, l, r, 2 * v + 1,val); 62 | set(t, m + 1, R, l, r, 2 * v + 2,val); 63 | t[v] = std::min(t[2 * v + 1], t[2 * v + 2]); 64 | } 65 | } 66 | 67 | void add(std::vector &t, long long L, long long R, long long l, long long r, long long v, long long val) { 68 | if (r < L || R < l) { 69 | return; 70 | } 71 | if (L == R) { 72 | t[v] += val; 73 | d[v] = 0; 74 | return; 75 | } 76 | if (L >= l && R <= r) { 77 | t[v] += val; 78 | d[v] += val; 79 | } 80 | else { 81 | propogate(t, L, R, v); 82 | long long m = (L + R) / 2; 83 | add(t, L, m, l, r, 2 * v + 1, val); 84 | add(t, m + 1, R, l, r, 2 * v + 2, val); 85 | t[v] = std::min(t[2 * v + 1], t[2 * v + 2]); 86 | } 87 | } 88 | void build(std::vector &a, std::vector &t, long long L, long long R, long long v) { 89 | if (L == R) { 90 | t[v] = a[L]; 91 | } 92 | else { 93 | long long m = (L + R) / 2; 94 | build(a, t, L, m, 2 * v + 1); 95 | build(a, t, m + 1, R, 2 * v + 2); 96 | t[v] = std::min(t[2 * v + 1], t[2 * v + 2]); 97 | } 98 | } 99 | int main() 100 | { 101 | std::ifstream in("rmq2.in"); 102 | std::ofstream out("rmq2.out"); 103 | long long n; 104 | in >> n; 105 | std::vector a(n); 106 | std::vector t(4 * n, inf); 107 | for (long long i = 0; i < n; i++) { 108 | in >> a[i]; 109 | } 110 | build(a, t, 0, n - 1, 0); 111 | std::string s; 112 | while (in >> s) 113 | { 114 | if (s == "min") { 115 | long long x, y; 116 | in >> x >> y; 117 | out << min(t, 0, n - 1, x - 1, y - 1, 0) << "\n"; 118 | } 119 | else if (s=="set"){ 120 | long long x, y, z; 121 | in >> x >> y >> z; 122 | set(t, 0, n - 1, x - 1, y - 1, 0, z); 123 | } 124 | else { 125 | long long x, y, z; 126 | in >> x >> y >> z; 127 | add(t, 0, n - 1, x - 1, y - 1, 0, z); 128 | } 129 | } 130 | in.close(); 131 | out.close(); 132 | return 0; 133 | } 134 | -------------------------------------------------------------------------------- /term1/trees/G.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | struct leaf { 8 | long long priority, size; 9 | long long sum, val; 10 | leaf* left; 11 | leaf* right; 12 | leaf(long long val) : val(val), sum(val*val), size(1), left(NULL), right(NULL) { priority = rand(); }; 13 | }; 14 | typedef pair pll; 15 | 16 | long long getSize(leaf*t) { 17 | return (t ? t->size : 0); 18 | } 19 | 20 | long long index(leaf*t) { 21 | return getSize(t->left) + 1; 22 | } 23 | 24 | long long getSum(leaf*t) { 25 | return (t ? t->sum : 0); 26 | } 27 | 28 | void update(leaf*t) { 29 | if (!t) 30 | return; 31 | t->size = getSize(t->left) + getSize(t->right) + 1; 32 | t->sum = getSum(t->left) + getSum(t->right) + (t->val)*(t->val); 33 | } 34 | 35 | leaf* merge(leaf*l, leaf*r) { 36 | if (!l) 37 | return r; 38 | if (!r) 39 | return l; 40 | if (l->priority > r->priority) { 41 | l->right = merge(l->right, r); 42 | update(l); 43 | return l; 44 | } 45 | else { 46 | r->left = merge(l, r->left); 47 | update(r); 48 | return r; 49 | } 50 | } 51 | 52 | pll split(leaf*t, long long k) { 53 | if (!t) 54 | return pll(NULL, NULL); 55 | pll ans; 56 | if (index(t) <= k) { 57 | ans = split(t->right, k - index(t)); 58 | t->right = ans.first; 59 | ans.first = t; 60 | } 61 | else { 62 | ans = split(t->left, k); 63 | t->left = ans.second; 64 | ans.second = t; 65 | } 66 | update(t); 67 | return ans; 68 | } 69 | 70 | leaf* insert(leaf*t, long long i, long long x) { 71 | leaf*n = new leaf(x); 72 | if (!t) return n; 73 | pll p = split(t, i); 74 | t = merge(merge(p.first, n), p.second); 75 | return t; 76 | } 77 | leaf* del(leaf*t, long long i) { 78 | if (!t) return NULL; 79 | pll p = split(t, i - 1); 80 | pll p2 = split(p.second, 1); 81 | t = merge(p.first, p2.second); 82 | return t; 83 | } 84 | long long get(leaf*t, long long i) { 85 | if (!t) 86 | return 0; 87 | if (index(t) == i) 88 | return t->val; 89 | if (index(t) < i) 90 | return get(t->right, i - index(t)); 91 | return get(t->left, i); 92 | } 93 | void set(leaf*t, long long i, long long val) { 94 | if (!t) 95 | return; 96 | if (index(t) == i) 97 | t->val += val; 98 | if (index(t) < i) 99 | set(t->right, i - index(t), val); 100 | if (index(t) > i) 101 | set(t->left, i, val); 102 | update(t); 103 | } 104 | 105 | 106 | int main() { 107 | srand(time(0)); 108 | ofstream out("river.out"); 109 | ifstream in("river.in"); 110 | long long n, p; 111 | in >> n >> p; 112 | leaf*t = NULL; 113 | for (long long i = 0; i < n; i++) { 114 | long long temp; 115 | in >> temp; 116 | leaf*n = new leaf(temp); 117 | t = merge(t, n); 118 | } 119 | out << getSum(t) << "\n"; 120 | 121 | long long k; 122 | in >> k; 123 | for (long long i = 0; i < k; i++) { 124 | long long x, pos; 125 | in >> x >> pos; 126 | if (x == 1) { 127 | long long val = get(t, pos); 128 | if (pos == 1) set(t, 2, val); 129 | else if (pos == getSize(t)) set(t, getSize(t) - 1, val); 130 | else { 131 | long long l = val / 2, r = val - l; 132 | set(t, pos - 1, l); 133 | set(t, pos + 1, r); 134 | } 135 | t = del(t, pos); 136 | } 137 | else { 138 | long long val = get(t, pos); 139 | long long l = val / 2, r = val - l; 140 | t = del(t, pos); 141 | t = insert(t, pos - 1, r); 142 | t = insert(t, pos - 1, l); 143 | } 144 | out << getSum(t) << "\n"; 145 | } 146 | in.close(); 147 | out.close(); 148 | return 0; 149 | } -------------------------------------------------------------------------------- /term4/Min cost flow/E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const string file_name = "mincost"; 5 | 6 | #define inp cin 7 | #define out cout 8 | 9 | //ifstream inp(file_name + ".in"); 10 | //ofstream out(file_name + ".out"); 11 | 12 | struct Edge { 13 | int from; 14 | int to; 15 | long long flow; 16 | long long capacity; 17 | long long cost; 18 | int rev_id = -1; 19 | 20 | Edge() { 21 | 22 | } 23 | 24 | Edge(int from, int to, long long flow, long long capacity, long long cost) : from(from), to(to), flow(flow), 25 | capacity(capacity), cost(cost) { 26 | } 27 | }; 28 | 29 | const int MAX_N = 256 + 5; 30 | long long INF = LONG_LONG_MAX; 31 | 32 | int s, t; 33 | int n, m; 34 | long long max_flow = 0; 35 | long long min_cost = 0; 36 | vector> edges(2 * MAX_N, vector()); 37 | vector d(MAX_N, INF); 38 | vector id(MAX_N, 0); 39 | vector path(MAX_N); 40 | vector a(MAX_N); 41 | 42 | void add_edge(int from, int to, long long capacity, long long cost) { 43 | edges[from].push_back(Edge(from, to, 0, capacity, cost)); 44 | edges[to].push_back(Edge(to, from, 0, 0, -cost)); 45 | 46 | edges[from].back().rev_id = (int) edges[to].size() - 1; 47 | edges[to].back().rev_id = (int) edges[from].size() - 1; 48 | } 49 | 50 | void input() { 51 | inp >> n >> m; 52 | s = 0; 53 | t = n + n + 1; 54 | for (int i = 1; i <= n; ++i) { 55 | inp >> a[i]; 56 | add_edge(n + i, i, INF, a[i]); 57 | add_edge(0, n + i, 1, 0); 58 | add_edge(i, n + n + 1, 1, 0); 59 | add_edge(i, n + i, INF, 0); 60 | } 61 | 62 | for (int i = 0; i < m; ++i) { 63 | int from, to; 64 | long long value; 65 | inp >> from >> to >> value; 66 | add_edge(n + from, to, INF, value); 67 | } 68 | 69 | n = 2 * n + 2; 70 | 71 | } 72 | 73 | void levit() { 74 | deque q; 75 | id.assign(n + 1, 0); 76 | d.assign(n + 1, INF); 77 | path.assign(n + 1, nullptr); 78 | 79 | d[s] = 0; 80 | q.push_back(s); 81 | 82 | while (!q.empty()) { 83 | int v = q.front(); 84 | q.pop_front(); 85 | id[v] = 2; 86 | 87 | for (auto &edge: edges[v]) { 88 | if (edge.flow < edge.capacity && d[edge.to] > d[edge.from] + edge.cost) { 89 | d[edge.to] = d[edge.from] + edge.cost; 90 | if (id[edge.to] == 0) { 91 | q.push_back(edge.to); 92 | } else if (id[edge.to] == 2) { 93 | q.push_front(edge.to); 94 | } 95 | path[edge.to] = &edge; 96 | id[edge.to] = 1; 97 | } 98 | } 99 | } 100 | } 101 | 102 | void solve() { 103 | while (true) { 104 | levit(); 105 | if (d[t] == INF) { 106 | break; 107 | } 108 | 109 | long long delta = INF; 110 | for (int v = t; v != s; v = path[v]->from) { 111 | Edge *e = path[v]; 112 | delta = min(delta, e->capacity - e->flow); 113 | } 114 | 115 | for (int v = t; v != s; v = path[v]->from) { 116 | Edge *e = path[v]; 117 | Edge *e_rev = &edges[e->to][e->rev_id]; 118 | 119 | e->flow += delta; 120 | e_rev->flow -= delta; 121 | 122 | min_cost += e->cost * delta; 123 | } 124 | 125 | max_flow += delta; 126 | } 127 | } 128 | 129 | void output() { 130 | out << min_cost; 131 | } 132 | 133 | 134 | int main() { 135 | input(); 136 | solve(); 137 | output(); 138 | return 0; 139 | } -------------------------------------------------------------------------------- /term3/Strings/G/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | vector strings; 16 | string t, s; 17 | int n, m, f; 18 | string ans_s = ""; 19 | const unsigned int MAX_N = 1000000 + 50; 20 | 21 | vector ans; 22 | //#define in cin 23 | //#define out cout 24 | ifstream in("search4.in"); 25 | ofstream out("search4.out"); 26 | 27 | int get_letter_index(char ch) { 28 | return ch - 'a'; 29 | } 30 | 31 | class Node { 32 | public: 33 | Node* next[30] = {nullptr}; 34 | Node* links[30] = {nullptr}; 35 | bool term; 36 | char letter_from_parrent; 37 | Node *parent; 38 | Node *suff_link; 39 | bool naxyi_etot_aho_korasik; 40 | vector numb; 41 | 42 | Node() { 43 | term = false; 44 | letter_from_parrent = -1; 45 | parent = nullptr; 46 | suff_link = nullptr; 47 | naxyi_etot_aho_korasik = false; 48 | numb = {}; 49 | } 50 | }; 51 | 52 | Node root; 53 | 54 | Node *next(Node *cur, char ch); 55 | 56 | Node *get_link(Node *cur) { 57 | if (!cur->suff_link) { 58 | if (cur == &root || cur->parent == &root) 59 | cur->suff_link = &root; 60 | else { 61 | cur->suff_link = next(get_link(cur->parent), cur->letter_from_parrent); 62 | if (cur->suff_link->term) { 63 | cur->suff_link->naxyi_etot_aho_korasik = true; 64 | for (auto num: cur->suff_link->numb) 65 | ans[num] = true; 66 | } 67 | } 68 | 69 | } 70 | return cur->suff_link; 71 | } 72 | 73 | Node *next(Node *cur, char ch) { 74 | int i = get_letter_index(ch); 75 | if (!cur->links[i]) 76 | if (cur->next[i]) 77 | cur->links[i] = cur->next[i]; 78 | else { 79 | if (cur == &root) 80 | cur->links[i] = &root; 81 | else 82 | cur->links[i] = next(get_link(cur), ch); 83 | } 84 | get_link(cur->links[i]); 85 | return cur->links[i]; 86 | } 87 | 88 | void add_string(string &st, int numb) { 89 | Node *cur = &root; 90 | int i; 91 | for (auto ch: st) { 92 | i = get_letter_index(ch); 93 | if (cur->next[i] == nullptr) { 94 | cur->next[i] = new Node(); 95 | cur->next[i]->parent = cur; 96 | cur->next[i]->letter_from_parrent = ch; 97 | } 98 | cur = cur->next[i]; 99 | } 100 | cur->term = true; 101 | cur->numb.push_back(numb); 102 | } 103 | 104 | 105 | 106 | void input() { 107 | in >> n; 108 | for (int i = 0; i < n; ++i) { 109 | in >> s; 110 | add_string(s, i); 111 | } 112 | ans.resize(n); 113 | in >> t; 114 | } 115 | 116 | void solve() { 117 | Node *cur = &root; 118 | for (int i = 0; i < t.length(); ++i) { 119 | cur = next(cur, t[i]); 120 | if (cur->term && !cur->naxyi_etot_aho_korasik) { 121 | cur->naxyi_etot_aho_korasik = true; 122 | cur->naxyi_etot_aho_korasik = true; 123 | cur->naxyi_etot_aho_korasik = true; 124 | cur->naxyi_etot_aho_korasik = true; 125 | cur->naxyi_etot_aho_korasik = true; 126 | cur->naxyi_etot_aho_korasik = true; 127 | for (auto num: cur->numb) 128 | ans[num] = true; 129 | } 130 | 131 | } 132 | } 133 | 134 | void output() { 135 | for (auto i: ans) 136 | out << (i ? "YES" : "NO") << "\n"; 137 | } 138 | 139 | int main() { 140 | input(); 141 | solve(); 142 | output(); 143 | return 0; 144 | } -------------------------------------------------------------------------------- /term4/Crypto/G.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | const string file_name = "assignment"; 5 | 6 | #define inp cin 7 | #define out cout 8 | 9 | //ifstream inp(file_name + ".in"); 10 | //ofstream out(file_name + ".out"); 11 | 12 | #define PI 3.14159265359 13 | vector n; 14 | vector m; 15 | vector res; 16 | bool neg_n = false, neg_m = false; 17 | bool neg = true; 18 | 19 | void input() { 20 | string n_s, m_s; 21 | inp >> n_s >> m_s; 22 | if (n_s[0] == '-') { 23 | neg_n = true; 24 | n_s[0] = '0'; 25 | } 26 | if (m_s[0] == '-') { 27 | neg_m = true; 28 | m_s[0] = '0'; 29 | } 30 | if (neg_m && neg_n || !neg_m && !neg_n) { 31 | neg = false; 32 | } 33 | for (auto c: n_s) { 34 | n.push_back((int) (c - '0')); 35 | } 36 | for (auto c: m_s) { 37 | m.push_back((int) (c - '0')); 38 | } 39 | reverse(n.begin(), n.end()); 40 | reverse(m.begin(), m.end()); 41 | } 42 | 43 | void fft(vector> &a) { 44 | auto n = (int) a.size(); 45 | if (n == 1) { 46 | return; 47 | } 48 | 49 | vector> a0(static_cast(n / 2)); 50 | vector> a1(static_cast(n / 2)); 51 | 52 | for (int i = 0, j = 0; i < n; i += 2, ++j) { 53 | a0[j] = a[i]; 54 | a1[j] = a[i + 1]; 55 | } 56 | 57 | fft(a0); 58 | fft(a1); 59 | 60 | double ang = 2 * PI / n; 61 | complex w(1, 0); 62 | complex wn(cos(ang), sin(ang)); 63 | for (int i = 0; i < n / 2; ++i) { 64 | a[i] = a0[i] + w * a1[i]; 65 | a[i + n / 2] = a0[i] - w * a1[i]; 66 | w *= wn; 67 | } 68 | } 69 | 70 | void fft_back(vector> &a) { 71 | auto n = (int) a.size(); 72 | if (n == 1) { 73 | return; 74 | } 75 | 76 | vector> a0(static_cast(n / 2)); 77 | vector> a1(static_cast(n / 2)); 78 | 79 | for (int i = 0, j = 0; i < n; i += 2, ++j) { 80 | a0[j] = a[i]; 81 | a1[j] = a[i + 1]; 82 | } 83 | 84 | fft_back(a0); 85 | fft_back(a1); 86 | 87 | double ang = -2 * PI / n; 88 | complex w(1, 0); 89 | complex wn(cos(ang), sin(ang)); 90 | for (int i = 0; i < n / 2; ++i) { 91 | a[i] = a0[i] + w * a1[i]; 92 | a[i + n / 2] = a0[i] - w * a1[i]; 93 | a[i] /= 2; 94 | a[i + n / 2] /= 2; 95 | w *= wn; 96 | } 97 | } 98 | 99 | void solve() { 100 | vector> fn(n.begin(), n.end()); 101 | vector> fm(m.begin(), m.end()); 102 | size_t size = 1; 103 | while (size < max(n.size(), m.size())) { 104 | size *= 2; 105 | } 106 | size *= 2; 107 | 108 | fn.resize(size); 109 | fm.resize(size); 110 | 111 | fft(fn); 112 | fft(fm); 113 | for (size_t i = 0; i < size; ++i) 114 | fn[i] *= fm[i]; 115 | fft_back(fn); 116 | 117 | res.resize(size); 118 | for (size_t i = 0; i < size; ++i) 119 | res[i] = int(fn[i].real() + 0.5); 120 | 121 | int carry = 0; 122 | for (size_t i = 0; i < size; ++i) { 123 | res[i] += carry; 124 | carry = res[i] / 10; 125 | res[i] %= 10; 126 | } 127 | } 128 | 129 | void output() { 130 | int i = static_cast(res.size() - 1); 131 | while (i >= 0 && res[i] == 0) { 132 | --i; 133 | } 134 | if (i == -1) { 135 | printf("%d", 0); 136 | exit(0); 137 | } 138 | if (neg) { 139 | printf("-"); 140 | } 141 | for (; i >= 0; --i) { 142 | printf("%d", res[i]); 143 | } 144 | } 145 | 146 | 147 | int main() { 148 | input(); 149 | solve(); 150 | output(); 151 | return 0; 152 | } -------------------------------------------------------------------------------- /term4/Flow and Matching/F.kt: -------------------------------------------------------------------------------- 1 | import java.io.* 2 | import java.lang.Math.sqrt 3 | import java.util.* 4 | import kotlin.collections.ArrayList 5 | 6 | 7 | const val fileName = "snails" 8 | const val MAX_N = 50 + 5 9 | const val MAX_M = 50 + 5 10 | const val MAX_E = 100 + 5 11 | const val MAX_C = 10_000 + 5 12 | 13 | class FastScanner(f: InputStream) { 14 | private lateinit var br: BufferedReader 15 | private var st: StringTokenizer? = null 16 | 17 | init { 18 | try { 19 | br = BufferedReader(InputStreamReader(f)) 20 | } catch (e: FileNotFoundException) { 21 | e.printStackTrace() 22 | } 23 | 24 | } 25 | 26 | operator fun next(): String { 27 | while (st == null || !st!!.hasMoreTokens()) { 28 | try { 29 | st = StringTokenizer(br.readLine()) 30 | } catch (e: IOException) { 31 | e.printStackTrace() 32 | } 33 | 34 | } 35 | return st!!.nextToken() 36 | } 37 | 38 | fun nextInt(): Int { 39 | return next().toInt() 40 | } 41 | 42 | fun nextDouble(): Double { 43 | return next().toDouble() 44 | } 45 | } 46 | 47 | //var inp = FastScanner(File("$fileName.in").inputStream()) 48 | //var out = File("$fileName.out").printWriter() 49 | 50 | var inp = FastScanner(System.`in`) 51 | var out = System.out 52 | 53 | 54 | data class Item(val x: Double, val y: Double, val speed: Double) 55 | 56 | 57 | var edges = Array>(MAX_N, { ArrayList() }) 58 | var matching = IntArray(MAX_N, { -1 }) 59 | val was = Array(MAX_N, { false }) 60 | val positions = ArrayList>() 61 | val items = ArrayList() 62 | var n = 0 63 | var m = 0 64 | 65 | 66 | fun input() { 67 | n = inp.nextInt() 68 | for (i in 0 until n) { 69 | items.add(Item(inp.nextDouble(), inp.nextDouble(), inp.nextDouble())) 70 | } 71 | for (i in 0 until n) { 72 | positions.add(Pair(inp.nextDouble(), inp.nextDouble())) 73 | } 74 | } 75 | 76 | const val Eps = 0.00001 77 | 78 | fun distance(item: Item, pos: Pair) = sqrt( 79 | (item.x - pos.first) * (item.x - pos.first) + (item.y - pos.second) * (item.y - pos.second) 80 | ) 81 | 82 | fun neededTime(item: Item, pos: Pair) = distance(item, pos) / item.speed 83 | 84 | fun kuhn(v: Int): Boolean { 85 | if (was[v]) { 86 | return false 87 | } 88 | was[v] = true 89 | 90 | for (u in edges[v]) { 91 | if (matching[u] == -1 || kuhn(matching[u])) { 92 | matching[u] = v 93 | return true 94 | } 95 | } 96 | return false 97 | } 98 | 99 | fun res(time: Double): Boolean { 100 | edges = Array(MAX_N, { ArrayList() }) 101 | for (i in 0 until n) { 102 | for (j in 0 until n) { 103 | if (neededTime(items[i], positions[j]) <= time) { 104 | edges[i].add(j) 105 | } 106 | } 107 | } 108 | matching = IntArray(MAX_N, { -1 }) 109 | 110 | var counter = 0 111 | for (v in 0 until n) { 112 | was.fill(false) 113 | if (kuhn(v)) { 114 | counter++ 115 | } 116 | } 117 | 118 | return counter == n 119 | 120 | } 121 | 122 | fun solve() { 123 | var l = 0.0 124 | var r = Integer.MAX_VALUE.toDouble() 125 | 126 | while (r - l > Eps) { 127 | val m = (l + r) / 2 128 | if (res(m)) { 129 | r = m 130 | } else { 131 | l = m 132 | } 133 | } 134 | 135 | out.println(String.format("%.5f",l)) 136 | } 137 | 138 | fun output() { 139 | 140 | } 141 | 142 | fun main(args: Array) { 143 | try { 144 | input() 145 | solve() 146 | output() 147 | out.close() 148 | } catch (e: IOException) { 149 | e.printStackTrace() 150 | } 151 | } -------------------------------------------------------------------------------- /term3/LCA/A/main.kt: -------------------------------------------------------------------------------- 1 | import java.util.* 2 | import java.io.* 3 | import kotlin.collections.ArrayList 4 | 5 | class lca { 6 | lateinit private var `in`: FastScanner 7 | lateinit private var out: PrintWriter 8 | private val fileName = "lca" 9 | private var currentLine = "" 10 | val maxN = 5 * 10_000 + 10 11 | var log = 1 12 | var N = 0 13 | var up = Array(maxN, { Array(2, { 0 }) }) 14 | val timeIn = Array(maxN, { 0 }) 15 | val timeOut = Array(maxN, { 0 }) 16 | val parents = Array(maxN, { 0 }) 17 | val d = Array(maxN, { 0 }) 18 | val edges = Array(maxN, { ArrayList() }) 19 | val counter = ArrayList() 20 | 21 | @Throws(IOException::class) 22 | fun solve() { 23 | N = nextInt() 24 | while ((1 shl log) <= N) log++ 25 | counter.add(1) 26 | for (i in 1..log + 1) counter.add(1 shl i) 27 | up = Array(maxN, { Array(log + 1, { 0 }) }) 28 | for (v in 1 until N) { 29 | val u = nextInt() - 1 30 | parents[v] = u 31 | edges[u].add(v) 32 | } 33 | dfs(0) 34 | val M = nextInt() 35 | for (i in 1..M) { 36 | out.println(lca(nextInt() - 1, nextInt() - 1)) 37 | } 38 | 39 | } 40 | 41 | fun lca(vTemp: Int, uTemp: Int): Int { 42 | var v = vTemp 43 | var u = uTemp 44 | if (d[v] > d[u]) { 45 | val temp = v 46 | v = u 47 | u = temp 48 | } 49 | for (i in log downTo 0) 50 | if (d[u] - d[v] >= counter[i]) 51 | u = up[u][i] 52 | if (v == u) 53 | return v + 1 54 | for (i in log downTo 0) 55 | if (up[v][i] != up[u][i]) { 56 | v = up[v][i] 57 | u = up[u][i] 58 | } 59 | return parents[v] + 1 60 | } 61 | 62 | var timer = 0 63 | var depth = 0 64 | fun dfs(v: Int, p: Int = 0) { 65 | timeIn[v] = ++timer 66 | d[v] = depth 67 | up[v][0] = p 68 | for (i in 1..log) 69 | up[v][i] = up[up[v][i - 1]][i - 1] 70 | for (to in edges[v]) 71 | if (to != p) { 72 | depth++ 73 | dfs(to, v) 74 | depth-- 75 | } 76 | timeOut[v] = ++timer 77 | } 78 | 79 | fun upper(v: Int, u: Int) = timeIn[v] <= timeIn[u] && timeOut[v] >= timeOut[u] 80 | 81 | fun nextInt() = `in`.nextInt() 82 | 83 | fun next() = `in`.br.readLine() 84 | 85 | fun run() { 86 | try { 87 | `in` = FastScanner(File(fileName + ".in")) 88 | out = PrintWriter(File(fileName + ".out")) 89 | 90 | solve() 91 | 92 | out.close() 93 | } catch (e: IOException) { 94 | e.printStackTrace() 95 | } 96 | 97 | } 98 | 99 | class FastScanner(f: File) { 100 | lateinit var br: BufferedReader 101 | var st: StringTokenizer? = null 102 | 103 | init { 104 | try { 105 | br = BufferedReader(FileReader(f)) 106 | } catch (e: FileNotFoundException) { 107 | e.printStackTrace() 108 | } 109 | 110 | } 111 | 112 | operator fun next(): String { 113 | while (st == null || !st!!.hasMoreTokens()) { 114 | try { 115 | st = StringTokenizer(br.readLine()) 116 | } catch (e: IOException) { 117 | e.printStackTrace() 118 | } 119 | 120 | } 121 | return st!!.nextToken() 122 | } 123 | 124 | fun nextInt(): Int { 125 | return Integer.parseInt(next()) 126 | } 127 | } 128 | 129 | companion object { 130 | @JvmStatic 131 | fun main(arg: Array) { 132 | lca().run() 133 | } 134 | } 135 | } -------------------------------------------------------------------------------- /term3/LCA/G/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace std; 11 | 12 | string fileName = "carno"; 13 | ofstream out(fileName + ".out"); 14 | ifstream in(fileName + ".in"); 15 | int l, m, n; 16 | int const maxN = 200000 + 50; 17 | vector> edges(maxN); 18 | vector dead(maxN, false); 19 | vector > up(maxN); 20 | vector timeIn(maxN), timeOut(maxN); 21 | vector parent(maxN); 22 | vector depth(maxN); 23 | vector counter; 24 | vector r(maxN); 25 | vector alive(maxN); 26 | int timer = 0; 27 | 28 | void input() { 29 | in >> n; 30 | } 31 | 32 | void dfs(int v, int p, int d) { 33 | up[v][0] = p; 34 | depth[v] = d; 35 | for (int i = 1; i <= l; ++i) 36 | up[v][i] = up[up[v][i - 1]][i - 1]; 37 | for (auto to: edges[v]) 38 | dfs(to, v, d + 1); 39 | } 40 | 41 | void makeSet(int v) { 42 | parent[v] = v; 43 | r[v] = 0; 44 | } 45 | 46 | int find_set(int v) { 47 | if (v == parent[v]) 48 | return v; 49 | return parent[v] = find_set(parent[v]); 50 | } 51 | 52 | void union_sets(int a, int b) { 53 | a = find_set(a); 54 | b = find_set(b); 55 | if (a != b) { 56 | if (r[a] < r[b]) { 57 | int temp = a; 58 | a = b; 59 | b = temp; 60 | } 61 | parent[b] = a; 62 | if (r[a] == r[b]) 63 | ++r[a]; 64 | } 65 | } 66 | 67 | void check(int v) { 68 | makeSet(v); 69 | for (auto child: edges[v]) 70 | if (dead[child]) 71 | union_sets(child, v); 72 | alive[find_set(v)] = up[v][0]; 73 | if (dead[up[v][0]]) { 74 | int temp = alive[find_set(up[v][0])]; 75 | union_sets(v, up[v][0]); 76 | alive[find_set(v)] = temp; 77 | } 78 | } 79 | 80 | int get(int v) { 81 | if (dead[v]) 82 | return alive[find_set(v)]; 83 | return v; 84 | } 85 | 86 | int lca(int v, int u) { 87 | if (depth[v] > depth[u]) { 88 | int temp = u; 89 | u = v; 90 | v = temp; 91 | } 92 | for (int i = l; i >= 0; --i) 93 | if (depth[u] - depth[v] >= counter[i]) 94 | u = up[u][i]; 95 | if (v == u) 96 | return v; 97 | for (int i = l; i >= 0; --i) 98 | if (up[v][i] != up[u][i] && depth[up[v][i]] == depth[up[u][i]]) { 99 | v = up[v][i]; 100 | u = up[u][i]; 101 | } 102 | return get(up[v][0]); 103 | } 104 | 105 | void add(int parent, int child) { 106 | depth[child] = depth[parent] + 1; 107 | up[child][0] = parent; 108 | for (int i = 1; i <= l; ++i) { 109 | up[child][i] = up[up[child][i - 1]][i - 1]; 110 | } 111 | } 112 | 113 | void output() { 114 | string s; 115 | int numb = 1; 116 | for (int i = 0; i < n; ++i) { 117 | in >> s; 118 | if (s == "+") { 119 | int v; 120 | in >> v; 121 | --v; 122 | edges[v].push_back(numb); 123 | add(v, numb); 124 | numb++; 125 | } else if (s == "-") { 126 | int v; 127 | in >> v; 128 | --v; 129 | dead[v] = true; 130 | check(v); 131 | } else { 132 | int v, u; 133 | in >> v >> u; 134 | --v; 135 | --u; 136 | out << lca(v, u) + 1 << "\n"; 137 | } 138 | } 139 | } 140 | 141 | 142 | void solve() { 143 | l = 1; 144 | while ((1 << l) <= n) ++l; 145 | ++l; 146 | for (int i = 0; i < maxN; ++i) alive[i] = i; 147 | for (int i = 0; i <= l; ++i) counter.push_back(1 << i); 148 | for (int i = 0; i < n; ++i) up[i].resize(l + 1); 149 | dfs(0, 0, 1); 150 | } 151 | 152 | 153 | int main() { 154 | input(); 155 | solve(); 156 | output(); 157 | return 0; 158 | } -------------------------------------------------------------------------------- /term2/Graphs/A.java: -------------------------------------------------------------------------------- 1 | import javafx.util.Pair; 2 | 3 | import java.lang.reflect.Array; 4 | import java.util.*; 5 | import java.io.*; 6 | 7 | public class Main { 8 | private FastScanner in; 9 | private PrintWriter out; 10 | 11 | private int n, m; 12 | private ArrayList, Integer>> edges = new ArrayList<>(); 13 | int cost = 0; 14 | int[] parent = new int[20000]; 15 | int[] rank = new int[20000]; 16 | 17 | private void make_set(int v) { 18 | parent[v] = v; 19 | rank[v] = 0; 20 | } 21 | 22 | private int find_set(int v) { 23 | if (v == parent[v]) { 24 | return v; 25 | } 26 | return parent[v] = find_set(parent[v]); 27 | } 28 | 29 | private void union_sets(int a, int b) { 30 | a = find_set(a); 31 | b = find_set(b); 32 | if (a != b) { 33 | if (rank[a] < rank[b]) { 34 | int c = b; 35 | b = a; 36 | a = c; 37 | } 38 | parent[b] = a; 39 | if (rank[a] == rank[b]) { 40 | rank[a]++; 41 | } 42 | } 43 | } 44 | 45 | public class CustomComparator implements Comparator, Integer>> { 46 | @Override 47 | public int compare(Pair, Integer> o1, Pair, Integer> o2) { 48 | return o1.getValue().compareTo(o2.getValue()); 49 | } 50 | } 51 | 52 | private void input() throws IOException { 53 | n = in.nextInt(); 54 | m = in.nextInt(); 55 | for (int i = 0; i < m; i++) { 56 | edges.add(new Pair<>(new Pair<>(in.nextInt(), in.nextInt()), in.nextInt())); 57 | } 58 | edges.sort(new CustomComparator()); 59 | for (int i = 0; i < n; i++) { 60 | make_set(i); 61 | } 62 | } 63 | 64 | 65 | private void solve() throws IOException { 66 | input(); 67 | for (int i = 0; i < m; i++) { 68 | int from = edges.get(i).getKey().getKey(); 69 | int to = edges.get(i).getKey().getValue(); 70 | int w = edges.get(i).getValue(); 71 | if (find_set(from) != find_set(to)) { 72 | cost += w; 73 | union_sets(from, to); 74 | } 75 | } 76 | output(); 77 | } 78 | 79 | private void output() throws IOException { 80 | out.print(cost); 81 | } 82 | 83 | private void run() { 84 | try { 85 | String fileName = "spantree2"; 86 | in = new FastScanner(new File(fileName + ".in")); 87 | out = new PrintWriter(new File(fileName + ".out")); // PrintWriter(System.out) || new File("output" + ".out") 88 | 89 | solve(); 90 | 91 | out.close(); 92 | } catch (IOException e) { 93 | e.printStackTrace(); 94 | } 95 | } 96 | 97 | class FastScanner { 98 | BufferedReader br; 99 | StringTokenizer st; 100 | 101 | FastScanner(File f) { 102 | try { 103 | br = new BufferedReader(new FileReader(f)); //InputStreamReader(System.in) || new FileReader(f) 104 | } catch (FileNotFoundException e) { 105 | e.printStackTrace(); 106 | } 107 | } 108 | 109 | String next() { 110 | while (st == null || !st.hasMoreTokens()) { 111 | try { 112 | st = new StringTokenizer(br.readLine()); 113 | } catch (IOException e) { 114 | e.printStackTrace(); 115 | } 116 | } 117 | return st.nextToken(); 118 | } 119 | 120 | int nextInt() { 121 | return Integer.parseInt(next()); 122 | } 123 | } 124 | 125 | public static void main(String[] arg) { 126 | new Main().run(); 127 | } 128 | } -------------------------------------------------------------------------------- /term3/Strings/H/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | vector strings; 16 | string t, s; 17 | int n, m, f; 18 | string ans_s = ""; 19 | const unsigned int MAX_N = 1000000 + 50; 20 | 21 | vector ans; 22 | //#define in cin 23 | //#define out cout 24 | ifstream in("search5.in"); 25 | ofstream out("search5.out"); 26 | 27 | int get_letter_index(char ch) { 28 | return ch - 'a'; 29 | } 30 | 31 | class Node { 32 | public: 33 | Node *next[30] = {nullptr}; 34 | Node *links[30] = {nullptr}; 35 | bool term; 36 | char letter_from_parrent; 37 | Node *parent; 38 | Node *suff_link; 39 | Node *nice_suff_link; 40 | vector numb; 41 | int count; 42 | 43 | Node() { 44 | count = 0; 45 | term = false; 46 | letter_from_parrent = -1; 47 | parent = nullptr; 48 | suff_link = nullptr; 49 | nice_suff_link = nullptr; 50 | numb = {}; 51 | } 52 | }; 53 | 54 | Node root; 55 | 56 | Node *next(Node *cur, char ch); 57 | 58 | Node *get_link(Node *cur) { 59 | if (!cur->suff_link) { 60 | if (cur == &root || cur->parent == &root) 61 | cur->suff_link = &root; 62 | else { 63 | cur->suff_link = next(get_link(cur->parent), cur->letter_from_parrent); 64 | if (cur->suff_link->term) { 65 | cur->nice_suff_link = cur->suff_link; 66 | } else { 67 | cur->nice_suff_link = cur->suff_link->nice_suff_link; 68 | } 69 | } 70 | 71 | } 72 | return cur->suff_link; 73 | } 74 | 75 | Node *next(Node *cur, char ch) { 76 | int i = get_letter_index(ch); 77 | if (!cur->links[i]) 78 | if (cur->next[i]) 79 | cur->links[i] = cur->next[i]; 80 | else { 81 | if (cur == &root) 82 | cur->links[i] = &root; 83 | else 84 | cur->links[i] = next(get_link(cur), ch); 85 | } 86 | get_link(cur->links[i]); 87 | return cur->links[i]; 88 | } 89 | 90 | void add_string(string &st, int numb) { 91 | Node *cur = &root; 92 | int i; 93 | for (auto ch: st) { 94 | i = get_letter_index(ch); 95 | if (cur->next[i] == nullptr) { 96 | cur->next[i] = new Node(); 97 | cur->next[i]->parent = cur; 98 | cur->next[i]->letter_from_parrent = ch; 99 | } 100 | cur = cur->next[i]; 101 | } 102 | cur->term = true; 103 | cur->numb.push_back(numb); 104 | } 105 | 106 | 107 | void input() { 108 | in >> n; 109 | for (int i = 0; i < n; ++i) { 110 | in >> s; 111 | add_string(s, i); 112 | } 113 | ans.resize(n, 0); 114 | in >> t; 115 | } 116 | 117 | map was; 118 | 119 | void dfs(Node *v) { 120 | was[v] = true; 121 | for (auto to: v->links) 122 | if (to && !was[to]) { 123 | Node *temp = to; 124 | int count = to->count; 125 | if (count) 126 | while (temp && temp != &root) { 127 | if (temp->term) 128 | for (auto num: temp->numb) 129 | ans[num] += count; 130 | temp = temp->nice_suff_link; 131 | } 132 | dfs(to); 133 | } 134 | } 135 | 136 | void solve() { 137 | Node *cur = &root; 138 | for (int i = 0; i < t.length(); ++i) { 139 | cur = next(cur, t[i]); 140 | ++cur->count; 141 | } 142 | dfs(&root); 143 | } 144 | 145 | void output() { 146 | for (int i = 0; i < n; ++i) 147 | out << ans[i] << "\n"; 148 | } 149 | 150 | int main() { 151 | input(); 152 | solve(); 153 | output(); 154 | return 0; 155 | } -------------------------------------------------------------------------------- /term4/Flow and Matching/C.kt: -------------------------------------------------------------------------------- 1 | import java.io.* 2 | import java.lang.Integer.min 3 | import java.util.* 4 | import kotlin.collections.ArrayList 5 | import kotlin.collections.HashMap 6 | import kotlin.collections.HashSet 7 | 8 | 9 | const val fileName = "snails" 10 | const val MAX_V = 100_000 + 5 11 | const val MAX_E = 100_000 + 5 12 | const val MAX_C = 10_000 + 5 13 | var s = 1 14 | var t = 1 15 | 16 | class FastScanner(f: File) { 17 | private lateinit var br: BufferedReader 18 | private var st: StringTokenizer? = null 19 | 20 | init { 21 | try { 22 | br = BufferedReader(FileReader(f)) 23 | } catch (e: FileNotFoundException) { 24 | e.printStackTrace() 25 | } 26 | 27 | } 28 | 29 | operator fun next(): String { 30 | while (st == null || !st!!.hasMoreTokens()) { 31 | try { 32 | st = StringTokenizer(br.readLine()) 33 | } catch (e: IOException) { 34 | e.printStackTrace() 35 | } 36 | 37 | } 38 | return st!!.nextToken() 39 | } 40 | 41 | fun nextInt(): Int { 42 | return next().toInt() 43 | } 44 | 45 | fun nextDouble(): Double { 46 | return next().toDouble() 47 | } 48 | } 49 | 50 | var inp = FastScanner(File("$fileName.in")) 51 | var out = File("$fileName.out").printWriter() 52 | 53 | class Tube(val v: Int, val c: Int, var flow: Int) 54 | 55 | val edges = Array>(MAX_V, { ArrayList() }) 56 | var n = 0 57 | var m = 0 58 | val edgesBack = HashMap, Tube>() 59 | var maxFlow = 0 60 | val tubes = ArrayList() 61 | 62 | fun input() { 63 | n = inp.nextInt() 64 | m = inp.nextInt() 65 | s = inp.nextInt() 66 | t = inp.nextInt() 67 | for (i in 1..m) { 68 | val v = inp.nextInt() 69 | val u = inp.nextInt() 70 | edges[v].add(Tube(u, 1, 0)) 71 | edges[u].add(Tube(v, 0, 0)) 72 | edgesBack[Pair(v, u)] = edges[u].last() 73 | edgesBack[Pair(u, v)] = edges[v].last() 74 | } 75 | } 76 | 77 | val was = Array(MAX_V, { false }) 78 | 79 | fun updateFlow(v: Int, Cmin: Int): Int { 80 | if (v == t) { 81 | return Cmin 82 | } 83 | was[v] = true 84 | 85 | for (to in edges[v]) { 86 | if (!was[to.v] && to.flow < to.c) { 87 | val delta = updateFlow(to.v, min(Cmin, to.c - to.flow)) 88 | if (delta > 0) { 89 | to.flow += delta 90 | edgesBack[Pair(v, to.v)]!!.flow -= delta 91 | return delta 92 | } 93 | } 94 | } 95 | return 0 96 | } 97 | 98 | fun findMaxFlow() { 99 | while (true) { 100 | was.fill(false) 101 | val pushedFlow = updateFlow(s, 1000_000_000) 102 | maxFlow += pushedFlow 103 | if (pushedFlow == 0) { 104 | break 105 | } 106 | } 107 | } 108 | 109 | fun solve() { 110 | findMaxFlow() 111 | } 112 | 113 | fun output() { 114 | if (maxFlow >= 2) { 115 | out.println("YES") 116 | var to = s 117 | val was = HashSet() 118 | while (to != t) { 119 | out.print(to.toString() + " ") 120 | for (tube in edges[to]) { 121 | if (tube !in was && tube.flow == 1) { 122 | was.add(tube) 123 | to = tube.v 124 | break 125 | } 126 | } 127 | } 128 | to = s 129 | out.println(t) 130 | while (to != t) { 131 | out.print(to.toString() + " ") 132 | for (tube in edges[to]) { 133 | if (tube !in was && tube.flow == 1) { 134 | was.add(tube) 135 | to = tube.v 136 | break 137 | } 138 | } 139 | } 140 | out.println(t) 141 | } else { 142 | out.print("NO") 143 | } 144 | } 145 | 146 | fun main(args: Array) { 147 | try { 148 | input() 149 | solve() 150 | output() 151 | out.close() 152 | } catch (e: IOException) { 153 | e.printStackTrace() 154 | } 155 | } --------------------------------------------------------------------------------