├── .gitignore ├── README.md ├── Z-algorithm ├── step1 │ ├── A.cpp │ ├── B.cpp │ ├── C.cpp │ └── D.cpp ├── step2 │ ├── A.cpp │ ├── B.cpp │ └── C.cpp ├── step3 │ └── A.cpp └── step4 │ ├── A.cpp │ ├── B.cpp │ ├── C.cpp │ ├── D.cpp │ ├── E.cpp │ ├── F.cpp │ ├── G.cpp │ ├── H.cpp │ └── I.cpp ├── binary-search ├── step1 │ ├── A.cpp │ ├── B.cpp │ ├── C.cpp │ └── D.cpp ├── step2 │ ├── A.cpp │ ├── B.cpp │ ├── C.cpp │ ├── D.cpp │ ├── E.cpp │ ├── F.cpp │ ├── G.cpp │ └── H.cpp ├── step3 │ ├── A.cpp │ ├── B.cpp │ ├── C.cpp │ └── D.cpp ├── step4 │ ├── A.cpp │ ├── B.cpp │ └── C.cpp └── step5 │ ├── A.cpp │ ├── B.cpp │ └── C.cpp ├── disjoint-set-union ├── step1 │ ├── A.cpp │ ├── B.cpp │ ├── C.cpp │ ├── D.cpp │ └── E.cpp ├── step2 │ ├── A.cpp │ ├── B.cpp │ ├── C.cpp │ ├── D.cpp │ ├── E.cpp │ ├── F.cpp │ ├── G.cpp │ ├── H.cpp │ ├── I.cpp │ └── J.cpp └── step3 │ ├── A.cpp │ ├── B.cpp │ └── C.cpp ├── graph-theory └── step1 │ ├── A.cpp │ ├── B.cpp │ ├── C.cpp │ └── D.cpp ├── segment-tree-part1 ├── step1 │ ├── A.cpp │ ├── B.cpp │ └── C.cpp ├── step2 │ ├── A.cpp │ ├── B.cpp │ ├── C.cpp │ └── D.cpp ├── step3 │ ├── A.cpp │ ├── B.cpp │ ├── C.cpp │ ├── D.cpp │ └── E.cpp └── step4 │ ├── A.cpp │ ├── B.cpp │ ├── C.cpp │ ├── D.cpp │ └── E.cpp ├── segment-tree-part2 ├── step1 │ ├── A.cpp │ ├── B.cpp │ └── C.cpp ├── step2 │ ├── A.cpp │ ├── B.cpp │ ├── C.cpp │ ├── D.cpp │ ├── E.cpp │ └── F.cpp ├── step3 │ ├── A.cpp │ ├── B.cpp │ └── C.cpp └── step4 │ ├── A.cpp │ ├── B.cpp │ ├── C.cpp │ ├── D.cpp │ └── E.cpp ├── suffix-array ├── step1 │ └── A.cpp ├── step2 │ └── A.cpp ├── step3 │ ├── A.cpp │ └── B.cpp ├── step4 │ └── A.cpp └── step5 │ ├── A.cpp │ ├── B.cpp │ └── C.cpp └── two-pointers-method └── step1 ├── A.cpp ├── B.cpp └── C.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # codeforces-edu 2 | https://codeforces.com/edu/course/2 [ITMO Academy: пилотный курс] 3 | -------------------------------------------------------------------------------- /Z-algorithm/step1/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | int main(void) { 6 | int n; 7 | string input; 8 | 9 | cin >> n; 10 | 11 | while (n--) { 12 | cin >> input; 13 | int best = 1; 14 | 15 | for (int i = input.size() - 1; i >= 1; i--) { 16 | bool ok = true; 17 | for (int a = 0; i - a >= a; a++) { 18 | if (input[i-a] != input[a]) { 19 | ok = false; 20 | break; 21 | } 22 | } 23 | if (ok) { 24 | best = i + 1; 25 | break; 26 | } 27 | } 28 | 29 | cout << best << endl; 30 | } 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /Z-algorithm/step1/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | int main(void) { 6 | int n; 7 | string input; 8 | 9 | cin >> n; 10 | 11 | while (n--) { 12 | cin >> input; 13 | 14 | int result = 0; 15 | 16 | for (int i = 0; i < input.size(); i++) { 17 | for (int j = i; j < input.size(); j++) { 18 | bool prefix = true; 19 | bool suffix = true; 20 | for (int k = i; k <= j; k++) { 21 | // prefix 22 | if (input[k] != input[k-i]) { 23 | prefix = false; 24 | } 25 | // suffix 26 | if (input[k] != input[input.size() - 1 - j + k]) { 27 | suffix = false; 28 | } 29 | 30 | if (!prefix && !suffix) { 31 | break; 32 | } 33 | } 34 | 35 | if ((prefix && suffix) || (!prefix && !suffix)) { 36 | continue; 37 | } 38 | 39 | result++; 40 | } 41 | } 42 | 43 | cout << result << endl; 44 | } 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /Z-algorithm/step1/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | int main(void) { 7 | int n; 8 | string input, joker; 9 | 10 | cin >> n; 11 | 12 | while (n--) { 13 | cin >> input; 14 | cin >> joker; 15 | 16 | int count = 0; 17 | vector indexes; 18 | 19 | for (int i = 0; i < input.size(); i++) { 20 | bool ok = true; 21 | for (int j = 0; j < joker.size(); j++) { 22 | if (i + j >= input.size()) { 23 | ok = false; 24 | break; 25 | } 26 | if (joker[j] == '?') { 27 | continue; 28 | } 29 | if (input[i+j] != joker[j]) { 30 | ok = false; 31 | break; 32 | } 33 | } 34 | if (ok) { 35 | count++; 36 | indexes.push_back(i); 37 | } 38 | } 39 | 40 | cout << count << endl; 41 | for (int i = 0; i < indexes.size(); i++) { 42 | if (i > 0) cout << " "; 43 | cout << indexes[i]; 44 | } 45 | cout << endl; 46 | } 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /Z-algorithm/step1/D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | int main(void) { 7 | int n; 8 | string input; 9 | string str; 10 | 11 | cin >> n; 12 | 13 | while (n--) { 14 | cin >> input; 15 | cin >> str; 16 | 17 | int count = 0; 18 | 19 | if (str.size() > input.size()) { 20 | count = input.size() * (1 + input.size()) / 2; 21 | } else { 22 | for (int i = 1; i < str.size(); i++) { 23 | count += input.size() - i + 1; 24 | } 25 | 26 | int start = 0; 27 | 28 | for (int i = 0; i < input.size(); i++) { 29 | bool ok = true; 30 | for (int j = 0; j < str.size(); j++) { 31 | if (i + j >= input.size()) { 32 | ok = false; 33 | break; 34 | } 35 | if (input[i + j] != str[j]) { 36 | ok = false; 37 | break; 38 | } 39 | } 40 | 41 | if (ok) { 42 | int end = i + str.size() - 1; 43 | int len = end - start; 44 | for (int x = str.size(); x <= len; x++) { 45 | count += len - x + 1; 46 | } 47 | start = i + 1; 48 | } 49 | } 50 | 51 | int end = input.size() - 1; 52 | int len = end - start + 1; 53 | for (int x = str.size(); x <= len; x++) { 54 | count += len - x + 1; 55 | } 56 | } 57 | 58 | cout << count << endl; 59 | } 60 | 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /Z-algorithm/step2/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | int main(void) { 7 | string input; 8 | 9 | cin >> input; 10 | 11 | vector v(input.size()); 12 | 13 | for (int i = 0; i < input.size(); i++) { 14 | v[i] = 0; 15 | } 16 | 17 | for (int i = 1; i < input.size(); i++) { 18 | while (v[i] + i < input.size() && input[i + v[i]] == input[v[i]]) { 19 | v[i]++; 20 | } 21 | } 22 | 23 | for (int i = 0; i < input.size(); i++) { 24 | if (i > 0) cout << " "; 25 | cout << v[i]; 26 | } 27 | cout << endl; 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /Z-algorithm/step2/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | int main(void) { 7 | int t; 8 | vector gray; 9 | 10 | gray.push_back("a"); 11 | int idx = 1; 12 | for (char c = 'b'; c <= 'z'; c++) { 13 | gray.push_back(gray[idx-1] + c + gray[idx-1]); 14 | idx++; 15 | } 16 | 17 | cin >> t; 18 | 19 | while (t--) { 20 | int k, j; 21 | cin >> k >> j; 22 | 23 | if (j == 0) { 24 | cout << 0 << endl; 25 | } else { 26 | int result = 0; 27 | 28 | while (result + j < gray[k-1].size() && gray[k-1][j + result] == gray[k-1][result]) { 29 | result++; 30 | } 31 | 32 | cout << result << endl; 33 | } 34 | } 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /Z-algorithm/step2/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | int main(void) { 7 | int t; 8 | string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 9 | 10 | cin >> t; 11 | 12 | while (t--) { 13 | int len; 14 | cin >> len; 15 | 16 | vector z(len); 17 | string result = ""; 18 | 19 | bool ok = true; 20 | 21 | for (int i = 0; i < len; i++) { 22 | cin >> z[i]; 23 | if (z[i] >= len) { 24 | ok = false; 25 | } 26 | result += chars[i]; 27 | } 28 | 29 | if (z[0] != 0) { 30 | ok = false; 31 | } 32 | 33 | if (!ok) { 34 | cout << "!" << endl; 35 | } else { 36 | for (int i = 1; i < len; i++) { 37 | if (z[i] > 0) { 38 | for (int j = 0; j < z[i]; j++) { 39 | result[i+j] = result[j]; 40 | } 41 | } 42 | } 43 | 44 | if (!ok) { 45 | cout << "!" << endl; 46 | } else { 47 | vector test(len); 48 | for (int i = 0; i < len; i++) { 49 | test[i] = 0; 50 | } 51 | 52 | for (int i = 1; i < len; i++) { 53 | while (test[i] + i < len && result[test[i] + i] == result[test[i]]) { 54 | test[i]++; 55 | } 56 | } 57 | 58 | for (int i = 0; i < len; i++) { 59 | if (z[i] != test[i]) { 60 | ok = false; 61 | break; 62 | } 63 | } 64 | 65 | if (!ok) { 66 | cout << "!" << endl; 67 | } else { 68 | cout << result << endl; 69 | } 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Z-algorithm/step3/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | int main(void) { 11 | string input; 12 | 13 | cin >> input; 14 | 15 | vector z(input.size()); 16 | 17 | for (int i = 1, l = 0, r = 0; i < input.size(); i++) { 18 | if (i <= r) { 19 | z[i] = min(z[i-l], r - i + 1); 20 | } 21 | while (i + z[i] < input.size() && input[z[i]] == input[i+z[i]]) { 22 | z[i]++; 23 | } 24 | if (i + z[i] - 1 > r) { 25 | l = i; 26 | r = i + z[i] - 1; 27 | } 28 | } 29 | 30 | for (int i = 0; i < input.size(); i++) { 31 | if (i > 0) cout << " "; 32 | cout << z[i]; 33 | } 34 | cout << endl; 35 | } 36 | -------------------------------------------------------------------------------- /Z-algorithm/step4/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | using namespace std; 15 | 16 | #define ll long long 17 | #define pb push_back 18 | #define loop(a) for(int i = 0; i < a; i++) 19 | #define loopv(i,a) for (int i = 0; i < a; i++) 20 | #define all(x) (x).begin(), (x).end() 21 | #define prDouble(x) cout << fixed << setprecision(10) << x 22 | #define goog(tno) cout << "Case #" << tno <<": " 23 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 24 | 25 | const int maxN = 1e6; 26 | char input[maxN+1]; 27 | int z[maxN]; 28 | 29 | int main(void) { 30 | int t; 31 | cin >> t; 32 | 33 | while (t--) { 34 | scanf("%s", input); 35 | 36 | int l = 0, r = 0; 37 | int n = strlen(input); 38 | int result = -1; 39 | for (int i = 1; i < n; i++) { 40 | z[i] = 0; 41 | 42 | if (r >= i) 43 | z[i] = min(z[i - l], r - i + 1); 44 | 45 | while (i + z[i] < n && input[z[i]] == input[z[i] + i]) 46 | z[i]++; 47 | 48 | if (i + z[i] - 1 > r) { 49 | l = i; 50 | r = i + z[i] - 1; 51 | } 52 | 53 | if (i + z[i] == n) { 54 | result = i; 55 | break; 56 | } 57 | } 58 | 59 | if (result == -1) { 60 | printf("%s\n", input); 61 | } else { 62 | printf("%.*s\n", result, input); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Z-algorithm/step4/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | using namespace std; 15 | 16 | #define ll long long 17 | #define pb push_back 18 | #define loop(a) for(int i = 0; i < a; i++) 19 | #define loopv(i,a) for (int i = 0; i < a; i++) 20 | #define all(x) (x).begin(), (x).end() 21 | #define prDouble(x) cout << fixed << setprecision(10) << x 22 | #define goog(tno) cout << "Case #" << tno <<": " 23 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 24 | 25 | const int maxN = 3e6+5; 26 | int z[maxN]; 27 | 28 | int main(void) { 29 | fast_io; 30 | 31 | int q; 32 | cin >> q; 33 | 34 | while (q--) { 35 | string s, t; 36 | cin >> s >> t; 37 | 38 | string x = t + "$" + s + s; 39 | int n = x.size(); 40 | 41 | int result = -1; 42 | int r = 0, l = 0; 43 | for (int i = 1; i < n; i++) { 44 | z[i] = 0; 45 | 46 | if (r >= i) { 47 | z[i] = min(z[i - l], r - i + 1); 48 | } 49 | 50 | while (i + z[i] < n && x[z[i]] == x[i + z[i]]) 51 | z[i]++; 52 | 53 | if (i + z[i] - 1 > r) { 54 | l = i; 55 | r = i + z[i] - 1; 56 | } 57 | 58 | if (z[i] == t.size()) { 59 | result = i - t.size() - 1; 60 | break; 61 | } 62 | } 63 | 64 | cout << result << endl; 65 | } 66 | 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /Z-algorithm/step4/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | using namespace std; 15 | 16 | #define ll long long 17 | #define pb push_back 18 | #define loop(a) for(int i = 0; i < a; i++) 19 | #define loopv(i,a) for (int i = 0; i < a; i++) 20 | #define all(x) (x).begin(), (x).end() 21 | #define prDouble(x) cout << fixed << setprecision(10) << x 22 | #define goog(tno) cout << "Case #" << tno <<": " 23 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 24 | 25 | const int maxN = 1e6; 26 | int z[maxN]; 27 | int counter[maxN], result[maxN]; 28 | 29 | int main(void) { 30 | fast_io; 31 | 32 | int q; 33 | cin >> q; 34 | 35 | while (q--) { 36 | string input; 37 | cin >> input; 38 | 39 | int l = 0, r = 0; 40 | int n = input.size(); 41 | for (int i = 1; i < n; i++) { 42 | z[i] = 0; 43 | 44 | if (r >= i) 45 | z[i] = min(z[i - l], r - i + 1); 46 | 47 | while (i + z[i] < n && input[z[i]] == input[i + z[i]]) 48 | z[i]++; 49 | 50 | if (r < i + z[i] - 1) { 51 | l = i; 52 | r = i + z[i] - 1; 53 | } 54 | 55 | if (z[i] > 0) 56 | counter[z[i]]++; 57 | } 58 | 59 | int sum = 0; 60 | for (int i = n - 1; i > 0; i--) { 61 | result[i-1] = sum + counter[i]; 62 | sum += counter[i]; 63 | counter[i] = 0; 64 | } 65 | 66 | for (int i = 0; i < n; i++) { 67 | if (i > 0) cout << " "; 68 | cout << result[i] + 1; 69 | result[i] = 0; 70 | } 71 | cout << endl; 72 | } 73 | 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /Z-algorithm/step4/D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | using namespace std; 15 | 16 | #define ll long long 17 | #define pb push_back 18 | #define loop(a) for(int i = 0; i < a; i++) 19 | #define loopv(i,a) for (int i = 0; i < a; i++) 20 | #define all(x) (x).begin(), (x).end() 21 | #define prDouble(x) cout << fixed << setprecision(10) << x 22 | #define goog(tno) cout << "Case #" << tno <<": " 23 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 24 | 25 | const int maxN = 1e6; 26 | int z[maxN]; 27 | 28 | int main(void) { 29 | fast_io; 30 | 31 | string input; 32 | 33 | cin >> input; 34 | 35 | string x = input; 36 | reverse(input.begin(), input.end()); 37 | x += "$" + input; 38 | 39 | int n = x.size(); 40 | 41 | int l = 0, r = 0; 42 | for (int i = 1; i < n; i++) { 43 | if (r >= i) 44 | z[i] = min(z[i - l], r - i + 1); 45 | 46 | while (i + z[i] < n && x[z[i]] == x[i + z[i]]) 47 | z[i]++; 48 | 49 | if (r < i + z[i] - 1) { 50 | l = i; 51 | r = i + z[i] - 1; 52 | } 53 | 54 | if (i + z[i] == n) { 55 | cout << z[i] << endl; 56 | break; 57 | } 58 | } 59 | 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /Z-algorithm/step4/E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | using namespace std; 15 | 16 | #define ll long long 17 | #define pb push_back 18 | #define loop(a) for(int i = 0; i < a; i++) 19 | #define loopv(i,a) for (int i = 0; i < a; i++) 20 | #define all(x) (x).begin(), (x).end() 21 | #define prDouble(x) cout << fixed << setprecision(10) << x 22 | #define goog(tno) cout << "Case #" << tno <<": " 23 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 24 | 25 | const int maxN = 1e5+100; 26 | int z1[maxN]; 27 | int z2[maxN]; 28 | 29 | int main(void) { 30 | fast_io; 31 | 32 | string s, t; 33 | cin >> s >> t; 34 | 35 | if (s.size() != t.size()) { 36 | cout << "No" << endl; 37 | return 0; 38 | } 39 | 40 | string a = t + "$" + s; 41 | reverse(t.begin(), t.end()); 42 | string b = t + "$" + s; 43 | 44 | int n = a.size(); 45 | int l = 0, r = 0; 46 | for (int i = 1; i < n; i++) { 47 | z1[i] = 0; 48 | 49 | if (r >= i) 50 | z1[i] = min(z1[i - l], r - i + 1); 51 | 52 | while (i + z1[i] < n && a[z1[i]] == a[i + z1[i]]) 53 | z1[i]++; 54 | 55 | if (r < i + z1[i] - 1) { 56 | l = i; 57 | r = i + z1[i] - 1; 58 | } 59 | } 60 | 61 | l = r = 0; 62 | for (int i = 1; i < n; i++) { 63 | z2[i] = 0; 64 | 65 | if (r >= i) 66 | z2[i] = min(z2[i - l], r - i + 1); 67 | 68 | while (i + z2[i] < n && b[z2[i]] == b[i + z2[i]]) 69 | z2[i]++; 70 | 71 | if (r < i + z2[i] - 1) { 72 | l = i; 73 | r = i + z2[i] - 1; 74 | } 75 | } 76 | 77 | int N = s.size(); 78 | int result = -1; 79 | for (int i = 0; i <= s.size(); i++) { 80 | if ((i == N || z1[N+i+1] == N-i) && z2[N+1] >= i) { 81 | result = i; 82 | break; 83 | } 84 | } 85 | 86 | 87 | 88 | if (result == -1) { 89 | cout << "No" << endl; 90 | } else { 91 | cout << "Yes" << endl; 92 | cout << result << endl; 93 | } 94 | 95 | return 0; 96 | } 97 | -------------------------------------------------------------------------------- /Z-algorithm/step4/F.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | using namespace std; 15 | 16 | #define ll long long 17 | #define pb push_back 18 | #define loop(a) for(int i = 0; i < a; i++) 19 | #define loopv(i,a) for (int i = 0; i < a; i++) 20 | #define all(x) (x).begin(), (x).end() 21 | #define prDouble(x) cout << fixed << setprecision(10) << x 22 | #define goog(tno) cout << "Case #" << tno <<": " 23 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 24 | 25 | const int maxN = 2e6+10; 26 | int z1[maxN]; 27 | int z2[maxN]; 28 | 29 | int main(void) { 30 | fast_io; 31 | int q; 32 | string a, b; 33 | 34 | cin >> q; 35 | while (q--) { 36 | cin >> a >> b; 37 | string aa = a + "$" + b; 38 | string bb = b + "$" + a; 39 | 40 | int z1max = 0; 41 | int z2max = 0; 42 | 43 | int l = 0, r = 0; 44 | int n = aa.size(); 45 | for (int i = 1; i < n; i++) { 46 | z1[i] = 0; 47 | 48 | if (r >= i) 49 | z1[i] = min(z1[i - l], r - i + 1); 50 | 51 | while (i + z1[i] < n && aa[z1[i]] == aa[i+z1[i]]) 52 | z1[i]++; 53 | 54 | if (i > a.size()) { 55 | if (z1[i] == a.size()) { 56 | z1max = z1[i]; 57 | } else if (i + z1[i] == aa.size()) { 58 | z1max = max(z1max, z1[i]); 59 | } 60 | } 61 | 62 | if (r < i + z1[i] - 1) { 63 | l = i; 64 | r = i + z1[i] - 1; 65 | } 66 | } 67 | 68 | l = r = 0; 69 | for (int i = 1; i < n; i++) { 70 | z2[i] = 0; 71 | 72 | if (r >= i) 73 | z2[i] = min(z2[i - l], r - i + 1); 74 | 75 | while (i + z2[i] < n && bb[z2[i]] == bb[i+z2[i]]) 76 | z2[i]++; 77 | 78 | if (i > b.size()) { 79 | if (z2[i] == b.size()) { 80 | z2max = z2[i]; 81 | } else if (i + z2[i] == bb.size()) { 82 | z2max = max(z2max, z2[i]); 83 | } 84 | } 85 | 86 | if (r < i + z2[i] - 1) { 87 | l = i; 88 | r = i + z2[i] - 1; 89 | } 90 | } 91 | 92 | if (z1max == a.size()) { 93 | cout << b << endl; 94 | } else if (z2max == b.size()) { 95 | cout << a << endl; 96 | } else if (z1max >= z2max) { 97 | cout << b.substr(0, b.size() - z1max) << a << endl; 98 | } else { 99 | cout << a.substr(0, a.size() - z2max) << b << endl; 100 | } 101 | } 102 | 103 | return 0; 104 | } 105 | -------------------------------------------------------------------------------- /Z-algorithm/step4/G.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | using namespace std; 15 | 16 | #define ll long long 17 | #define pb push_back 18 | #define loop(a) for(int i = 0; i < a; i++) 19 | #define loopv(i,a) for (int i = 0; i < a; i++) 20 | #define all(x) (x).begin(), (x).end() 21 | #define prDouble(x) cout << fixed << setprecision(10) << x 22 | #define goog(tno) cout << "Case #" << tno <<": " 23 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 24 | 25 | const int maxN = 1e5, maxM = 1e5; 26 | int cubes[2*maxN+5]; 27 | int z[2*maxN+5]; 28 | 29 | int main(void) { 30 | fast_io; 31 | int n; 32 | int m; 33 | cin >> n >> m; 34 | 35 | loop(n) { 36 | cin >> cubes[i]; 37 | } 38 | cubes[n] = maxM + 1; 39 | for (int i = n - 1; i >= 0; i--) { 40 | cubes[n+n-i] = cubes[i]; 41 | } 42 | 43 | int l = 0, r = 0; 44 | int N = n + n + 1; 45 | 46 | /* 47 | cout << "N = " << N << endl; 48 | loop(N) { 49 | cout << cubes[i] << " "; 50 | } 51 | cout << endl; 52 | */ 53 | 54 | for (int i = 1; i < N; i++) { 55 | if (r >= i) { 56 | z[i] = min(z[i - l], r - i + 1); 57 | } 58 | 59 | while (i + z[i] < N && cubes[z[i]] == cubes[i + z[i]]) 60 | z[i]++; 61 | 62 | if (r < i + z[i] - 1) { 63 | l = i; 64 | r = i + z[i] - 1; 65 | } 66 | } 67 | 68 | /* 69 | for (int i = 0; i < N; i++) { 70 | cout << z[i] << " "; 71 | } 72 | cout << endl; 73 | */ 74 | 75 | bool first = true; 76 | int x = n / 2; 77 | for (int i = x; i >= 1; i--) { 78 | if (z[N-2*i] >= i) { 79 | if (!first) cout << " "; 80 | first = false; 81 | cout << n - i; 82 | } 83 | } 84 | if (!first) cout << " "; 85 | cout << n << endl; 86 | 87 | return 0; 88 | } 89 | -------------------------------------------------------------------------------- /Z-algorithm/step4/H.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | using namespace std; 15 | 16 | #define ll long long 17 | #define pb push_back 18 | #define loop(a) for(int i = 0; i < a; i++) 19 | #define loopv(i,a) for (int i = 0; i < a; i++) 20 | #define all(x) (x).begin(), (x).end() 21 | #define prDouble(x) cout << fixed << setprecision(10) << x 22 | #define goog(tno) cout << "Case #" << tno <<": " 23 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 24 | 25 | int z[8001]; 26 | 27 | ll calc(string s) { 28 | int l = 0, r = 0; 29 | int best = 0; 30 | ll result = 0; 31 | for (int i = 1; i < s.size(); i++) { 32 | z[i] = 0; 33 | if (r >= i) { 34 | z[i] = min(z[i - l], r - i + 1); 35 | } 36 | 37 | while (i + z[i] < s.size() && s[z[i]] == s[i + z[i]]) 38 | z[i]++; 39 | 40 | best = max(best, z[i]); 41 | 42 | if (r < i + z[i] - 1) { 43 | l = i; 44 | r = i + z[i] - 1; 45 | } 46 | } 47 | 48 | for (int i = best + 1; i <= s.size(); i++) { 49 | result += i; 50 | } 51 | 52 | return result; 53 | } 54 | 55 | int main(void) { 56 | fast_io; 57 | string input; 58 | 59 | cin >> input; 60 | 61 | ll sum = 0; 62 | int n = input.size(); 63 | for (int i = n - 1; i >= 0; i--) { 64 | sum += calc(input.substr(i)); 65 | } 66 | cout << sum << endl; 67 | 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /Z-algorithm/step4/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 | #include 13 | #include 14 | using namespace std; 15 | 16 | #define ll long long 17 | #define pb push_back 18 | #define loop(a) for(int i = 0; i < a; i++) 19 | #define loopv(i,a) for (int i = 0; i < a; i++) 20 | #define all(x) (x).begin(), (x).end() 21 | #define prDouble(x) cout << fixed << setprecision(10) << x 22 | #define goog(tno) cout << "Case #" << tno <<": " 23 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 24 | 25 | const int maxN = 1e6; 26 | int z1[2*maxN+5]; 27 | int z2[2*maxN+5]; 28 | 29 | int main(void) { 30 | fast_io; 31 | 32 | int k; 33 | string t, p; 34 | cin >> t >> p >> k; 35 | 36 | string a = p + "$" + t; 37 | reverse(t.begin(), t.end()); 38 | reverse(p.begin(), p.end()); 39 | string b = p + "$" + t; 40 | 41 | int n = a.size(); 42 | int l = 0, r = 0; 43 | for (int i = 1; i < n; i++) { 44 | if (r >= i) { 45 | z1[i] = min(z1[i - l], r - i + 1); 46 | } 47 | 48 | while (i + z1[i] < n && a[z1[i]] == a[i + z1[i]]) 49 | z1[i]++; 50 | 51 | if (r < i + z1[i] - 1) { 52 | l = i; 53 | r = i + z1[i] - 1; 54 | } 55 | } 56 | 57 | l = r = 0; 58 | for (int i = 1; i < n; i++) { 59 | if (r >= i) { 60 | z2[i] = min(z2[i - l], r - i + 1); 61 | } 62 | 63 | while (i + z2[i] < n && b[z2[i]] == b[i + z2[i]]) 64 | z2[i]++; 65 | 66 | if (r < i + z2[i] - 1) { 67 | l = i; 68 | r = i + z2[i] - 1; 69 | } 70 | } 71 | 72 | /* 73 | cout << a << endl; 74 | cout << b << endl; 75 | for (int i = 0; i < n; i++) { 76 | cout << z1[i] << " "; 77 | } 78 | cout << endl; 79 | for (int i = 0; i < n; i++) { 80 | cout << z2[i] << " "; 81 | } 82 | cout << endl; 83 | */ 84 | 85 | int count = 0; 86 | vector idx; 87 | /* 88 | cout << "n = " << n << endl; 89 | cout << "i < " << n - p.size() << endl; 90 | */ 91 | for (int i = p.size() + 1; i < n - p.size() + 1; i++) { 92 | //cout << " i = " << i << " z1[i] = " << z1[i] << " z2[n-z1[i]] = " << z2[n-(i-p.size()-1)-z1[i]-(p.size() - z1[i])] << endl; 93 | if (z1[i] + k >= p.size()) { 94 | //cout << "!!!!!" << endl; 95 | count++; 96 | idx.push_back(i - p.size()); 97 | } else if (z1[i] + k + z2[n-i+1] >= p.size()) { 98 | //cout << "????" << endl; 99 | count++; 100 | idx.push_back(i - p.size()); 101 | } 102 | } 103 | 104 | cout << count << endl; 105 | for (int i = 0; i < idx.size(); i++) { 106 | if (i > 0) cout << " "; 107 | cout << idx[i]; 108 | } 109 | cout << endl; 110 | 111 | return 0; 112 | } 113 | -------------------------------------------------------------------------------- /binary-search/step1/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | #define ll long long 20 | #define pb push_back 21 | #define loop(a) for(int i = 0; i < a; i++) 22 | #define loopv(i,a) for (int i = 0; i < a; i++) 23 | #define rep(i,a,b) for (int i = a; i < b; i++) 24 | #define all(x) (x).begin(), (x).end() 25 | #define prDouble(x) cout << fixed << setprecision(10) << x 26 | #define goog(tno) cout << "Case #" << tno <<": " 27 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 28 | 29 | int find_lower(vector& v, int x) { 30 | int l = - 1, r = v.size(); 31 | 32 | while (r > l + 1) { 33 | int m = (l + r) / 2; 34 | if (v[m] > x) r = m; 35 | else l = m; 36 | } 37 | 38 | return l; 39 | } 40 | 41 | bool find(vector& v, int x) { 42 | int i = find_lower(v, x); 43 | return i >= 0 && v[i] == x; 44 | } 45 | 46 | int main(void) { 47 | int n, k; 48 | 49 | cin >> n >> k; 50 | 51 | vector nums(n); 52 | for (auto& x : nums) { 53 | cin >> x; 54 | } 55 | 56 | while (k--) { 57 | int x; 58 | cin >> x; 59 | if (find(nums, x)) cout << "YES" << endl; 60 | else cout << "NO" << endl; 61 | } 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /binary-search/step1/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | #define ll long long 20 | #define pb push_back 21 | #define loop(a) for(int i = 0; i < a; i++) 22 | #define loopv(i,a) for (int i = 0; i < a; i++) 23 | #define rep(i,a,b) for (int i = a; i < b; i++) 24 | #define all(x) (x).begin(), (x).end() 25 | #define prDouble(x) cout << fixed << setprecision(10) << x 26 | #define goog(tno) cout << "Case #" << tno <<": " 27 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 28 | 29 | int find_lower(vector& v, int x) { 30 | int l = -1, r = v.size(); 31 | while (r > l + 1) { 32 | int m = (l + r) / 2; 33 | if (v[m] > x) r = m; 34 | else l = m; 35 | } 36 | return l; 37 | } 38 | 39 | int main(void) { 40 | int n, k; 41 | 42 | cin >> n >> k; 43 | 44 | vector v(n); 45 | for (auto& x : v) { 46 | cin >> x; 47 | } 48 | 49 | while (k--) { 50 | int x; 51 | cin >> x; 52 | cout << find_lower(v, x) + 1 << endl; 53 | } 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /binary-search/step1/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | #define ll long long 20 | #define pb push_back 21 | #define loop(a) for(int i = 0; i < a; i++) 22 | #define loopv(i,a) for (int i = 0; i < a; i++) 23 | #define rep(i,a,b) for (int i = a; i < b; i++) 24 | #define all(x) (x).begin(), (x).end() 25 | #define prDouble(x) cout << fixed << setprecision(10) << x 26 | #define goog(tno) cout << "Case #" << tno <<": " 27 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 28 | 29 | int find_upper(vector& v, int x) { 30 | int l = -1, r = v.size(); 31 | while (r > l + 1) { 32 | int m = (l + r) / 2; 33 | if (v[m] < x) l = m; 34 | else r = m; 35 | } 36 | return r; 37 | } 38 | 39 | int main(void) { 40 | int n, k; 41 | 42 | cin >> n >> k; 43 | 44 | vector v(n); 45 | for (auto& x : v) { 46 | cin >> x; 47 | } 48 | 49 | while (k--) { 50 | int x; 51 | cin >> x; 52 | cout << find_upper(v, x) + 1 << endl; 53 | } 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /binary-search/step1/D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | #define ll long long 20 | #define pb push_back 21 | #define loop(a) for(int i = 0; i < a; i++) 22 | #define loopv(i,a) for (int i = 0; i < a; i++) 23 | #define rep(i,a,b) for (int i = a; i < b; i++) 24 | #define all(x) (x).begin(), (x).end() 25 | #define prDouble(x) cout << fixed << setprecision(10) << x 26 | #define goog(tno) cout << "Case #" << tno <<": " 27 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 28 | 29 | int find_lower(vector& v, int x) { 30 | int l = -1, r = v.size(); 31 | while (r > l + 1) { 32 | int m = (l + r) / 2; 33 | if (v[m] > x) r = m; 34 | else l = m; 35 | } 36 | return l; 37 | } 38 | 39 | int find_upper(vector& v, int x) { 40 | int l = -1, r = v.size(); 41 | while (r > l + 1) { 42 | int m = (l + r) / 2; 43 | if (v[m] < x) l = m; 44 | else r = m; 45 | } 46 | return r; 47 | } 48 | 49 | int main(void) { 50 | int n; 51 | cin >> n; 52 | 53 | vector v(n); 54 | for (auto& x : v) { 55 | cin >> x; 56 | } 57 | 58 | sort(v.begin(), v.end()); 59 | 60 | int k; 61 | cin >> k; 62 | 63 | int l, r; 64 | while (k--) { 65 | cin >> l >> r; 66 | int a = find_upper(v, l); 67 | int b = find_lower(v, r); 68 | 69 | cout << b - a + 1; 70 | if (k) cout << " "; 71 | } 72 | cout << endl; 73 | 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /binary-search/step2/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | #define ll long long 20 | #define pb push_back 21 | #define loop(a) for(int i = 0; i < a; i++) 22 | #define loopv(i,a) for (int i = 0; i < a; i++) 23 | #define rep(i,a,b) for (int i = a; i < b; i++) 24 | #define all(x) (x).begin(), (x).end() 25 | #define prDouble(x) cout << fixed << setprecision(10) << x 26 | #define goog(tno) cout << "Case #" << tno <<": " 27 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 28 | 29 | bool good(ll w, ll h, ll n, ll m) { 30 | return (m / w) * (m / h) >= n; 31 | } 32 | 33 | int main(void) { 34 | ll w, h, n; 35 | 36 | cin >> w >> h >> n; 37 | ll l = 0, r = 1; 38 | while (!good(w, h, n, r)) { 39 | r *= 2; 40 | } 41 | 42 | while (r > l + 1) { 43 | ll m = (l + r) / 2; 44 | if (good(w, h, n, m)) { 45 | r = m; 46 | } else { 47 | l = m; 48 | } 49 | } 50 | 51 | cout << r << endl; 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /binary-search/step2/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | #define ll long long 20 | #define pb push_back 21 | #define loop(a) for(int i = 0; i < a; i++) 22 | #define loopv(i,a) for (int i = 0; i < a; i++) 23 | #define rep(i,a,b) for (int i = a; i < b; i++) 24 | #define all(x) (x).begin(), (x).end() 25 | #define prDouble(x) cout << fixed << setprecision(10) << x 26 | #define goog(tno) cout << "Case #" << tno <<": " 27 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 28 | 29 | int main(void) { 30 | int n, k; 31 | cin >> n >> k; 32 | 33 | vector v(n); 34 | for (auto& x: v) { 35 | cin >> x; 36 | } 37 | 38 | double l = 0; 39 | double r = 1e8; 40 | 41 | for (int i = 0; i < 100; i++) { 42 | double m = (l + r) / 2; 43 | int s = 0; 44 | for (int j = 0; j < n; j++) { 45 | s += (int)(v[j] / m); 46 | } 47 | if (s >= k) { 48 | l = m; 49 | } else { 50 | r = m; 51 | } 52 | } 53 | 54 | cout << setprecision(10) << l << endl; 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /binary-search/step2/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | #define ll long long 20 | #define pb push_back 21 | #define loop(a) for(int i = 0; i < a; i++) 22 | #define loopv(i,a) for (int i = 0; i < a; i++) 23 | #define rep(i,a,b) for (int i = a; i < b; i++) 24 | #define all(x) (x).begin(), (x).end() 25 | #define prDouble(x) cout << fixed << setprecision(10) << x 26 | #define goog(tno) cout << "Case #" << tno <<": " 27 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 28 | 29 | bool good(ll n, ll x, ll y, ll m) { 30 | ll lowest = min(x, y); 31 | if (m < lowest) return false; 32 | 33 | ll result = 1; 34 | m -= lowest; 35 | result += m / x; 36 | result += m / y; 37 | return result >= n; 38 | } 39 | 40 | int main(void) { 41 | ll n, x, y; 42 | cin >> n >> x >> y; 43 | 44 | ll l = 0; 45 | ll r = 2e9+5; 46 | 47 | while (r > l + 1) { 48 | ll m = (l + r) / 2; 49 | if (good(n, x, y, m)) { 50 | r = m; 51 | } else { 52 | l = m; 53 | } 54 | } 55 | 56 | cout << r << endl; 57 | 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /binary-search/step2/D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | #define ll long long 20 | #define pb push_back 21 | #define loop(a) for(int i = 0; i < a; i++) 22 | #define loopv(i,a) for (int i = 0; i < a; i++) 23 | #define rep(i,a,b) for (int i = a; i < b; i++) 24 | #define all(x) (x).begin(), (x).end() 25 | #define prDouble(x) cout << fixed << setprecision(10) << x 26 | #define goog(tno) cout << "Case #" << tno <<": " 27 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 28 | 29 | struct helper { 30 | ll t, z, y; 31 | }; 32 | 33 | ll blown(helper x, int time) { 34 | ll result = 0; 35 | 36 | result += x.z * (time / (x.t * x.z + x.y)); 37 | ll rem = time % (x.t * x.z + x.y); 38 | if (rem >= (x.t * x.z)) result += x.z; 39 | else result += rem / x.t; 40 | 41 | return result; 42 | } 43 | 44 | bool good(int m, vector& h, int time) { 45 | ll result = 0; 46 | 47 | for (const auto& x : h) { 48 | result += blown(x, time); 49 | } 50 | 51 | return result >= m; 52 | } 53 | 54 | int main(void) { 55 | ll m, n; 56 | cin >> m >> n; 57 | 58 | vector h(n); 59 | for (auto& x : h) { 60 | cin >> x.t >> x.z >> x.y; 61 | } 62 | 63 | ll l = -1; 64 | ll r = 2e9+1; 65 | 66 | while (r > l + 1) { 67 | ll mid = (l + r) / 2; 68 | if (good(m, h, mid)) { 69 | r = mid; 70 | } else { 71 | l = mid; 72 | } 73 | } 74 | 75 | cout << r << endl; 76 | for (int i = 0; i < n; i++) { 77 | if (i > 0) cout << " "; 78 | 79 | ll x = blown(h[i], r); 80 | cout << min(m, x); 81 | m -= min(m, x); 82 | } 83 | cout << endl; 84 | 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /binary-search/step2/E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | #define ll long long 20 | #define pb push_back 21 | #define loop(a) for(int i = 0; i < a; i++) 22 | #define loopv(i,a) for (int i = 0; i < a; i++) 23 | #define rep(i,a,b) for (int i = a; i < b; i++) 24 | #define all(x) (x).begin(), (x).end() 25 | #define prDouble(x) cout << fixed << setprecision(10) << x 26 | #define goog(tno) cout << "Case #" << tno <<": " 27 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 28 | 29 | int main(void) { 30 | double c; 31 | cin >> c; 32 | 33 | double l = 0; 34 | double r = 1e6; 35 | for (int i = 0; i < 100; i++) { 36 | double x = (r + l) / 2; 37 | double result = x * x + sqrt(x); 38 | if (result > c) { 39 | r = x; 40 | } else { 41 | l = x; 42 | } 43 | } 44 | 45 | cout << setprecision(10) << r << endl; 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /binary-search/step2/F.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | #define ll long long 20 | #define pb push_back 21 | #define loop(a) for(int i = 0; i < a; i++) 22 | #define loopv(i,a) for (int i = 0; i < a; i++) 23 | #define rep(i,a,b) for (int i = a; i < b; i++) 24 | #define all(x) (x).begin(), (x).end() 25 | #define prDouble(x) cout << fixed << setprecision(10) << x 26 | #define goog(tno) cout << "Case #" << tno <<": " 27 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 28 | 29 | bool good(string& a, string& b, vector& v, int m) { 30 | int idx = 0; 31 | 32 | for (int i = 0; i < a.size() && idx < b.size(); i++) { 33 | if (v[i] <= m) continue; 34 | if (a[i] == b[idx]) { 35 | idx++; 36 | } 37 | } 38 | 39 | return idx == b.size(); 40 | } 41 | 42 | int main(void) { 43 | string a, b; 44 | cin >> a >> b; 45 | 46 | int x; 47 | vector v(a.size()); 48 | for (int i = 1; i <= a.size(); i++) { 49 | cin >> x; 50 | v[x-1] = i; 51 | } 52 | 53 | int l = 0; 54 | int r = a.size(); 55 | while (r > l + 1) { 56 | int m = (l + r) / 2; 57 | if (good(a, b, v, m)) { 58 | l = m; 59 | } else { 60 | r = m; 61 | } 62 | } 63 | 64 | cout << l << endl; 65 | 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /binary-search/step2/G.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | #define ll long long 20 | #define pb push_back 21 | #define loop(a) for(int i = 0; i < a; i++) 22 | #define loopv(i,a) for (int i = 0; i < a; i++) 23 | #define rep(i,a,b) for (int i = a; i < b; i++) 24 | #define all(x) (x).begin(), (x).end() 25 | #define prDouble(x) cout << fixed << setprecision(10) << x 26 | #define goog(tno) cout << "Case #" << tno <<": " 27 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 28 | 29 | bool good(int k, int n, vector v, ll m) { 30 | ll sum = 0; 31 | 32 | for (auto x : v) { 33 | sum += min(m, x); 34 | } 35 | 36 | return sum >= m * k; 37 | } 38 | 39 | int main(void) { 40 | int k, n; 41 | cin >> k >> n; 42 | 43 | vector v(n); 44 | for (auto& x : v) { 45 | cin >> x; 46 | } 47 | 48 | ll l = 0; 49 | ll r = 1e17; 50 | while (r > l + 1) { 51 | ll m = (l + r) / 2; 52 | if (good(k, n, v, m)) { 53 | l = m; 54 | } else { 55 | r = m; 56 | } 57 | } 58 | 59 | cout << l << endl; 60 | 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /binary-search/step2/H.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | #define ll long long 20 | #define pb push_back 21 | #define loop(a) for(int i = 0; i < a; i++) 22 | #define loopv(i,a) for (int i = 0; i < a; i++) 23 | #define rep(i,a,b) for (int i = a; i < b; i++) 24 | #define all(x) (x).begin(), (x).end() 25 | #define prDouble(x) cout << fixed << setprecision(10) << x 26 | #define goog(tno) cout << "Case #" << tno <<": " 27 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 28 | 29 | bool good(ll rb, ll rs, ll rc, ll nb, ll ns, ll nc, ll pb, ll ps, ll pc, ll sum, ll M) { 30 | ll mb = M * rb; 31 | ll ms = M * rs; 32 | ll mc = M * rc; 33 | 34 | ll x = 0; 35 | x += max(mb - nb, 0LL) * pb; 36 | x += max(ms - ns, 0LL) * ps; 37 | x += max(mc - nc, 0LL) * pc; 38 | 39 | return x <= sum; 40 | } 41 | 42 | int main(void) { 43 | string r; 44 | ll nb, ns, nc; 45 | ll pb, ps, pc; 46 | ll sum; 47 | 48 | cin >> r; 49 | cin >> nb >> ns >> nc; 50 | cin >> pb >> ps >> pc; 51 | cin >> sum; 52 | 53 | ll rb = 0, rs = 0, rc = 0; 54 | for (int i = 0; i < r.size(); i++) { 55 | if (r[i] == 'B') { 56 | rb++; 57 | } else if (r[i] == 'S') { 58 | rs++; 59 | } else { 60 | rc++; 61 | } 62 | } 63 | 64 | ll L = 0; 65 | ll R = 1e15; 66 | 67 | while (R > L + 1) { 68 | ll M = (L + R) / 2; 69 | if (good(rb, rs, rc, nb, ns, nc, pb, ps, pc, sum, M)) { 70 | L = M; 71 | } else { 72 | R = M; 73 | } 74 | } 75 | 76 | cout << L << endl; 77 | 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /binary-search/step3/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | #define ll long long 20 | #define pb push_back 21 | #define loop(a) for(int i = 0; i < a; i++) 22 | #define loopv(i,a) for (int i = 0; i < a; i++) 23 | #define rep(i,a,b) for (int i = a; i < b; i++) 24 | #define all(x) (x).begin(), (x).end() 25 | #define prDouble(x) cout << fixed << setprecision(10) << x 26 | #define goog(tno) cout << "Case #" << tno <<": " 27 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 28 | 29 | bool good(int n, vector& x, vector& v, double M) { 30 | double L = -1e10; 31 | double R = 1e10; 32 | for (int i = 0; i < n; i++) { 33 | double xl = x[i] - M*v[i]; 34 | double xr = x[i] + M*v[i]; 35 | 36 | L = max(L, xl); 37 | R = min(R, xr); 38 | 39 | if (L > R) { 40 | return false; 41 | } 42 | } 43 | 44 | return true; 45 | } 46 | 47 | int main(void) { 48 | int n; 49 | cin >> n; 50 | vector x(n), v(n); 51 | for (int i = 0; i < n; i++) { 52 | cin >> x[i] >> v[i]; 53 | } 54 | 55 | double L = 0; 56 | double R = 1e18; 57 | 58 | for (int i = 0; i < 100; i++) { 59 | double M = (L + R) / 2; 60 | 61 | if (good(n, x, v, M)) { 62 | R = M; 63 | } else { 64 | L = M; 65 | } 66 | } 67 | 68 | cout << setprecision(10) << R << endl; 69 | 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /binary-search/step3/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | #define ll long long 20 | #define pb push_back 21 | #define loop(a) for(int i = 0; i < a; i++) 22 | #define loopv(i,a) for (int i = 0; i < a; i++) 23 | #define rep(i,a,b) for (int i = a; i < b; i++) 24 | #define all(x) (x).begin(), (x).end() 25 | #define prDouble(x) cout << fixed << setprecision(10) << x 26 | #define goog(tno) cout << "Case #" << tno <<": " 27 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 28 | 29 | bool good(int n, int k, vector& v, ll M) { 30 | int c = 1; 31 | 32 | ll s = 0; 33 | for (int i = 0; i < n; i++) { 34 | if (v[i] > M) return false; 35 | 36 | if (s + v[i] > M) { 37 | s = v[i]; 38 | c++; 39 | } else { 40 | s += v[i]; 41 | } 42 | } 43 | 44 | return c <= k; 45 | } 46 | 47 | int main(void) { 48 | int n, k; 49 | cin >> n >> k; 50 | 51 | vector v(n); 52 | for (int i = 0; i < n; i++) { 53 | cin >> v[i]; 54 | } 55 | 56 | ll L = 0; 57 | ll R = 1e16; 58 | while (R > L + 1) { 59 | ll M = (L + R) / 2; 60 | if (good(n, k, v, M)) { 61 | R = M; 62 | } else { 63 | L = M; 64 | } 65 | } 66 | 67 | cout << R << endl; 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /binary-search/step3/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | #define ll long long 20 | #define pb push_back 21 | #define loop(a) for(int i = 0; i < a; i++) 22 | #define loopv(i,a) for (int i = 0; i < a; i++) 23 | #define rep(i,a,b) for (int i = a; i < b; i++) 24 | #define all(x) (x).begin(), (x).end() 25 | #define prDouble(x) cout << fixed << setprecision(10) << x 26 | #define goog(tno) cout << "Case #" << tno <<": " 27 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 28 | 29 | bool good(int n, int k, vector& v, int M) { 30 | int c = 1; 31 | int p = 0; 32 | for (int i = 1; i < n; i++) { 33 | if (v[i] - v[p] >= M) { 34 | c++; 35 | p = i; 36 | } 37 | } 38 | 39 | return c >= k; 40 | } 41 | 42 | int main(void) { 43 | int n, k; 44 | cin >> n >> k; 45 | 46 | vector v(n); 47 | 48 | for (int i = 0; i < n; i++) { 49 | cin >> v[i]; 50 | } 51 | 52 | int L = 0; 53 | int R = 1e9+5; 54 | 55 | while (R > L + 1) { 56 | int M = (L + R) / 2; 57 | if (good(n, k, v, M)) { 58 | L = M; 59 | } else { 60 | R = M; 61 | } 62 | } 63 | 64 | cout << L << endl; 65 | 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /binary-search/step3/D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | using namespace std; 19 | 20 | #define ll long long 21 | #define pb push_back 22 | #define loop(a) for(int i = 0; i < a; i++) 23 | #define loopv(i,a) for (int i = 0; i < a; i++) 24 | #define rep(i,a,b) for (int i = a; i < b; i++) 25 | #define all(x) (x).begin(), (x).end() 26 | #define prDouble(x) cout << fixed << setprecision(10) << x 27 | #define goog(tno) cout << "Case #" << tno <<": " 28 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 29 | 30 | const int maxN = 1e6; 31 | int n, m, d; 32 | map> edges; 33 | map visited; 34 | int parent[maxN]; 35 | 36 | bool good(int limit) { 37 | queue> q; 38 | q.push({1, 0}); 39 | visited[1] = true; 40 | while (!q.empty()) { 41 | auto [current, taken] = q.front(); 42 | q.pop(); 43 | 44 | if (current == n) { 45 | return true; 46 | } 47 | 48 | if (taken == d) continue; 49 | 50 | for (auto [k, w] : edges[current]) { 51 | if (w > limit || visited[k]) continue; 52 | visited[k] = true; 53 | parent[k] = current; 54 | q.push({k, taken+1}); 55 | } 56 | } 57 | 58 | return false; 59 | } 60 | 61 | int main(void) { 62 | cin >> n >> m >> d; 63 | 64 | int a, b, c; 65 | int L = INT_MAX; 66 | int R = INT_MIN; 67 | 68 | while (m--) { 69 | cin >> a >> b >> c; 70 | edges[a][b] = c; 71 | L = min(L, c); 72 | R = max(R, c); 73 | } 74 | 75 | L--; 76 | R++; 77 | bool found = false; 78 | while (R > L + 1) { 79 | int M = (L + R) / 2; 80 | visited.clear(); 81 | if (good(M)) { 82 | found = true; 83 | R = M; 84 | } else { 85 | L = M; 86 | } 87 | } 88 | 89 | if (!found) { 90 | cout << -1 << endl; 91 | } else { 92 | visited.clear(); 93 | assert(good(R)); 94 | vector result; 95 | int x = n; 96 | while (x != 1) { 97 | result.push_back(x); 98 | x = parent[x]; 99 | } 100 | result.push_back(1); 101 | cout << result.size() - 1 << endl; 102 | for (auto it = result.rbegin(); it != result.rend(); it++) { 103 | cout << *it << " "; 104 | } 105 | cout << endl; 106 | } 107 | 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /binary-search/step4/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | using namespace std; 19 | 20 | #define ll long long 21 | #define pb push_back 22 | #define loop(a) for(int i = 0; i < a; i++) 23 | #define loopv(i,a) for (int i = 0; i < a; i++) 24 | #define rep(i,a,b) for (int i = a; i < b; i++) 25 | #define all(x) (x).begin(), (x).end() 26 | #define prDouble(x) cout << fixed << setprecision(10) << x 27 | #define goog(tno) cout << "Case #" << tno <<": " 28 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 29 | 30 | pair good(int n, int d, vector& a, double M) { 31 | vector pre(n+1), pmin(n+1); 32 | vector pminidx(n+1); 33 | 34 | pre[0] = a[0] - M; 35 | pmin[0] = pre[0]; 36 | pminidx[0] = 0; 37 | for (int i = 1; i <= n; i++) { 38 | pre[i] = pre[i-1] + a[i] - M; 39 | 40 | if (pre[i] < pmin[i-1]) { 41 | pmin[i] = pre[i]; 42 | pminidx[i] = i; 43 | } else { 44 | pmin[i] = pmin[i-1]; 45 | pminidx[i] = pminidx[i-1]; 46 | } 47 | } 48 | 49 | for (int R = d; R <= n; R++) { 50 | if (pre[R] >= pmin[R-d]) { 51 | int L = pminidx[R-d] + 1; 52 | return {L, R}; 53 | } 54 | } 55 | 56 | return {-1, -1}; 57 | } 58 | 59 | int main(void) { 60 | int n, d; 61 | cin >> n >> d; 62 | 63 | vector a(n+1); 64 | for (int i = 1; i <= n; i++) { 65 | cin >> a[i]; 66 | } 67 | 68 | double L = -1; 69 | double R = 101; 70 | 71 | pair current, result; 72 | for (int i = 0; i < 100; i++) { 73 | double M = (L + R) / 2; 74 | current = good(n, d, a, M); 75 | if (current.first == -1) { 76 | R = M; 77 | } else { 78 | result = current; 79 | L = M; 80 | } 81 | } 82 | 83 | cout << result.first << " " << result.second << endl; 84 | 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /binary-search/step4/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | using namespace std; 19 | 20 | #define ll long long 21 | #define pb push_back 22 | #define loop(a) for(int i = 0; i < a; i++) 23 | #define loopv(i,a) for (int i = 0; i < a; i++) 24 | #define rep(i,a,b) for (int i = a; i < b; i++) 25 | #define all(x) (x).begin(), (x).end() 26 | #define prDouble(x) cout << fixed << setprecision(10) << x 27 | #define goog(tno) cout << "Case #" << tno <<": " 28 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 29 | 30 | const int maxN = 1e5+1; 31 | int n, m; 32 | vector> adj[maxN]; 33 | 34 | bool good(double M) { 35 | vector dp(n+1, 1e18); 36 | dp[1] = 0; 37 | for (int i = 1; i <= n; i++) { 38 | for (auto [k, w] : adj[i]) { 39 | dp[k] = min(dp[k], dp[i] + w - M); 40 | } 41 | } 42 | 43 | return dp[n] <= 0; 44 | } 45 | 46 | int main(void) { 47 | cin >> n >> m; 48 | 49 | int a, b, c; 50 | while (m--) { 51 | cin >> a >> b >> c; 52 | adj[a].push_back({b, c}); 53 | } 54 | 55 | double L = -1; 56 | double R = 101; 57 | for (int i = 0; i < 80; i++) { 58 | double M = (L + R) / 2; 59 | if (good(M)) { 60 | R = M; 61 | } else { 62 | L = M; 63 | } 64 | } 65 | 66 | vector dp(n+1, 1e18); 67 | vector parent(n+1); 68 | dp[1] = 0; 69 | for (int i = 1; i <= n; i++) { 70 | for (auto [k, w] : adj[i]) { 71 | if (dp[k] > dp[i] + w - R) { 72 | parent[k] = i; 73 | dp[k] = dp[i] + w - R; 74 | } 75 | } 76 | } 77 | 78 | vector result; 79 | int x = n; 80 | while (x != 1) { 81 | result.push_back(x); 82 | x = parent[x]; 83 | } 84 | result.push_back(1); 85 | reverse(result.begin(), result.end()); 86 | 87 | cout << result.size() - 1 << endl; 88 | for (auto x : result) { 89 | cout << x << " "; 90 | } 91 | cout << endl; 92 | 93 | return 0; 94 | } 95 | -------------------------------------------------------------------------------- /binary-search/step4/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | using namespace std; 19 | 20 | #define ll long long 21 | #define pb push_back 22 | #define loop(a) for(int i = 0; i < a; i++) 23 | #define loopv(i,a) for (int i = 0; i < a; i++) 24 | #define rep(i,a,b) for (int i = a; i < b; i++) 25 | #define all(x) (x).begin(), (x).end() 26 | #define prDouble(x) cout << fixed << setprecision(10) << x 27 | #define goog(tno) cout << "Case #" << tno <<": " 28 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 29 | 30 | bool good(int n, int k, vector>& v, double M) { 31 | vector x(n); 32 | for (int i = 0; i < n; i++) { 33 | x[i] = v[i].first - v[i].second * M; 34 | } 35 | sort(x.begin(), x.end()); 36 | double s = 0; 37 | for (int i = 1; i <= k; i++) { 38 | s += x[n - i]; 39 | } 40 | return s <= 0; 41 | } 42 | 43 | int main(void) { 44 | int n, k; 45 | cin >> n >> k; 46 | 47 | vector> v(n); 48 | for (auto& x : v) { 49 | cin >> x.first >> x.second; 50 | } 51 | 52 | double L = -1; 53 | double R = 1e18; 54 | for (int i = 0; i < 100; i++) { 55 | double M = (L + R) / 2; 56 | if (good(n, k, v, M)) { 57 | R = M; 58 | } else { 59 | L = M; 60 | } 61 | } 62 | 63 | cout << setprecision(10) << R << endl; 64 | 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /binary-search/step5/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | using namespace std; 19 | 20 | #define ll long long 21 | #define pb push_back 22 | #define loop(a) for(int i = 0; i < a; i++) 23 | #define loopv(i,a) for (int i = 0; i < a; i++) 24 | #define rep(i,a,b) for (int i = a; i < b; i++) 25 | #define all(x) (x).begin(), (x).end() 26 | #define prDouble(x) cout << fixed << setprecision(10) << x 27 | #define goog(tno) cout << "Case #" << tno <<": " 28 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 29 | 30 | bool good(int n, int k, vector>& v, ll M) { 31 | ll count = 0; 32 | for (int i = 0; i < n; i++) { 33 | if (M > v[i].second) { 34 | count += min(v[i].second, M) - v[i].first + 1; 35 | } else if (M > v[i].first) { 36 | count += M - v[i].first; 37 | } 38 | } 39 | 40 | return count <= k; 41 | } 42 | 43 | int main(void) { 44 | int n, k; 45 | cin >> n >> k; 46 | 47 | vector> v(n); 48 | for (int i = 0; i < n; i++) { 49 | cin >> v[i].first >> v[i].second; 50 | } 51 | 52 | ll L = -1e10; 53 | ll R = 1e10; 54 | while (R > L + 1) { 55 | ll M = (L + R) / 2; 56 | if (good(n, k, v, M)) { 57 | L = M; 58 | } else { 59 | R = M; 60 | } 61 | } 62 | 63 | cout << L << endl; 64 | 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /binary-search/step5/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | using namespace std; 19 | 20 | #define ll long long 21 | #define pb push_back 22 | #define loop(a) for(int i = 0; i < a; i++) 23 | #define loopv(i,a) for (int i = 0; i < a; i++) 24 | #define rep(i,a,b) for (int i = a; i < b; i++) 25 | #define all(x) (x).begin(), (x).end() 26 | #define prDouble(x) cout << fixed << setprecision(10) << x 27 | #define goog(tno) cout << "Case #" << tno <<": " 28 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 29 | 30 | bool good(ll n, ll k, ll M) { 31 | ll count = 0; 32 | 33 | for (ll i = 1; i <= n; i++) { 34 | if (M % i == 0) { 35 | count += min(n, M / i - 1); 36 | } else { 37 | count += min(n, M / i); 38 | } 39 | } 40 | 41 | return count < k; 42 | } 43 | 44 | int main(void) { 45 | ll n, k; 46 | cin >> n >> k; 47 | 48 | ll L = 0; 49 | ll R = 1e18; 50 | while (R > L + 1) { 51 | ll M = (L + R) / 2; 52 | if (good(n, k, M)) { 53 | L = M; 54 | } else { 55 | R = M; 56 | } 57 | } 58 | 59 | cout << L << endl; 60 | 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /binary-search/step5/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | using namespace std; 19 | 20 | #define ll long long 21 | #define pb push_back 22 | #define loop(a) for(int i = 0; i < a; i++) 23 | #define loopv(i,a) for (int i = 0; i < a; i++) 24 | #define rep(i,a,b) for (int i = a; i < b; i++) 25 | #define all(x) (x).begin(), (x).end() 26 | #define prDouble(x) cout << fixed << setprecision(10) << x 27 | #define goog(tno) cout << "Case #" << tno <<": " 28 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 29 | 30 | int ai = 0, bi = 0; 31 | 32 | bool good(ll n, ll k, vector& a, vector& b, ll M) { 33 | ll count = 0; 34 | 35 | for (int i = 0; i < n; i++) { 36 | if (a[i] >= M) continue; 37 | count += lower_bound(b.begin(), b.end(), M - a[i]) - b.begin(); 38 | } 39 | 40 | return count < k; 41 | } 42 | 43 | /* 44 | ll find_sum(ll n, vector& a, vector& b, ll M) { 45 | int idx = 46 | } 47 | */ 48 | 49 | int main(void) { 50 | ll n, k; 51 | cin >> n >> k; 52 | 53 | vector a(n), b(n); 54 | for (int i = 0; i < n; i++) { 55 | cin >> a[i]; 56 | } 57 | for (int i = 0; i < n; i++) { 58 | cin >> b[i]; 59 | } 60 | 61 | sort(a.begin(), a.end()); 62 | sort(b.begin(), b.end()); 63 | 64 | ll L = 0; 65 | ll R = 1e18; 66 | while (R > L + 1) { 67 | ll M = (L + R) / 2; 68 | if (good(n, k, a, b, M)) { 69 | L = M; 70 | } else { 71 | R = M; 72 | } 73 | } 74 | 75 | cout << L << endl; 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /disjoint-set-union/step1/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | int main(void) { 8 | int n, m; 9 | cin >> n >> m; 10 | 11 | n++; 12 | vector p(n), r(n); 13 | 14 | for (int i = 0; i < n; i++) { 15 | p[i] = i; 16 | r[i] = 1; 17 | } 18 | 19 | string cmd; 20 | int a, b; 21 | 22 | function get = [&](int x) { 23 | if (x != p[x]) { 24 | p[x] = get(p[x]); 25 | } 26 | return p[x]; 27 | }; 28 | 29 | while (m--) { 30 | cin >> cmd >> a >> b; 31 | if (cmd == "union") { 32 | int pa = get(a); 33 | int pb = get(b); 34 | if (r[pa] == r[pb]) { 35 | r[pa]++; 36 | p[pb] = pa; 37 | } else if (r[pa] > r[pb]) { 38 | p[pb] = pa; 39 | } else { 40 | p[pa] = pb; 41 | } 42 | } else { // get 43 | int pa = get(a); 44 | int pb = get(b); 45 | if (pa == pb) cout << "YES" << endl; 46 | else cout << "NO" << endl; 47 | } 48 | } 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /disjoint-set-union/step1/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | int main(void) { 7 | int n, m; 8 | cin >> n >> m; 9 | 10 | n++; 11 | vector p(n), r(n), sz(n), _min(n), _max(n); 12 | 13 | for (int i = 0; i < n; i++) { 14 | p[i] = i; 15 | r[i] = 1; 16 | sz[i] = 1; 17 | _min[i] = i; 18 | _max[i] = i; 19 | } 20 | 21 | function get = [&](int x) { 22 | if (p[x] != x) { 23 | p[x] = get(p[x]); 24 | } 25 | return p[x]; 26 | }; 27 | 28 | string cmd; 29 | int u, v; 30 | 31 | while (m--) { 32 | cin >> cmd; 33 | if (cmd == "union") { 34 | cin >> u >> v; 35 | int pa = get(u); 36 | int pb = get(v); 37 | if (pa == pb) { 38 | continue; 39 | } 40 | if (r[pa] == r[pb]) { 41 | r[pa]++; 42 | p[pb] = pa; 43 | sz[pa] += sz[pb]; 44 | _min[pa] = min(_min[pa], _min[pb]); 45 | _max[pa] = max(_max[pa], _max[pb]); 46 | } else if (r[pa] > r[pb]) { 47 | p[pb] = pa; 48 | sz[pa] += sz[pb]; 49 | _min[pa] = min(_min[pa], _min[pb]); 50 | _max[pa] = max(_max[pa], _max[pb]); 51 | } else { 52 | p[pa] = pb; 53 | sz[pb] += sz[pa]; 54 | _min[pb] = min(_min[pa], _min[pb]); 55 | _max[pb] = max(_max[pa], _max[pb]); 56 | } 57 | } else { 58 | cin >> v; 59 | int pa = get(v); 60 | cout << _min[pa] << " " << _max[pa] << " " << sz[pa] << endl; 61 | } 62 | } 63 | 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /disjoint-set-union/step1/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | int main(void) { 8 | int n, m; 9 | cin >> n >> m; 10 | n++; 11 | 12 | vector p(n), r(n), score(n); 13 | 14 | for (int i = 0; i < n; i++) { 15 | p[i] = i; 16 | r[i] = 1; 17 | score[i] = 0; 18 | } 19 | 20 | string cmd; 21 | int x, y, v; 22 | 23 | function get = [&](int x) { 24 | if (p[x] != x) { 25 | return get(p[x]); 26 | } 27 | return p[x]; 28 | }; 29 | 30 | function getScore = [&](int x) { 31 | int result = score[x]; 32 | while (x != p[x]) { 33 | x = p[x]; 34 | result += score[x]; 35 | } 36 | return result; 37 | }; 38 | 39 | while (m--) { 40 | cin >> cmd; 41 | if (cmd == "add") { 42 | cin >> x >> v; 43 | int px = get(x); 44 | score[px] += v; 45 | } else if (cmd == "join") { 46 | cin >> x >> y; 47 | int px = get(x); 48 | int py = get(y); 49 | if (px == py) continue; 50 | if (r[px] == r[py]) { 51 | r[px]++; 52 | } 53 | 54 | if (r[px] > r[py]) { 55 | p[py] = px; 56 | score[py] -= score[px]; 57 | } else { 58 | p[px] = py; 59 | score[px] -= score[py]; 60 | } 61 | } else { // get 62 | cin >> x; 63 | cout << getScore(x) << endl; 64 | } 65 | } 66 | 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /disjoint-set-union/step1/D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | const int ASK = 0; 8 | const int CUT = 1; 9 | 10 | struct cmd { 11 | int t, u, v; 12 | }; 13 | 14 | int main(void) { 15 | int n, m, k; 16 | cin >> n >> m >> k; 17 | 18 | n++; 19 | 20 | vector p(n), r(n); 21 | vector cmds(k); 22 | 23 | for (int i = 0; i < n; i++) { 24 | p[i] = i; 25 | r[i] = 1; 26 | } 27 | 28 | function get = [&](int x) { 29 | if (x != p[x]) { 30 | p[x] = get(p[x]); 31 | } 32 | return p[x]; 33 | }; 34 | 35 | function join = [&](int a, int b) { 36 | int pa = get(a); 37 | int pb = get(b); 38 | if (pa == pb) return; 39 | if (r[pa] == r[pb]) r[pa]++; 40 | 41 | if (r[pa] > r[pb]) { 42 | p[pb] = pa; 43 | } else { 44 | p[pa] = pb; 45 | } 46 | }; 47 | 48 | string s; 49 | int u, v; 50 | 51 | while (m--) { 52 | cin >> u >> v; 53 | } 54 | 55 | int cnt = 0; 56 | for (int i = 0; i < k; i++) { 57 | cin >> s >> u >> v; 58 | if (s == "ask") { 59 | cmds[i] = {ASK, u, v}; 60 | cnt++; 61 | } else { 62 | cmds[i] = {CUT, u, v}; 63 | } 64 | } 65 | 66 | vector result(cnt); 67 | for (int i = k - 1; i >= 0; i--) { 68 | if (cmds[i].t == ASK) { 69 | int pa = get(cmds[i].u); 70 | int pb = get(cmds[i].v); 71 | result[--cnt] = pa == pb; 72 | } else { 73 | join(cmds[i].u, cmds[i].v); 74 | } 75 | } 76 | 77 | for (int i = 0; i < result.size(); i++) { 78 | if (result[i]) cout << "YES" << endl; 79 | else cout << "NO" << endl; 80 | } 81 | 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /disjoint-set-union/step1/E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | int main(void) { 7 | int n, m; 8 | cin >> n >> m; 9 | 10 | n++; 11 | vector> monkies(n); 12 | vector parent(n), rank(n), result(n, -1); 13 | vector> group(n); 14 | for (int i = 1; i < n; i++) { 15 | parent[i] = i; 16 | rank[i] = 1; 17 | group[i].push_back(i); 18 | cin >> monkies[i].first >> monkies[i].second; 19 | } 20 | 21 | vector p(m), h(m); 22 | for (int i = 0; i < m; i++) { 23 | cin >> p[i] >> h[i]; 24 | if (h[i] == 1) { 25 | h[i] = monkies[p[i]].first; 26 | monkies[p[i]].first = -1; 27 | } else { 28 | h[i] = monkies[p[i]].second; 29 | monkies[p[i]].second = -1; 30 | } 31 | } 32 | 33 | function get = [&](int x) { 34 | if (x != parent[x]) parent[x] = get(parent[x]); 35 | return parent[x]; 36 | }; 37 | 38 | function join = [&](int a, int b, int t) { 39 | int top = get(1); 40 | int pa = get(a); 41 | int pb = get(b); 42 | 43 | if (pa == pb) { 44 | return; 45 | } 46 | 47 | if (rank[pa] == rank[pb]) { 48 | rank[pa]++; 49 | } 50 | 51 | if (pa == top) { 52 | for (int i : group[pb]) { 53 | result[i] = t; 54 | } 55 | } else if (pb == top) { 56 | for (int i : group[pa]) { 57 | result[i] = t; 58 | } 59 | } 60 | 61 | if (rank[pa] > rank[pb]) { 62 | parent[pb] = pa; 63 | for (int i : group[pb]) { 64 | group[pa].push_back(i); 65 | } 66 | group[pb].clear(); 67 | } else { 68 | parent[pa] = pb; 69 | for (int i : group[pa]) { 70 | group[pb].push_back(i); 71 | } 72 | group[pa].clear(); 73 | } 74 | }; 75 | 76 | for (int i = 1; i < n; i++) { 77 | if (monkies[i].first != -1) { 78 | join(i, monkies[i].first, -1); 79 | } 80 | if (monkies[i].second != -1) { 81 | join(i, monkies[i].second, -1); 82 | } 83 | } 84 | 85 | for (int i = m - 1; i >= 0; i--) { 86 | join(p[i], h[i], i); 87 | } 88 | 89 | for (int i = 1; i < n; i++) { 90 | cout << result[i] << endl; 91 | } 92 | 93 | return 0; 94 | } 95 | -------------------------------------------------------------------------------- /disjoint-set-union/step2/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | int main(void) { 7 | ios_base::sync_with_stdio(false); 8 | cin.tie(NULL); 9 | cout.tie(NULL); 10 | 11 | int n, m; 12 | cin >> n >> m; 13 | 14 | n += 2; 15 | vector p(n); 16 | for (int i = 0; i < n; i++) { 17 | p[i] = i; 18 | } 19 | 20 | function get = [&](int x) { 21 | if (x != p[x]) p[x] = get(p[x]); 22 | return p[x]; 23 | }; 24 | 25 | // make b parent of a 26 | function join = [&](int a, int b) { 27 | int pa = get(a); 28 | int pb = get(b); 29 | if (pa == pb) return; 30 | p[pa] = pb; 31 | }; 32 | 33 | char cmd; 34 | int v; 35 | 36 | while (m--) { 37 | cin >> cmd >> v; 38 | if (cmd == '?') { 39 | int pv = get(v); 40 | if (pv == n - 1) { 41 | cout << -1 << endl; 42 | } else { 43 | cout << pv << endl; 44 | } 45 | } else { 46 | join(v, v + 1); 47 | } 48 | } 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /disjoint-set-union/step2/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | int main(void) { 7 | int n; 8 | cin >> n; 9 | 10 | vector p(n + 1); 11 | for (int i = 0; i <= n; i++) { 12 | p[i] = i; 13 | } 14 | 15 | function get = [&](int x) { 16 | if (x != p[x]) p[x] = get(p[x]); 17 | return p[x]; 18 | }; 19 | 20 | int x; 21 | for (int i = 0; i < n; i++) { 22 | cin >> x; 23 | int px = get(x); 24 | if (px == n) { 25 | p[px] = 1; 26 | } else { 27 | p[px] = px + 1; 28 | } 29 | 30 | cout << px << endl; 31 | } 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /disjoint-set-union/step2/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | struct DSU { 6 | vector n, p, r, mx; 7 | DSU(int n) { 8 | p.resize(n + 1); 9 | r.resize(n + 1); 10 | mx.resize(n + 1); 11 | 12 | for (int i = 0; i <= n; i++) { 13 | p[i] = i; 14 | r[i] = 1; 15 | mx[i] = i; 16 | } 17 | } 18 | 19 | int get(int x) { 20 | if (x != p[x]) p[x] = get(p[x]); 21 | return p[x]; 22 | } 23 | 24 | void join(int a, int b) { 25 | int pa = get(a); 26 | int pb = get(b); 27 | if (pa == pb) return; 28 | 29 | if (r[pa] == r[pb]) r[pa]++; 30 | 31 | if (r[pa] > r[pb]) { 32 | p[pb] = pa; 33 | mx[pa] = max(mx[pa], mx[pb]); 34 | } else { 35 | p[pa] = pb; 36 | mx[pb] = max(mx[pa], mx[pb]); 37 | } 38 | } 39 | 40 | int getMax(int x) { 41 | return mx[x]; 42 | } 43 | }; 44 | 45 | int main(void) { 46 | ios_base::sync_with_stdio(false); 47 | cin.tie(nullptr); 48 | cout.tie(nullptr); 49 | 50 | int n, q; 51 | cin >> n >> q; 52 | 53 | DSU dsu(n); 54 | DSU dsuSeg(n); 55 | 56 | int t, x, y; 57 | while (q--) { 58 | cin >> t >> x >> y; 59 | 60 | if (t == 1) { 61 | dsu.join(x, y); 62 | } else if (t == 2) { 63 | int c = dsuSeg.getMax(dsuSeg.get(x)); 64 | while (c < y) { 65 | dsu.join(c, y); 66 | dsuSeg.join(c, c + 1); 67 | c = dsuSeg.getMax(dsuSeg.get(c)); 68 | } 69 | dsu.join(c, y); 70 | } else { 71 | cout << (dsu.get(x) == dsu.get(y) ? "YES" : "NO") << '\n'; 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /disjoint-set-union/step2/D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | struct DSU { 6 | vector p, steps; 7 | 8 | DSU(int n) { 9 | p.resize(n+1); 10 | steps.resize(n+1); 11 | for (int i = 0; i <= n; i++) { 12 | p[i] = i; 13 | steps[i] = 0; 14 | } 15 | } 16 | 17 | int get(int x) { 18 | if (p[x] == x) return x; 19 | 20 | int px = get(p[x]); 21 | if (p[x] != px) { 22 | steps[x] += steps[p[x]]; 23 | p[x] = px; 24 | } 25 | return px; 26 | } 27 | 28 | void join(int child, int parent) { 29 | p[child] = parent; 30 | steps[child] += 1; 31 | } 32 | 33 | int count(int x) { 34 | int px = get(x); 35 | int result = steps[x]; 36 | 37 | if (px != p[x]) { 38 | result += count(p[x]); 39 | } 40 | 41 | return result; 42 | } 43 | }; 44 | 45 | int main(void) { 46 | int n, m; 47 | cin >> n >> m; 48 | 49 | DSU dsu(n); 50 | 51 | int t, a, b, c; 52 | while (m--) { 53 | cin >> t; 54 | if (t == 1) { 55 | cin >> a >> b; 56 | dsu.join(a, b); 57 | } else { 58 | cin >> c; 59 | cout << dsu.count(c) << '\n'; 60 | } 61 | } 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /disjoint-set-union/step2/E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | struct Edge { 7 | int b, e, w; 8 | }; 9 | 10 | int main(void) { 11 | int n, m; 12 | cin >> n >> m; 13 | 14 | vector p(n+1), r(n+1); 15 | for (int i = 0; i <= n; i++) { 16 | p[i] = i; 17 | r[i] = 1; 18 | } 19 | 20 | function get = [&](int x) { 21 | if (x != p[x]) p[x] = get(p[x]); 22 | return p[x]; 23 | }; 24 | 25 | function join = [&](int a, int b) { 26 | int pa = get(a); 27 | int pb = get(b); 28 | if (pa == pb) return; 29 | 30 | if (r[pa] == r[pb]) r[pa]++; 31 | 32 | if (r[pa] > r[pb]) { 33 | p[pb] = pa; 34 | } else { 35 | p[pa] = pb; 36 | } 37 | }; 38 | 39 | vector edges(m); 40 | for (int i = 0; i < m; i++) { 41 | cin >> edges[i].b >> edges[i].e >> edges[i].w; 42 | } 43 | 44 | sort(edges.begin(), edges.end(), [&](const Edge &a, const Edge &b) { 45 | return a.w < b.w; 46 | }); 47 | 48 | long long result = 0; 49 | 50 | for (auto edge : edges) { 51 | int pb = get(edge.b); 52 | int pe = get(edge.e); 53 | if (pb == pe) continue; 54 | result += edge.w; 55 | join(edge.b, edge.e); 56 | } 57 | 58 | cout << result << endl; 59 | 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /disjoint-set-union/step2/F.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | struct Edge { 8 | int b, e, w; 9 | }; 10 | 11 | struct DSU { 12 | vector p, sz; 13 | 14 | DSU(int n) { 15 | p.resize(n+1); 16 | sz.resize(n+1); 17 | for (int i = 0; i <= n; i++) { 18 | p[i] = i; 19 | sz[i] = 1; 20 | } 21 | } 22 | 23 | int get(int x) { 24 | if (x != p[x]) p[x] = get(p[x]); 25 | return p[x]; 26 | } 27 | 28 | void join(int a, int b) { 29 | int pa = get(a); 30 | int pb = get(b); 31 | if (pa == pb) return; 32 | 33 | if (sz[pa] > sz[pb]) { 34 | swap(pa, pb); 35 | } 36 | 37 | p[pa] = pb; 38 | sz[pb] += sz[pa]; 39 | } 40 | 41 | int getSize(int x) { 42 | int px = get(x); 43 | return sz[px]; 44 | } 45 | }; 46 | 47 | int main(void) { 48 | int n, m; 49 | cin >> n >> m; 50 | 51 | vector edges(m); 52 | for (int i = 0; i < m; i++) { 53 | cin >> edges[i].b >> edges[i].e >> edges[i].w; 54 | } 55 | 56 | sort(edges.begin(), edges.end(), [](const Edge &a, const Edge &b) { 57 | return a.w < b.w; 58 | }); 59 | 60 | int result = INT_MAX; 61 | 62 | for (int i = 0; i < m; i++) { 63 | DSU dsu(n); 64 | int j = i; 65 | while (j < m && dsu.getSize(1) < n) { 66 | dsu.join(edges[j].b, edges[j].e); 67 | j++; 68 | } 69 | if (dsu.getSize(1) == n) { 70 | result = min(result, edges[j-1].w - edges[i].w); 71 | } 72 | } 73 | 74 | if (result == INT_MAX) { 75 | cout << "NO\n"; 76 | } else { 77 | cout << "YES\n"; 78 | cout << result << "\n"; 79 | } 80 | 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /disjoint-set-union/step2/G.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | struct Edge { 7 | int b, e, w; 8 | }; 9 | 10 | struct DSU { 11 | vector p, sz; 12 | 13 | DSU(int n) { 14 | p.resize(n+1); 15 | sz.resize(n+1); 16 | for (int i = 0; i <= n; i++) { 17 | p[i] = i; 18 | sz[i] = 1; 19 | } 20 | } 21 | 22 | int get(int x) { 23 | if (x != p[x]) p[x] = get(p[x]); 24 | return p[x]; 25 | } 26 | 27 | void join(int a, int b) { 28 | int pa = get(a); 29 | int pb = get(b); 30 | if (pa == pb) return; 31 | 32 | if (sz[pa] > sz[pb]) swap(pa, pb); 33 | 34 | p[pa] = pb; 35 | sz[pb] += sz[pa]; 36 | } 37 | 38 | int size(int x) { 39 | return sz[get(x)]; 40 | } 41 | }; 42 | 43 | int main(void) { 44 | ios_base::sync_with_stdio(false); 45 | cin.tie(NULL); 46 | cout.tie(NULL); 47 | 48 | int n, k; 49 | cin >> n >> k; 50 | 51 | vector edges(k); 52 | for (int i = 0; i < k; i++) { 53 | cin >> edges[i].b >> edges[i].e >> edges[i].w; 54 | } 55 | 56 | sort(edges.begin(), edges.end(), [](Edge a, Edge b) { 57 | return a.w < b.w; 58 | }); 59 | 60 | DSU dsu(n); 61 | int result; 62 | for (Edge edge : edges) { 63 | dsu.join(edge.b, edge.e); 64 | if (dsu.size(1) == n) { 65 | result = edge.w; 66 | break; 67 | } 68 | } 69 | 70 | cout << result << '\n'; 71 | 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /disjoint-set-union/step2/H.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | using ll = long long; 7 | 8 | struct Edge { 9 | int b, e; 10 | ll w; 11 | int idx; 12 | }; 13 | 14 | struct DSU { 15 | vector p, sz; 16 | DSU(int n) { 17 | p.resize(n+1); 18 | sz.resize(n+1); 19 | for (int i = 0; i <= n; i++) { 20 | p[i] = i; 21 | sz[i] = 1; 22 | } 23 | } 24 | 25 | int get(int x) { 26 | if (x != p[x]) p[x] = get(p[x]); 27 | return p[x]; 28 | } 29 | 30 | void join(int a, int b) { 31 | int pa = get(a); 32 | int pb = get(b); 33 | if (pa == pb) return; 34 | 35 | if (sz[pa] > sz[pb]) swap(pa, pb); 36 | 37 | p[pa] = pb; 38 | sz[pb] += sz[pa]; 39 | } 40 | 41 | int size(int x) { 42 | return sz[get(x)]; 43 | } 44 | }; 45 | 46 | int main(void) { 47 | ios_base::sync_with_stdio(false); 48 | cin.tie(NULL); 49 | cout.tie(NULL); 50 | 51 | int n, m; 52 | ll s; 53 | 54 | cin >> n >> m >> s; 55 | 56 | vector edges(m); 57 | for (int i = 0; i < m; i++) { 58 | cin >> edges[i].b >> edges[i].e >> edges[i].w; 59 | edges[i].idx = i + 1; 60 | } 61 | 62 | sort(edges.begin(), edges.end(), [](const Edge &a, const Edge &b) { 63 | return a.w > b.w; 64 | }); 65 | 66 | DSU dsu(n); 67 | vector remaining; 68 | 69 | for (int i = 0; i < m; i++) { 70 | if (dsu.size(1) == n) { 71 | remaining.push_back(edges[i]); 72 | continue; 73 | } 74 | 75 | int pb = dsu.get(edges[i].b); 76 | int pe = dsu.get(edges[i].e); 77 | if (pb == pe) { 78 | remaining.push_back(edges[i]); 79 | } else { 80 | dsu.join(pb, pe); 81 | } 82 | } 83 | 84 | ll x = 0; 85 | vector result; 86 | for (int i = remaining.size() - 1; i >= 0; i--) { 87 | if (x + remaining[i].w <= s) { 88 | x += remaining[i].w; 89 | result.push_back(remaining[i].idx); 90 | } else { 91 | break; 92 | } 93 | } 94 | 95 | cout << result.size() << '\n'; 96 | for (int i = 0; i < result.size(); i++) { 97 | if (i) cout << " "; 98 | cout << result[i]; 99 | } 100 | cout << '\n'; 101 | 102 | return 0; 103 | } 104 | -------------------------------------------------------------------------------- /disjoint-set-union/step2/I.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | struct DSU { 6 | vector p, r; 7 | 8 | DSU(int n) { 9 | p.resize(n+1); 10 | r.resize(n+1); 11 | for (int i = 0; i <= n; i++) { 12 | p[i] = i; 13 | r[i] = 1; 14 | } 15 | } 16 | 17 | int get(int x) { 18 | if (x != p[x]) p[x] = get(p[x]); 19 | return p[x]; 20 | } 21 | 22 | void join(int a, int b) { 23 | int pa = get(a); 24 | int pb = get(b); 25 | if (pa == pb) return; 26 | 27 | if (r[pa] == r[pb]) r[pa]++; 28 | 29 | if (r[pa] > r[pb]) { 30 | p[pb] = pa; 31 | } else { 32 | p[pa] = pb; 33 | } 34 | } 35 | 36 | bool connected(int a, int b) { 37 | return get(a) == get(b); 38 | } 39 | }; 40 | 41 | int main(void) { 42 | ios_base::sync_with_stdio(false); 43 | cin.tie(NULL); 44 | cout.tie(NULL); 45 | 46 | int n, m; 47 | cin >> n >> m; 48 | 49 | DSU dsu(n << 1); 50 | int shift = 0; 51 | int t, a, b; 52 | 53 | while (m--) { 54 | cin >> t >> a >> b; 55 | int x = (a + shift) % n; 56 | int y = (b + shift) % n; 57 | 58 | if (t == 0) { 59 | dsu.join((x << 1) | 0, (y << 1) | 1); 60 | dsu.join((x << 1) | 1, (y << 1) | 0); 61 | } else { 62 | bool connected = dsu.connected((x << 1) | 0, (y << 1) | 0) || dsu.connected((x << 1) | 1, (y << 1) | 1); 63 | if (connected) { 64 | cout << "YES\n"; 65 | shift = (shift + 1) % n; 66 | } else { 67 | cout << "NO\n"; 68 | } 69 | } 70 | } 71 | 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /disjoint-set-union/step2/J.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | struct DSU { 6 | vector p, sz; 7 | DSU(int n) { 8 | p.resize(n); 9 | sz.resize(n); 10 | for (int i = 0; i < n; i++) { 11 | p[i] = i; 12 | sz[i] = 1; 13 | } 14 | } 15 | 16 | int get(int x) { 17 | if (x != p[x]) p[x] = get(p[x]); 18 | return p[x]; 19 | } 20 | 21 | void join(int a, int b) { 22 | int pa = get(a); 23 | int pb = get(b); 24 | if (pa == pb) return; 25 | 26 | if (sz[pa] > sz[pb]) swap(pa, pb); 27 | 28 | p[pa] = pb; 29 | sz[pb] += sz[pa]; 30 | } 31 | 32 | bool connected(int a, int b) { 33 | return get(a) == get(b); 34 | } 35 | }; 36 | 37 | int main(void) { 38 | ios_base::sync_with_stdio(false); 39 | cin.tie(NULL); 40 | cout.tie(NULL); 41 | 42 | int n, m; 43 | cin >> n >> m; 44 | 45 | DSU dsu(n<<1); 46 | int a, b; 47 | int result = -1; 48 | for (int i = 0; i < m; i++) { 49 | cin >> a >> b; 50 | a--, b--; 51 | 52 | dsu.join((a << 1) | 0, (b << 1) | 1); 53 | dsu.join((a << 1) | 1, (b << 1) | 0); 54 | 55 | if (dsu.connected((a << 1) | 0, (a << 1) | 1)) { 56 | result = i + 1; 57 | break; 58 | } 59 | } 60 | 61 | cout << result << '\n'; 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /disjoint-set-union/step3/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | struct Snapshot { 6 | int pa; 7 | int pb; 8 | int sz; 9 | int count; 10 | }; 11 | 12 | struct DSU { 13 | int count; 14 | vector parent, sz; 15 | vector snapshots; 16 | vector versions; 17 | 18 | DSU(int n) { 19 | count = n; 20 | parent.resize(n+1); 21 | sz.resize(n+1); 22 | for (int i = 0; i <= n; i++) { 23 | parent[i] = i; 24 | sz[i] = 1; 25 | } 26 | } 27 | 28 | int get(int x) { 29 | if (parent[x] == x) return x; 30 | return get(parent[x]); 31 | } 32 | 33 | void join(int a, int b) { 34 | int pa = get(a); 35 | int pb = get(b); 36 | if (pa == pb) return; 37 | 38 | if (sz[pa] > sz[pb]) swap(pa, pb); 39 | 40 | snapshots.push_back({ 41 | pa, pb, sz[pb], count 42 | }); 43 | 44 | parent[pa] = pb; 45 | sz[pb] += sz[pa]; 46 | count--; 47 | } 48 | 49 | void persist() { 50 | versions.push_back(snapshots.size()); 51 | } 52 | 53 | void rollback() { 54 | int version = versions.back(); 55 | versions.pop_back(); 56 | while (snapshots.size() > version) { 57 | auto [_pa, _pb, _sz, _count] = snapshots.back(); 58 | snapshots.pop_back(); 59 | count = _count; 60 | sz[_pb] = _sz; 61 | parent[_pa] = _pa; 62 | } 63 | } 64 | }; 65 | 66 | int main(void) { 67 | ios_base::sync_with_stdio(false); 68 | cin.tie(NULL); 69 | cout.tie(NULL); 70 | 71 | int n, m; 72 | cin >> n >> m; 73 | 74 | DSU dsu(n); 75 | 76 | string cmd; 77 | int a, b; 78 | 79 | while (m--) { 80 | cin >> cmd; 81 | if (cmd[0] == 'p') { 82 | dsu.persist(); 83 | } else if (cmd[0] == 'u') { 84 | cin >> a >> b; 85 | dsu.join(a, b); 86 | cout << dsu.count << '\n'; 87 | } else { // cmd[0] == 'r' 88 | dsu.rollback(); 89 | cout << dsu.count << '\n'; 90 | } 91 | } 92 | 93 | return 0; 94 | } 95 | -------------------------------------------------------------------------------- /graph-theory/step1/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | int main(void) { 6 | int t; 7 | cin >> t; 8 | 9 | int n, m; 10 | while (t--) { 11 | cin >> n >> m; 12 | 13 | int a, b; 14 | bool ok = true; 15 | set> s; 16 | for (int i = 0; i < m; i++) { 17 | cin >> a >> b; 18 | if (a > b) swap(a, b); 19 | if (a == b || s.contains({a,b})) { 20 | ok = false; 21 | } 22 | s.insert({a,b}); 23 | } 24 | 25 | if (ok) { 26 | cout << "YES\n"; 27 | } else { 28 | cout << "NO\n"; 29 | } 30 | } 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /graph-theory/step1/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | int main(void) { 6 | int t; 7 | cin >> t; 8 | 9 | vector count(100001, 0); 10 | 11 | int n, m; 12 | while (t--) { 13 | cin >> n >> m; 14 | 15 | count.assign(100001, 0); 16 | 17 | int a, b; 18 | for (int i = 0; i < m; i++) { 19 | cin >> a >> b; 20 | count[a]++; 21 | count[b]++; 22 | } 23 | 24 | for (int i = 1; i <= n; i++) { 25 | if (i > 1) cout << " "; 26 | cout << count[i]; 27 | } 28 | cout << '\n'; 29 | } 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /graph-theory/step1/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | int main(void) { 7 | ios_base::sync_with_stdio(false); 8 | cin.tie(NULL); 9 | cout.tie(NULL); 10 | 11 | int t; 12 | cin >> t; 13 | 14 | vector cnt(100001, 0); 15 | vector a(100001, 0); 16 | int n, m, k; 17 | while (t--) { 18 | cin >> n >> m >> k; 19 | 20 | cnt.assign(100001, 0); 21 | 22 | bool simple = true; 23 | 24 | for (int i = 0; i < k; i++) { 25 | cin >> a[i]; 26 | cnt[a[i]]++; 27 | if (cnt[a[i]] > 1) { 28 | if (!(i == k - 1 && a[0] == a[k-1])) { 29 | simple = false; 30 | } 31 | } 32 | } 33 | 34 | int u, v; 35 | set> edges; 36 | for (int i = 0; i < m; i++) { 37 | cin >> u >> v; 38 | if (u > v) swap(u, v); 39 | edges.insert({u, v}); 40 | } 41 | 42 | bool connected = true; 43 | for (int i = 1; i < k; i++) { 44 | u = a[i-1]; 45 | v = a[i]; 46 | if (u > v) swap(u, v); 47 | if (!edges.contains({u,v})) { 48 | connected = false; 49 | break; 50 | } 51 | } 52 | 53 | if (!connected) { 54 | cout << "none\n"; 55 | } else if (a[0] == a[k-1] && simple) { 56 | cout << "simple cycle\n"; 57 | } else if (a[0] == a[k-1]) { 58 | cout << "cycle\n"; 59 | } else if (simple) { 60 | cout << "simple path\n"; 61 | } else { 62 | cout << "path\n"; 63 | } 64 | } 65 | 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /graph-theory/step1/D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | struct DSU { 7 | vector parent, sz; 8 | 9 | DSU(int n) { 10 | parent.resize(n+1); 11 | sz.resize(n+1); 12 | for (int i = 0; i <= n; i++) { 13 | parent[i] = i; 14 | sz[i] = 1; 15 | } 16 | } 17 | 18 | int get(int x) { 19 | if (x != parent[x]) parent[x] = get(parent[x]); 20 | return parent[x]; 21 | } 22 | 23 | void join(int a, int b) { 24 | int pa = get(a); 25 | int pb = get(b); 26 | if (pa == pb) return; 27 | 28 | if (sz[pa] > sz[pb]) swap(pa, pb); 29 | 30 | parent[pa] = pb; 31 | sz[pb] += sz[pa]; 32 | } 33 | }; 34 | 35 | int main(void) { 36 | ios_base::sync_with_stdio(false); 37 | cin.tie(NULL); 38 | cout.tie(NULL); 39 | 40 | int t; 41 | cin >> t; 42 | 43 | vector a(100001, 0); 44 | 45 | int n, m, k; 46 | while (t--) { 47 | cin >> n >> m >> k; 48 | 49 | a.assign(100001, 0); 50 | 51 | int x; 52 | for (int i = 0; i < k; i++) { 53 | cin >> x; 54 | a[x] = 1; 55 | } 56 | 57 | DSU dsu(n); 58 | int u, v; 59 | for (int i = 0; i < m; i++) { 60 | cin >> u >> v; 61 | dsu.join(u, v); 62 | } 63 | 64 | set s; 65 | for (int i = 1; i <= n; i++) { 66 | if (a[i] == 1) { 67 | s.insert(dsu.get(i)); 68 | } 69 | } 70 | 71 | bool ok = true; 72 | for (int i = 1; i <= n; i++) { 73 | if (a[i] == 0) { 74 | int p = dsu.get(i); 75 | if (s.contains(p)) { 76 | ok = false; 77 | break; 78 | } 79 | } 80 | } 81 | 82 | if (ok) cout << "YES\n"; 83 | else cout << "NO\n"; 84 | } 85 | 86 | return 0; 87 | } 88 | -------------------------------------------------------------------------------- /segment-tree-part1/step1/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | #define ll long long 19 | #define pb push_back 20 | #define loop(a) for(int i = 0; i < a; i++) 21 | #define loopv(i,a) for (int i = 0; i < a; i++) 22 | #define all(x) (x).begin(), (x).end() 23 | #define prDouble(x) cout << fixed << setprecision(10) << x 24 | #define goog(tno) cout << "Case #" << tno <<": " 25 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 26 | 27 | struct segtree { 28 | int size; 29 | vector vv; 30 | 31 | void build(vector &nums) { 32 | size = 1; 33 | while (size < nums.size()) size *= 2; 34 | vv.assign(2 * size, 0); 35 | build(nums, 0, 0, size); 36 | } 37 | 38 | void build(vector &nums, int x, int lx, int rx) { 39 | if (rx - lx == 1) { 40 | if (lx < nums.size()) { 41 | vv[x] = nums[lx]; 42 | } 43 | } else { 44 | int m = (lx + rx) / 2; 45 | build(nums, 2 * x + 1, lx, m); 46 | build(nums, 2 * x + 2, m, rx); 47 | vv[x] = vv[2 * x + 1] + vv[2 * x + 2]; 48 | } 49 | } 50 | 51 | void set(int i, int v) { 52 | set(i, v, 0, 0, size); 53 | } 54 | 55 | void set(int i, int v, int x, int lx, int rx) { 56 | if (rx - lx == 1) { 57 | vv[x] = v; 58 | } else { 59 | int m = (lx + rx) / 2; 60 | if (i < m) { 61 | set(i, v, 2*x+1, lx, m); 62 | } else { 63 | set(i, v, 2*x+2, m, rx); 64 | } 65 | vv[x] = vv[2*x+1] + vv[2*x+2]; 66 | } 67 | } 68 | 69 | ll sum(int l, int r) { 70 | return sum(l, r, 0, 0, size); 71 | } 72 | 73 | ll sum(int l, int r, int x, int lx, int rx) { 74 | if (r <= lx) return 0; 75 | if (l >= rx) return 0; 76 | if (lx >= l && rx <= r) return vv[x]; 77 | int m = (lx + rx) / 2; 78 | ll s1 = sum(l, r, 2*x+1, lx, m); 79 | ll s2 = sum(l, r, 2*x+2, m, rx); 80 | return s1 + s2; 81 | } 82 | }; 83 | 84 | int main(void) { 85 | int n, m; 86 | cin >> n >> m; 87 | 88 | segtree st; 89 | vector nums(n); 90 | 91 | loop(n) { 92 | cin >> nums[i]; 93 | } 94 | 95 | st.build(nums); 96 | 97 | int cmd; 98 | while (m--) { 99 | cin >> cmd; 100 | if (cmd == 1) { 101 | int i, v; 102 | cin >> i >> v; 103 | st.set(i, v); 104 | } else { 105 | int L, R; 106 | cin >> L >> R; 107 | cout << st.sum(L, R) << endl; 108 | } 109 | } 110 | 111 | return 0; 112 | } 113 | -------------------------------------------------------------------------------- /segment-tree-part1/step1/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | #define ll long long 19 | #define pb push_back 20 | #define loop(a) for(int i = 0; i < a; i++) 21 | #define loopv(i,a) for (int i = 0; i < a; i++) 22 | #define all(x) (x).begin(), (x).end() 23 | #define prDouble(x) cout << fixed << setprecision(10) << x 24 | #define goog(tno) cout << "Case #" << tno <<": " 25 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 26 | 27 | struct segtree { 28 | int size; 29 | vector vv; 30 | 31 | void build(vector &v) { 32 | size = 1; 33 | while (size < v.size()) size *= 2; 34 | vv.assign(2 * size, INT_MAX); 35 | build(v, 0, 0, size); 36 | } 37 | 38 | void build(vector &v, int x, int lx, int rx) { 39 | if (rx - lx == 1) { 40 | if (lx < v.size()) { 41 | vv[x] = v[lx]; 42 | } 43 | } else { 44 | int m = (lx + rx) / 2; 45 | build(v, 2*x+1, lx, m); 46 | build(v, 2*x+2, m, rx); 47 | vv[x] = ::min(vv[2*x+1], vv[2*x+2]); 48 | } 49 | } 50 | 51 | void set(int i, int v) { 52 | set(i, v, 0, 0, size); 53 | } 54 | 55 | void set(int i, int v, int x, int lx, int rx) { 56 | if (rx - lx == 1) { 57 | vv[x] = v; 58 | } else { 59 | int m = (lx + rx) / 2; 60 | if (i < m) set(i, v, 2*x+1, lx, m); 61 | else set(i, v, 2*x+2, m, rx); 62 | vv[x] = ::min(vv[2*x+1], vv[2*x+2]); 63 | } 64 | } 65 | 66 | int min(int l, int r) { 67 | return min(l, r, 0, 0, size); 68 | } 69 | 70 | int min(int l, int r, int x, int lx, int rx) { 71 | if (rx <= l) return INT_MAX; 72 | if (lx >= r) return INT_MAX; 73 | if (lx >= l && rx <= r) return vv[x]; 74 | int m = (lx + rx) / 2; 75 | int a = min(l, r, 2*x+1, lx, m); 76 | int b = min(l, r, 2*x+2, m, rx); 77 | return ::min(a, b); 78 | } 79 | }; 80 | 81 | int main(void) { 82 | int n, m; 83 | cin >> n >> m; 84 | 85 | vector nums(n); 86 | 87 | loop(n) { 88 | cin >> nums[i]; 89 | } 90 | 91 | segtree st; 92 | st.build(nums); 93 | 94 | int cmd; 95 | while (m--) { 96 | cin >> cmd; 97 | if (cmd == 1) { 98 | int i, v; 99 | cin >> i >> v; 100 | st.set(i, v); 101 | } else { 102 | int l, r; 103 | cin >> l >> r; 104 | cout << st.min(l, r) << endl; 105 | } 106 | } 107 | 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /segment-tree-part1/step1/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | #define ll long long 19 | #define pb push_back 20 | #define loop(a) for(int i = 0; i < a; i++) 21 | #define loopv(i,a) for (int i = 0; i < a; i++) 22 | #define all(x) (x).begin(), (x).end() 23 | #define prDouble(x) cout << fixed << setprecision(10) << x 24 | #define goog(tno) cout << "Case #" << tno <<": " 25 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 26 | 27 | struct segtree { 28 | int size; 29 | vector> vv; 30 | 31 | pair combine(pair a, pair b) { 32 | if (a.first < b.first) return a; 33 | if (b.first < a.first) return b; 34 | return { a.first, a.second + b.second }; 35 | } 36 | 37 | void build(vector &v) { 38 | size = 1; 39 | while (size < v.size()) size *= 2; 40 | vv.resize(2 * size, { INT_MAX, 0 }); 41 | build(v, 0, 0, size); 42 | } 43 | 44 | void build(vector &v, int x, int lx, int rx) { 45 | if (rx - lx == 1) { 46 | if (lx < v.size()) { 47 | vv[x] = { v[lx], 1 }; 48 | } 49 | } else { 50 | int m = (lx + rx) / 2; 51 | build(v, 2*x+1, lx, m); 52 | build(v, 2*x+2, m, rx); 53 | vv[x] = combine(vv[2*x+1], vv[2*x+2]); 54 | } 55 | } 56 | 57 | void set(int i, int v) { 58 | set(i, v, 0, 0, size); 59 | } 60 | 61 | void set(int i, int v, int x, int lx, int rx) { 62 | if (rx - lx == 1) { 63 | vv[x] = { v, 1 }; 64 | } else { 65 | int m = (lx + rx) / 2; 66 | if (i < m) 67 | set(i, v, 2*x+1, lx, m); 68 | else 69 | set(i, v, 2*x+2, m, rx); 70 | vv[x] = combine(vv[2*x+1], vv[2*x+2]); 71 | } 72 | } 73 | 74 | pair calc(int l, int r) { 75 | return calc(l, r, 0, 0, size); 76 | } 77 | 78 | pair calc(int l, int r, int x, int lx, int rx) { 79 | if (lx >= r) return { INT_MAX, 0 }; 80 | if (rx <= l) return { INT_MAX, 0 }; 81 | if (lx >= l && rx <= r) return vv[x]; 82 | int m = (lx + rx) / 2; 83 | auto a = calc(l, r, 2*x+1, lx, m); 84 | auto b = calc(l, r, 2*x+2, m, rx); 85 | return combine(a, b); 86 | } 87 | }; 88 | 89 | int main(void) { 90 | int n, m; 91 | cin >> n >> m; 92 | 93 | vector nums(n); 94 | 95 | loop(n) { 96 | cin >> nums[i]; 97 | } 98 | 99 | segtree st; 100 | st.build(nums); 101 | 102 | int cmd; 103 | while (m--) { 104 | cin >> cmd; 105 | if (cmd == 1) { 106 | int i, v; 107 | cin >> i >> v; 108 | st.set(i, v); 109 | } else { 110 | int l, r; 111 | cin >> l >> r; 112 | auto [a, b] = st.calc(l, r); 113 | cout << a << " " << b << endl; 114 | } 115 | } 116 | 117 | return 0; 118 | } 119 | -------------------------------------------------------------------------------- /segment-tree-part1/step2/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | #define ll long long 19 | #define pb push_back 20 | #define loop(a) for(int i = 0; i < a; i++) 21 | #define loopv(i,a) for (int i = 0; i < a; i++) 22 | #define all(x) (x).begin(), (x).end() 23 | #define prDouble(x) cout << fixed << setprecision(10) << x 24 | #define goog(tno) cout << "Case #" << tno <<": " 25 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 26 | 27 | struct segtree { 28 | int size; 29 | struct node { 30 | ll sum, pref, suf, seg; 31 | }; 32 | vector tree; 33 | 34 | const node ZERO = { 0, 0, 0, 0 }; 35 | 36 | node combine(node a, node b) { 37 | return { 38 | a.sum + b.sum, 39 | max(a.pref, a.sum + b.pref), 40 | max(b.suf, a.suf + b.sum), 41 | max(max(a.seg, b.seg), a.suf + b.pref) 42 | }; 43 | } 44 | 45 | node one_element(int v) { 46 | return { 47 | v, 48 | max(v, 0), 49 | max(v, 0), 50 | max(v, 0) 51 | }; 52 | } 53 | 54 | void build(vector &a) { 55 | size = 1; 56 | while (size < a.size()) size *= 2; 57 | tree.assign(2 * size, ZERO); 58 | build(a, 0, 0, size); 59 | } 60 | 61 | void build(vector &a, int x, int lx, int rx) { 62 | if (rx == lx + 1) { 63 | if (lx < a.size()) { 64 | tree[x] = one_element(a[lx]); 65 | } 66 | } else { 67 | int m = (lx + rx) / 2; 68 | build(a, 2*x+1, lx, m); 69 | build(a, 2*x+2, m, rx); 70 | tree[x] = combine(tree[2*x+1], tree[2*x+2]); 71 | } 72 | } 73 | 74 | void set(int idx, int v) { 75 | set(idx, v, 0, 0, size); 76 | } 77 | 78 | void set(int idx, int v, int x, int lx, int rx) { 79 | if (rx == lx + 1) { 80 | tree[x] = one_element(v); 81 | } else { 82 | int m = (lx + rx) / 2; 83 | if (idx < m) { 84 | set(idx, v, 2*x+1, lx, m); 85 | } else { 86 | set(idx, v, 2*x+2, m, rx); 87 | } 88 | tree[x] = combine(tree[2*x+1], tree[2*x+2]); 89 | } 90 | } 91 | }; 92 | 93 | int main(void) { 94 | int n, m; 95 | cin >> n >> m; 96 | 97 | vector a(n); 98 | loop(n) cin >> a[i]; 99 | 100 | segtree st; 101 | st.build(a); 102 | 103 | cout << st.tree[0].seg << endl; 104 | 105 | int i, v; 106 | while (m--) { 107 | cin >> i >> v; 108 | st.set(i, v); 109 | cout << st.tree[0].seg << endl; 110 | } 111 | 112 | return 0; 113 | } 114 | -------------------------------------------------------------------------------- /segment-tree-part1/step2/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | #define ll long long 19 | #define pb push_back 20 | #define loop(a) for(int i = 0; i < a; i++) 21 | #define loopv(i,a) for (int i = 0; i < a; i++) 22 | #define all(x) (x).begin(), (x).end() 23 | #define prDouble(x) cout << fixed << setprecision(10) << x 24 | #define goog(tno) cout << "Case #" << tno <<": " 25 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 26 | 27 | struct segtree { 28 | int size; 29 | vector tree; 30 | 31 | void build(vector &a) { 32 | size = 1; 33 | while (size < a.size()) size *= 2; 34 | tree.assign(2*size, 0); 35 | build(a, 0, 0, size); 36 | } 37 | 38 | void build(vector &a, int x, int lx, int rx) { 39 | if (rx == lx + 1) { 40 | if (lx < a.size()) { 41 | tree[x] = a[lx]; 42 | } 43 | } else { 44 | int m = (lx + rx) / 2; 45 | build(a, 2*x+1, lx, m); 46 | build(a, 2*x+2, m, rx); 47 | tree[x] = tree[2*x+1] + tree[2*x+2]; 48 | } 49 | } 50 | 51 | void set(int idx, int v) { 52 | set(idx, v, 0, 0, size); 53 | } 54 | 55 | void set(int idx, int v, int x, int lx, int rx) { 56 | if (rx == lx + 1) { 57 | tree[x] = v; 58 | } else { 59 | int m = (lx + rx) / 2; 60 | if (idx < m) 61 | set(idx, v, 2*x+1, lx, m); 62 | else 63 | set(idx, v, 2*x+2, m, rx); 64 | tree[x] = tree[2*x+1] + tree[2*x+2]; 65 | } 66 | } 67 | 68 | int find(int k) { 69 | return find(k, 0, 0, size); 70 | } 71 | 72 | int find(int k, int x, int lx, int rx) { 73 | if (tree[x] <= k) return -1; 74 | if (rx == lx + 1) return lx; 75 | int m = (lx + rx) / 2; 76 | int res = find(k, 2*x+1, lx, m); 77 | if (res == -1) 78 | res = find(k - tree[2*x+1], 2*x+2, m, rx); 79 | return res; 80 | } 81 | }; 82 | 83 | int main(void) { 84 | int n, m; 85 | cin >> n >> m; 86 | 87 | vector a(n); 88 | loop(n) cin >> a[i]; 89 | 90 | segtree st; 91 | st.build(a); 92 | 93 | int cmd, i, k; 94 | while (m--) { 95 | cin >> cmd; 96 | if (cmd == 1) { 97 | cin >> i; 98 | a[i] = 1 - a[i]; 99 | st.set(i, a[i]); 100 | } else { 101 | cin >> k; 102 | cout << st.find(k) << endl; 103 | } 104 | } 105 | 106 | return 0; 107 | } 108 | 109 | -------------------------------------------------------------------------------- /segment-tree-part1/step2/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | #define ll long long 19 | #define pb push_back 20 | #define loop(a) for(int i = 0; i < a; i++) 21 | #define loopv(i,a) for (int i = 0; i < a; i++) 22 | #define all(x) (x).begin(), (x).end() 23 | #define prDouble(x) cout << fixed << setprecision(10) << x 24 | #define goog(tno) cout << "Case #" << tno <<": " 25 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 26 | 27 | struct segtree { 28 | int size; 29 | vector tree; 30 | 31 | void build(vector &a) { 32 | size = 1; 33 | while (size < a.size()) size *= 2; 34 | tree.assign(2*size, 0); 35 | build(a, 0, 0, size); 36 | } 37 | 38 | void build(vector &a, int x, int lx, int rx) { 39 | if (rx == lx + 1) { 40 | if (lx < a.size()) { 41 | tree[x] = a[lx]; 42 | } 43 | } else { 44 | int m = (lx + rx) / 2; 45 | build(a, 2*x+1, lx, m); 46 | build(a, 2*x+2, m, rx); 47 | tree[x] = max(tree[2*x+1], tree[2*x+2]); 48 | } 49 | } 50 | 51 | void set(int idx, int v) { 52 | set(idx, v, 0, 0, size); 53 | } 54 | 55 | void set(int idx, int v, int x, int lx, int rx) { 56 | if (rx == lx+1) { 57 | tree[x] = v; 58 | } else { 59 | int m = (lx + rx) / 2; 60 | if (idx < m) 61 | set(idx, v, 2*x+1, lx, m); 62 | else 63 | set(idx, v, 2*x+2, m, rx); 64 | tree[x] = max(tree[2*x+1], tree[2*x+2]); 65 | } 66 | } 67 | 68 | int find(int v) { 69 | return find(v, 0, 0, size); 70 | } 71 | 72 | int find(int v, int x, int lx, int rx) { 73 | if (tree[x] < v) return -1; 74 | if (rx == lx + 1) return lx; 75 | int m = (lx + rx) / 2; 76 | int res = find(v, 2*x+1, lx, m); 77 | if (res == -1) 78 | res = find(v, 2*x+2, m, rx); 79 | return res; 80 | } 81 | }; 82 | 83 | int main(void) { 84 | int n, m; 85 | cin >> n >> m; 86 | 87 | vector a(n); 88 | loop(n) cin >> a[i]; 89 | 90 | segtree st; 91 | st.build(a); 92 | 93 | int cmd, i, v; 94 | while (m--) { 95 | cin >> cmd; 96 | if (cmd == 1) { 97 | cin >> i >> v; 98 | st.set(i, v); 99 | } else { 100 | cin >> v; 101 | cout << st.find(v) << endl; 102 | } 103 | } 104 | 105 | return 0; 106 | } 107 | -------------------------------------------------------------------------------- /segment-tree-part1/step2/D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | #define ll long long 19 | #define pb push_back 20 | #define loop(a) for(int i = 0; i < a; i++) 21 | #define loopv(i,a) for (int i = 0; i < a; i++) 22 | #define all(x) (x).begin(), (x).end() 23 | #define prDouble(x) cout << fixed << setprecision(10) << x 24 | #define goog(tno) cout << "Case #" << tno <<": " 25 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 26 | 27 | struct segtree { 28 | int size; 29 | vector tree; 30 | 31 | void build(vector &a) { 32 | size = 1; 33 | while (size < a.size()) size *= 2; 34 | tree.assign(2*size, 0); 35 | build(a, 0, 0, size); 36 | } 37 | 38 | void build(vector &a, int x, int lx, int rx) { 39 | if (rx == lx + 1) { 40 | if (lx < a.size()) { 41 | tree[x] = a[lx]; 42 | } 43 | } else { 44 | int m = (lx + rx) / 2; 45 | build(a, 2*x+1, lx, m); 46 | build(a, 2*x+2, m, rx); 47 | tree[x] = max(tree[2*x+1], tree[2*x+2]); 48 | } 49 | } 50 | 51 | void set(int idx, int v) { 52 | set(idx, v, 0, 0, size); 53 | } 54 | 55 | void set(int idx, int v, int x, int lx, int rx) { 56 | if (rx == lx+1) { 57 | tree[x] = v; 58 | } else { 59 | int m = (lx + rx) / 2; 60 | if (idx < m) 61 | set(idx, v, 2*x+1, lx, m); 62 | else 63 | set(idx, v, 2*x+2, m, rx); 64 | tree[x] = max(tree[2*x+1], tree[2*x+2]); 65 | } 66 | } 67 | 68 | int find(int v, int l) { 69 | return find(v, l, 0, 0, size); 70 | } 71 | 72 | int find(int v, int l, int x, int lx, int rx) { 73 | if (tree[x] < v) return -1; 74 | if (rx <= l) return -1; 75 | if (rx == lx + 1) return lx; 76 | int m = (lx + rx) / 2; 77 | int res = find(v, l, 2*x+1, lx, m); 78 | if (res == -1) 79 | res = find(v, l, 2*x+2, m, rx); 80 | return res; 81 | } 82 | }; 83 | 84 | int main(void) { 85 | int n, m; 86 | cin >> n >> m; 87 | 88 | vector a(n); 89 | loop(n) cin >> a[i]; 90 | 91 | segtree st; 92 | st.build(a); 93 | 94 | int cmd, i, v, l; 95 | while (m--) { 96 | cin >> cmd; 97 | if (cmd == 1) { 98 | cin >> i >> v; 99 | st.set(i, v); 100 | } else { 101 | cin >> v >> l; 102 | cout << st.find(v, l) << endl; 103 | } 104 | } 105 | 106 | return 0; 107 | } 108 | -------------------------------------------------------------------------------- /segment-tree-part1/step3/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | #define ll long long 19 | #define pb push_back 20 | #define loop(a) for(int i = 0; i < a; i++) 21 | #define loopv(i,a) for (int i = 0; i < a; i++) 22 | #define all(x) (x).begin(), (x).end() 23 | #define prDouble(x) cout << fixed << setprecision(10) << x 24 | #define goog(tno) cout << "Case #" << tno <<": " 25 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 26 | 27 | struct segtree { 28 | int size; 29 | vector tree; 30 | 31 | void build(int n) { 32 | size = 1; 33 | while (size < n) size *= 2; 34 | tree.assign(2*size, 0); 35 | } 36 | 37 | void set(int idx, int v) { 38 | set(idx, v, 0, 0, size); 39 | } 40 | 41 | void set(int idx, int v, int x, int lx, int rx) { 42 | if (rx == lx + 1) { 43 | tree[x] = v; 44 | } else { 45 | int m = (lx + rx) / 2; 46 | if (idx < m) 47 | set(idx, v, 2*x+1, lx, m); 48 | else 49 | set(idx, v, 2*x+2, m, rx); 50 | tree[x] = tree[2*x+1] + tree[2*x+2]; 51 | } 52 | } 53 | 54 | int sum(int l, int r) { 55 | return sum(l, r, 0, 0, size); 56 | } 57 | 58 | int sum(int l, int r, int x, int lx, int rx) { 59 | if (rx <= l) return 0; 60 | if (lx >= r) return 0; 61 | if (lx >= l && rx <= r) return tree[x]; 62 | int m = (lx + rx) / 2; 63 | return sum(l, r, 2*x+1, lx, m) + sum(l, r, 2*x+2, m, rx); 64 | } 65 | }; 66 | 67 | int main(void) { 68 | int n; 69 | cin >> n; 70 | 71 | segtree st; 72 | st.build(n); 73 | 74 | int v; 75 | loop(n) { 76 | cin >> v; 77 | if (i > 0) cout << " "; 78 | cout << st.sum(v - 1, n); 79 | st.set(v - 1, 1); 80 | } 81 | cout << endl; 82 | 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /segment-tree-part1/step3/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | #define ll long long 19 | #define pb push_back 20 | #define loop(a) for(int i = 0; i < a; i++) 21 | #define loopv(i,a) for (int i = 0; i < a; i++) 22 | #define all(x) (x).begin(), (x).end() 23 | #define prDouble(x) cout << fixed << setprecision(10) << x 24 | #define goog(tno) cout << "Case #" << tno <<": " 25 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 26 | 27 | struct segtree { 28 | int size; 29 | vector tree; 30 | 31 | void build(vector &a) { 32 | size = 1; 33 | while (size < a.size()) size *= 2; 34 | tree.assign(2*size, 0); 35 | build(a, 0, 0, size); 36 | } 37 | 38 | void build(vector &a, int x, int lx, int rx) { 39 | if (rx == lx + 1) { 40 | if (lx < a.size()) { 41 | tree[x] = a[lx]; 42 | } 43 | } else { 44 | int m = (lx + rx) / 2; 45 | build(a, 2*x+1, lx, m); 46 | build(a, 2*x+2, m, rx); 47 | tree[x] = tree[2*x+1] + tree[2*x+2]; 48 | } 49 | } 50 | 51 | void set(int idx, int v) { 52 | set(idx, v, 0, 0, size); 53 | } 54 | 55 | void set(int idx, int v, int x, int lx, int rx) { 56 | if (rx == lx + 1) { 57 | tree[x] = v; 58 | } else { 59 | int m = (lx + rx) / 2; 60 | if (idx < m) 61 | set(idx, v, 2*x+1, lx, m); 62 | else 63 | set(idx, v, 2*x+2, m, rx); 64 | tree[x] = tree[2*x+1] + tree[2*x+2]; 65 | } 66 | } 67 | 68 | int find(int k) { 69 | return find(k, 0, 0, size); 70 | } 71 | 72 | int find(int k, int x, int lx, int rx) { 73 | if (tree[x] <= k) return -1; 74 | if (rx == lx + 1) return lx; 75 | int m = (lx + rx) / 2; 76 | int res = find(k, 2*x+1, lx, m); 77 | if (res == -1) 78 | res = find(k - tree[2*x+1], 2*x+2, m, rx); 79 | return res; 80 | } 81 | }; 82 | 83 | int main(void) { 84 | int n; 85 | cin >> n; 86 | vector a(n); 87 | loop(n) cin >> a[i]; 88 | 89 | vector b(n, 1); 90 | segtree st; 91 | st.build(b); 92 | 93 | vector result(n); 94 | int all = n; 95 | for (int i = n - 1; i >= 0; i--) { 96 | int x = st.find(all - a[i] - 1); 97 | st.set(x, 0); 98 | --all; 99 | result[i] = x + 1; 100 | } 101 | 102 | loop(n) { 103 | if (i > 0) cout << " "; 104 | cout << result[i]; 105 | } 106 | cout << endl; 107 | 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /segment-tree-part1/step3/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | #define ll long long 19 | #define pb push_back 20 | #define loop(a) for(int i = 0; i < a; i++) 21 | #define loopv(i,a) for (int i = 0; i < a; i++) 22 | #define rep(i,a,b) for (int i = a; i < b; i++) 23 | #define all(x) (x).begin(), (x).end() 24 | #define prDouble(x) cout << fixed << setprecision(10) << x 25 | #define goog(tno) cout << "Case #" << tno <<": " 26 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 27 | 28 | struct segtree { 29 | int size; 30 | vector tree; 31 | 32 | void build(int n) { 33 | size = 1; 34 | while (size < n) size *= 2; 35 | tree.assign(2*size, 0); 36 | } 37 | 38 | void set(int idx, int v) { 39 | set(idx, v, 0, 0, size); 40 | } 41 | 42 | void set(int idx, int v, int x, int lx, int rx) { 43 | if (rx == lx + 1) { 44 | tree[x] = v; 45 | } else { 46 | int m = (lx + rx) / 2; 47 | if (idx < m) 48 | set(idx, v, 2*x+1, lx, m); 49 | else 50 | set(idx, v, 2*x+2, m, rx); 51 | tree[x] = tree[2*x+1] + tree[2*x+2]; 52 | } 53 | } 54 | 55 | int sum(int l, int r) { 56 | return sum(l, r, 0, 0, size); 57 | } 58 | 59 | int sum(int l, int r, int x, int lx, int rx) { 60 | if (lx >= r) return 0; 61 | if (rx <= l) return 0; 62 | if (lx >= l && rx <= r) return tree[x]; 63 | int m = (lx + rx) / 2; 64 | return sum(l, r, 2*x+1, lx, m) + sum(l, r, 2*x+2, m, rx); 65 | } 66 | }; 67 | 68 | int main(void) { 69 | int n; 70 | cin >> n; 71 | 72 | vector visited(n+1, -1); 73 | vector a(2*n); 74 | vector result(n+1); 75 | loop(2*n) cin >> a[i]; 76 | 77 | segtree st; 78 | st.build(2*n); 79 | 80 | loop(2*n) { 81 | if (visited[a[i]] == -1) { 82 | visited[a[i]] = i; 83 | } else { 84 | result[a[i]] = st.sum(visited[a[i]], i); 85 | st.set(visited[a[i]], 1); 86 | } 87 | } 88 | 89 | rep (i, 1, n + 1) { 90 | if (i > 1) cout << " "; 91 | cout << result[i]; 92 | } 93 | cout << endl; 94 | 95 | return 0; 96 | } 97 | -------------------------------------------------------------------------------- /segment-tree-part1/step3/D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | #define ll long long 19 | #define pb push_back 20 | #define loop(a) for(int i = 0; i < a; i++) 21 | #define loopv(i,a) for (int i = 0; i < a; i++) 22 | #define rep(i,a,b) for (int i = a; i < b; i++) 23 | #define all(x) (x).begin(), (x).end() 24 | #define prDouble(x) cout << fixed << setprecision(10) << x 25 | #define goog(tno) cout << "Case #" << tno <<": " 26 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 27 | 28 | struct segtree { 29 | int size; 30 | vector tree; 31 | 32 | void build(int n) { 33 | size = 1; 34 | while (size < n) size *= 2; 35 | tree.assign(2 * size, 0); 36 | } 37 | 38 | void set(int idx, int v) { 39 | set(idx, v, 0, 0, size); 40 | } 41 | 42 | void set(int idx, int v, int x, int lx, int rx) { 43 | if (rx == lx + 1) { 44 | tree[x] = v; 45 | } else { 46 | int m = (lx + rx) / 2; 47 | if (idx < m) 48 | set(idx, v, 2*x+1, lx, m); 49 | else 50 | set(idx, v, 2*x+2, m, rx); 51 | tree[x] = tree[2*x+1] + tree[2*x+2]; 52 | } 53 | } 54 | 55 | int sum(int l, int r) { 56 | return sum(l, r, 0, 0, size); 57 | } 58 | 59 | int sum(int l, int r, int x, int lx, int rx) { 60 | if (lx >= r) return 0; 61 | if (rx <= l) return 0; 62 | if (lx >= l && rx <= r) return tree[x]; 63 | int m = (lx + rx) / 2; 64 | return sum(l, r, 2*x+1, lx, m) + sum(l, r, 2*x+2, m, rx); 65 | } 66 | }; 67 | 68 | int main(void) { 69 | int n; 70 | cin >> n; 71 | 72 | vector result(n+1); 73 | vector visited(2*n+1, -1); 74 | vector a(2*n); 75 | loop(2*n) cin >> a[i]; 76 | 77 | segtree st; 78 | st.build(2*n+1); 79 | 80 | loop(2*n) { 81 | if (visited[a[i]] == -1) { 82 | st.set(i, 1); 83 | visited[a[i]] = i; 84 | } else { 85 | st.set(visited[a[i]], 0); 86 | result[a[i]] += st.sum(visited[a[i]], i); 87 | } 88 | } 89 | 90 | st.build(2*n+1); 91 | visited.assign(2*n+1, -1); 92 | 93 | for (int i = 2*n-1; i >= 0; i--) { 94 | if (visited[a[i]] == -1) { 95 | st.set(i, 1); 96 | visited[a[i]] = i; 97 | } else { 98 | st.set(visited[a[i]], 0); 99 | result[a[i]] += st.sum(i, visited[a[i]]); 100 | } 101 | } 102 | 103 | rep (i, 1, n+1) { 104 | if (i > 1) cout << " "; 105 | cout << result[i]; 106 | } 107 | cout << endl; 108 | 109 | return 0; 110 | } 111 | -------------------------------------------------------------------------------- /segment-tree-part1/step3/E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | #define ll long long 19 | #define pb push_back 20 | #define loop(a) for(int i = 0; i < a; i++) 21 | #define loopv(i,a) for (int i = 0; i < a; i++) 22 | #define rep(i,a,b) for (int i = a; i < b; i++) 23 | #define all(x) (x).begin(), (x).end() 24 | #define prDouble(x) cout << fixed << setprecision(10) << x 25 | #define goog(tno) cout << "Case #" << tno <<": " 26 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 27 | 28 | struct segtree { 29 | int size; 30 | vector tree; 31 | 32 | void build(int n) { 33 | size = 1; 34 | while (size < n) size *= 2; 35 | tree.assign(2*size, 0); 36 | } 37 | 38 | void set(int idx, int v) { 39 | set(idx, v, 0, 0, size); 40 | } 41 | 42 | void set(int idx, int v, int x, int lx, int rx) { 43 | if (rx == lx + 1) { 44 | tree[x] += v; 45 | } else { 46 | int m = (lx + rx) / 2; 47 | if (idx < m) 48 | set(idx, v, 2*x+1, lx, m); 49 | else 50 | set(idx, v, 2*x+2, m, rx); 51 | tree[x] = tree[2*x+1] + tree[2*x+2]; 52 | } 53 | } 54 | 55 | ll sum(int l, int r) { 56 | return sum(l, r, 0, 0, size); 57 | } 58 | 59 | ll sum(int l, int r, int x, int lx, int rx) { 60 | if (lx >= r) return 0; 61 | if (rx <= l) return 0; 62 | if (lx >= l && rx <= r) return tree[x]; 63 | int m = (lx + rx) / 2; 64 | return sum(l, r, 2*x+1, lx, m) + sum(l, r, 2*x+2, m, rx); 65 | } 66 | }; 67 | 68 | int main(void) { 69 | int n, m; 70 | cin >> n >> m; 71 | 72 | segtree st; 73 | st.build(n); 74 | 75 | int cmd; 76 | while (m--) { 77 | cin >> cmd; 78 | if (cmd == 1) { 79 | int l, r, v; 80 | cin >> l >> r >> v; 81 | st.set(l, v); 82 | if (r < n) 83 | st.set(r, -v); 84 | } else { 85 | int i; 86 | cin >> i; 87 | cout << st.sum(0, i+1) << endl; 88 | } 89 | } 90 | 91 | return 0; 92 | } 93 | -------------------------------------------------------------------------------- /segment-tree-part1/step4/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | #define ll long long 19 | #define pb push_back 20 | #define loop(a) for(int i = 0; i < a; i++) 21 | #define loopv(i,a) for (int i = 0; i < a; i++) 22 | #define rep(i,a,b) for (int i = a; i < b; i++) 23 | #define all(x) (x).begin(), (x).end() 24 | #define prDouble(x) cout << fixed << setprecision(10) << x 25 | #define goog(tno) cout << "Case #" << tno <<": " 26 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 27 | 28 | struct segtree { 29 | int size; 30 | 31 | struct node { 32 | ll sum; 33 | int cnt; 34 | }; 35 | vector tree; 36 | 37 | node combine(node a, node b) { 38 | if (a.cnt % 2 == 0) return { a.sum + b.sum, a.cnt + b.cnt }; 39 | else return { a.sum - b.sum, a.cnt + b.cnt }; 40 | } 41 | 42 | void build(vector &a) { 43 | size = 1; 44 | while (size < a.size()) size *= 2; 45 | tree.assign(2*size, {0, 0}); 46 | build(a, 0, 0, size); 47 | } 48 | 49 | void build(vector &a, int x, int lx, int rx) { 50 | if (rx == lx + 1) { 51 | if (lx < a.size()) { 52 | tree[x] = {a[lx], 1}; 53 | } 54 | } else { 55 | int m = (lx + rx) / 2; 56 | build(a, 2*x+1, lx, m); 57 | build(a, 2*x+2, m, rx); 58 | tree[x] = combine(tree[2*x+1], tree[2*x+2]); 59 | } 60 | } 61 | 62 | void set(int idx, int v) { 63 | set(idx, v, 0, 0, size); 64 | } 65 | 66 | void set(int idx, int v, int x, int lx, int rx) { 67 | if (rx == lx + 1) { 68 | tree[x] = { v, 1 }; 69 | } else { 70 | int m = (lx + rx) / 2; 71 | if (idx < m) 72 | set(idx, v, 2*x+1, lx, m); 73 | else 74 | set(idx, v, 2*x+2, m, rx); 75 | tree[x] = combine(tree[2*x+1], tree[2*x+2]); 76 | } 77 | } 78 | 79 | ll calc(int l, int r) { 80 | return calc(l, r, 0, 0, size).sum; 81 | } 82 | 83 | node calc(int l, int r, int x, int lx, int rx) { 84 | if (lx >= r) return { 0, 0 }; 85 | if (rx <= l) return { 0, 0 }; 86 | if (lx >= l && rx <= r) return tree[x]; 87 | int m = (lx + rx) / 2; 88 | return combine(calc(l, r, 2*x+1, lx, m), calc(l, r, 2*x+2, m, rx)); 89 | } 90 | }; 91 | 92 | int main(void) { 93 | int n; 94 | cin >> n; 95 | 96 | vector a(n); 97 | loop(n) cin >> a[i]; 98 | 99 | segtree st; 100 | st.build(a); 101 | 102 | int m, cmd; 103 | cin >> m; 104 | while (m--) { 105 | cin >> cmd; 106 | if (cmd == 0) { 107 | int i, v; 108 | cin >> i >> v; 109 | --i; 110 | st.set(i, v); 111 | } else { 112 | int l, r; 113 | cin >> l >> r; 114 | --l; 115 | cout << st.calc(l, r) << endl; 116 | } 117 | } 118 | 119 | return 0; 120 | } 121 | -------------------------------------------------------------------------------- /segment-tree-part1/step4/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | #define ll long long 19 | #define pb push_back 20 | #define loop(a) for(int i = 0; i < a; i++) 21 | #define loopv(i,a) for (int i = 0; i < a; i++) 22 | #define rep(i,a,b) for (int i = a; i < b; i++) 23 | #define all(x) (x).begin(), (x).end() 24 | #define prDouble(x) cout << fixed << setprecision(10) << x 25 | #define goog(tno) cout << "Case #" << tno <<": " 26 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 27 | 28 | int r; 29 | struct matrix { 30 | int a,b,c,d; 31 | }; 32 | 33 | struct segtree { 34 | int size; 35 | vector tree; 36 | 37 | matrix combine(matrix a, matrix b) { 38 | return { 39 | (a.a * b.a + a.b * b.c) % r, 40 | (a.a * b.b + a.b * b.d) % r, 41 | (a.c * b.a + a.d * b.c) % r, 42 | (a.c * b.b + a.d * b.d) % r 43 | }; 44 | } 45 | 46 | void build(vector &a) { 47 | size = 1; 48 | while (size < a.size()) size *= 2; 49 | tree.assign(2*size, {1,0,0,1}); 50 | build(a, 0, 0, size); 51 | } 52 | 53 | void build(vector &a, int x, int lx, int rx) { 54 | if (rx == lx + 1) { 55 | if (lx < a.size()) { 56 | tree[x] = a[lx]; 57 | } 58 | } else { 59 | int m = (lx + rx) / 2; 60 | build(a, 2*x+1, lx, m); 61 | build(a, 2*x+2, m, rx); 62 | tree[x] = combine(tree[2*x+1], tree[2*x+2]); 63 | } 64 | } 65 | 66 | matrix calc(int L, int R) { 67 | return calc(L, R, 0, 0, size); 68 | } 69 | 70 | matrix calc(int L, int R, int x, int lx, int rx) { 71 | if (lx >= R) return {1,0,0,1}; 72 | if (rx <= L) return {1,0,0,1}; 73 | if (lx >= L && rx <= R) return tree[x]; 74 | int m = (lx + rx) / 2; 75 | return combine(calc(L, R, 2*x+1, lx, m), calc(L, R, 2*x+2, m, rx)); 76 | } 77 | }; 78 | 79 | int main(void) { 80 | int n, m; 81 | cin >> r >> n >> m; 82 | 83 | vector a(n); 84 | loop(n) { 85 | scanf("%d%d%d%d", &a[i].a, &a[i].b, &a[i].c, &a[i].d); 86 | } 87 | 88 | segtree st; 89 | st.build(a); 90 | 91 | int L, R; 92 | while (m--) { 93 | cin >> L >> R, --L; 94 | matrix result = st.calc(L, R); 95 | printf("%d %d\n%d %d\n", result.a, result.b, result.c, result.d); 96 | if (m > 0) printf("\n"); 97 | } 98 | 99 | return 0; 100 | } 101 | -------------------------------------------------------------------------------- /segment-tree-part1/step4/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | #define ll long long 19 | #define pb push_back 20 | #define loop(a) for(int i = 0; i < a; i++) 21 | #define loopv(i,a) for (int i = 0; i < a; i++) 22 | #define rep(i,a,b) for (int i = a; i < b; i++) 23 | #define all(x) (x).begin(), (x).end() 24 | #define prDouble(x) cout << fixed << setprecision(10) << x 25 | #define goog(tno) cout << "Case #" << tno <<": " 26 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 27 | 28 | struct segtree { 29 | struct node { 30 | int freq[41]; 31 | ll cnt; 32 | }; 33 | 34 | int size; 35 | vector tree; 36 | node ZERO; 37 | 38 | node combine(node a, node b) { 39 | node result; 40 | memset(result.freq, 0, sizeof result.freq); 41 | 42 | loop(41) result.freq[i] = a.freq[i] + b.freq[i]; 43 | ll count = a.cnt + b.cnt; 44 | 45 | rep (i, 0, 41) { 46 | rep (j, i + 1, 41) { 47 | count += b.freq[i] * a.freq[j]; 48 | } 49 | } 50 | 51 | result.cnt = count; 52 | 53 | return result; 54 | } 55 | 56 | void build(vector &a) { 57 | memset(ZERO.freq, 0, sizeof ZERO.freq); 58 | ZERO.cnt = 0; 59 | 60 | size = 1; 61 | while (size < a.size()) size *= 2; 62 | tree.assign(2 * size, ZERO); 63 | build(a, 0, 0, size); 64 | } 65 | 66 | void build(vector &a, int x, int lx, int rx) { 67 | if (rx == lx + 1) { 68 | if (lx < a.size()) { 69 | memset(tree[x].freq, 0, sizeof tree[x].freq); 70 | tree[x].freq[a[lx]]++; 71 | tree[x].cnt = 0; 72 | } 73 | } else { 74 | int m = (lx + rx) / 2; 75 | build(a, 2*x+1, lx, m); 76 | build(a, 2*x+2, m, rx); 77 | tree[x] = combine(tree[2*x+1], tree[2*x+2]); 78 | } 79 | } 80 | 81 | void set(int idx, int v) { 82 | set(idx, v, 0, 0, size); 83 | } 84 | 85 | void set(int idx, int v, int x, int lx, int rx) { 86 | if (rx == lx + 1) { 87 | memset(tree[x].freq, 0, sizeof tree[x].freq); 88 | tree[x].freq[v]++; 89 | tree[x].cnt = 0; 90 | } else { 91 | int m = (lx + rx) / 2; 92 | if (idx < m) 93 | set(idx, v, 2*x+1, lx, m); 94 | else 95 | set(idx, v, 2*x+2, m, rx); 96 | tree[x] = combine(tree[2*x+1], tree[2*x+2]); 97 | } 98 | } 99 | 100 | ll calc(int l, int r) { 101 | return (calc(l, r, 0, 0, size)).cnt; 102 | } 103 | 104 | node calc(int l, int r, int x, int lx, int rx) { 105 | if (lx >= r) return ZERO; 106 | if (rx <= l) return ZERO; 107 | if (lx >= l && rx <= r) return tree[x]; 108 | int m = (lx + rx) / 2; 109 | return combine(calc(l, r, 2*x+1, lx, m), calc(l, r, 2*x+2, m, rx)); 110 | } 111 | }; 112 | 113 | int main(void) { 114 | int n, q; 115 | cin >> n >> q; 116 | 117 | vector a(n); 118 | loop(n) cin >> a[i];; 119 | 120 | segtree st; 121 | st.build(a); 122 | 123 | int cmd; 124 | while (q--) { 125 | cin >> cmd; 126 | if (cmd == 1) { 127 | int L, R; 128 | cin >> L >> R, --L; 129 | cout << st.calc(L, R) << endl; 130 | } else { 131 | int i, v; 132 | cin >> i >> v, --i; 133 | st.set(i, v); 134 | } 135 | } 136 | 137 | return 0; 138 | } 139 | -------------------------------------------------------------------------------- /segment-tree-part1/step4/D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | #define ll long long 19 | #define pb push_back 20 | #define loop(a) for(int i = 0; i < a; i++) 21 | #define loopv(i,a) for (int i = 0; i < a; i++) 22 | #define rep(i,a,b) for (int i = a; i < b; i++) 23 | #define all(x) (x).begin(), (x).end() 24 | #define prDouble(x) cout << fixed << setprecision(10) << x 25 | #define goog(tno) cout << "Case #" << tno <<": " 26 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 27 | 28 | struct segtree { 29 | struct node { 30 | int freq[41]; 31 | int cnt; 32 | }; 33 | 34 | int size; 35 | vector tree; 36 | node ZERO; 37 | 38 | node combine(node a, node b) { 39 | node result; 40 | memset(result.freq, 0, sizeof result.freq); 41 | 42 | loop(41) result.freq[i] = a.freq[i] + b.freq[i]; 43 | int count = 0; 44 | 45 | rep (i, 0, 41) { 46 | if (result.freq[i] > 0) count++; 47 | } 48 | 49 | result.cnt = count; 50 | 51 | return result; 52 | } 53 | 54 | void build(vector &a) { 55 | memset(ZERO.freq, 0, sizeof ZERO.freq); 56 | ZERO.cnt = 0; 57 | 58 | size = 1; 59 | while (size < a.size()) size *= 2; 60 | tree.assign(2 * size, ZERO); 61 | build(a, 0, 0, size); 62 | } 63 | 64 | void build(vector &a, int x, int lx, int rx) { 65 | if (rx == lx + 1) { 66 | if (lx < a.size()) { 67 | memset(tree[x].freq, 0, sizeof tree[x].freq); 68 | tree[x].freq[a[lx]]++; 69 | tree[x].cnt = 1; 70 | } 71 | } else { 72 | int m = (lx + rx) / 2; 73 | build(a, 2*x+1, lx, m); 74 | build(a, 2*x+2, m, rx); 75 | tree[x] = combine(tree[2*x+1], tree[2*x+2]); 76 | } 77 | } 78 | 79 | void set(int idx, int v) { 80 | set(idx, v, 0, 0, size); 81 | } 82 | 83 | void set(int idx, int v, int x, int lx, int rx) { 84 | if (rx == lx + 1) { 85 | memset(tree[x].freq, 0, sizeof tree[x].freq); 86 | tree[x].freq[v]++; 87 | tree[x].cnt = 1; 88 | } else { 89 | int m = (lx + rx) / 2; 90 | if (idx < m) 91 | set(idx, v, 2*x+1, lx, m); 92 | else 93 | set(idx, v, 2*x+2, m, rx); 94 | tree[x] = combine(tree[2*x+1], tree[2*x+2]); 95 | } 96 | } 97 | 98 | ll calc(int l, int r) { 99 | return (calc(l, r, 0, 0, size)).cnt; 100 | } 101 | 102 | node calc(int l, int r, int x, int lx, int rx) { 103 | if (lx >= r) return ZERO; 104 | if (rx <= l) return ZERO; 105 | if (lx >= l && rx <= r) return tree[x]; 106 | int m = (lx + rx) / 2; 107 | return combine(calc(l, r, 2*x+1, lx, m), calc(l, r, 2*x+2, m, rx)); 108 | } 109 | }; 110 | 111 | int main(void) { 112 | int n, q; 113 | cin >> n >> q; 114 | 115 | vector a(n); 116 | loop(n) cin >> a[i];; 117 | 118 | segtree st; 119 | st.build(a); 120 | 121 | int cmd; 122 | while (q--) { 123 | cin >> cmd; 124 | if (cmd == 1) { 125 | int L, R; 126 | cin >> L >> R, --L; 127 | cout << st.calc(L, R) << endl; 128 | } else { 129 | int i, v; 130 | cin >> i >> v, --i; 131 | st.set(i, v); 132 | } 133 | } 134 | 135 | return 0; 136 | } 137 | -------------------------------------------------------------------------------- /segment-tree-part1/step4/E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | #define ll long long 19 | #define pb push_back 20 | #define loop(a) for(int i = 0; i < a; i++) 21 | #define loopv(i,a) for (int i = 0; i < a; i++) 22 | #define rep(i,a,b) for (int i = a; i < b; i++) 23 | #define all(x) (x).begin(), (x).end() 24 | #define prDouble(x) cout << fixed << setprecision(10) << x 25 | #define goog(tno) cout << "Case #" << tno <<": " 26 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 27 | 28 | const int INF = 1e9+7; 29 | 30 | struct segtree { 31 | int size; 32 | vector tree; 33 | 34 | void build(int n) { 35 | size = 1; 36 | while (size < n) size *= 2; 37 | tree.assign(2*size, INF); 38 | } 39 | 40 | void set(int idx, int v) { 41 | set(idx, v, 0, 0, size); 42 | } 43 | 44 | void set(int idx, int v, int x, int lx, int rx) { 45 | if (rx == lx + 1) { 46 | tree[x] = v; 47 | } else { 48 | int m = (lx + rx) / 2; 49 | if (idx < m) 50 | set(idx, v, 2*x+1, lx, m); 51 | else 52 | set(idx, v, 2*x+2, m, rx); 53 | tree[x] = min(tree[2*x+1], tree[2*x+2]); 54 | } 55 | } 56 | 57 | int calc(int l, int r, int p) { 58 | return calc(l, r, p, 0, 0, size); 59 | } 60 | 61 | int calc(int l, int r, int p, int x, int lx, int rx) { 62 | if (rx <= l) return 0; 63 | if (lx >= r) return 0; 64 | if (tree[x] > p) return 0; 65 | 66 | if (rx == lx + 1) { 67 | tree[x] = INF; 68 | return 1; 69 | } else { 70 | int m = (lx + rx) / 2; 71 | int s1 = calc(l, r, p, 2*x+1, lx, m); 72 | int s2 = calc(l, r, p, 2*x+2, m, rx); 73 | tree[x] = min(tree[2*x+1], tree[2*x+2]); 74 | return s1 + s2; 75 | } 76 | } 77 | }; 78 | 79 | int main(void) { 80 | int n, m; 81 | cin >> n >> m; 82 | 83 | segtree st; 84 | st.build(n); 85 | 86 | int cmd; 87 | while (m--) { 88 | cin >> cmd; 89 | if (cmd == 1) { 90 | int i, v; 91 | cin >> i >> v; 92 | st.set(i, v); 93 | } else { 94 | int l, r, p; 95 | cin >> l >> r >> p; 96 | cout << st.calc(l, r, p) << endl; 97 | } 98 | } 99 | 100 | return 0; 101 | } 102 | -------------------------------------------------------------------------------- /segment-tree-part2/step1/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | #define ll long long 19 | #define pb push_back 20 | #define loop(a) for(int i = 0; i < a; i++) 21 | #define loopv(i,a) for (int i = 0; i < a; i++) 22 | #define rep(i,a,b) for (int i = a; i < b; i++) 23 | #define all(x) (x).begin(), (x).end() 24 | #define prDouble(x) cout << fixed << setprecision(10) << x 25 | #define goog(tno) cout << "Case #" << tno <<": " 26 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 27 | 28 | struct segtree { 29 | int size; 30 | vector tree; 31 | 32 | void build(int n) { 33 | size = 1; 34 | while (size < n) size *= 2; 35 | tree.assign(2*size, 0); 36 | } 37 | 38 | void add(int l, int r, int v) { 39 | add(l, r, v, 0, 0, size); 40 | } 41 | 42 | void add(int l, int r, int v, int x, int lx, int rx) { 43 | if (lx >= r) return; 44 | if (rx <= l) return; 45 | if (lx >= l && rx <= r) { 46 | tree[x] += v; 47 | return; 48 | } 49 | 50 | int m = (lx + rx) / 2; 51 | add(l, r, v, 2*x+1, lx, m); 52 | add(l, r, v, 2*x+2, m, rx); 53 | } 54 | 55 | ll get(int idx) { 56 | return get(idx, 0, 0, size); 57 | } 58 | 59 | ll get(int idx, int x, int lx, int rx) { 60 | if (rx == lx + 1) { 61 | return tree[x]; 62 | } 63 | 64 | int m = (lx + rx) / 2; 65 | if (idx < m) 66 | return get(idx, 2*x+1, lx, m) + tree[x]; 67 | else 68 | return get(idx, 2*x+2, m, rx) + tree[x]; 69 | } 70 | }; 71 | 72 | int main(void) { 73 | int n, m; 74 | cin >> n >> m; 75 | 76 | segtree st; 77 | st.build(n); 78 | 79 | int cmd; 80 | while (m--) { 81 | cin >> cmd; 82 | if (cmd == 1) { 83 | int l, r, v; 84 | cin >> l >> r >> v; 85 | st.add(l, r, v); 86 | } else { 87 | int i; 88 | cin >> i; 89 | cout << st.get(i) << endl; 90 | } 91 | } 92 | 93 | return 0; 94 | } 95 | -------------------------------------------------------------------------------- /segment-tree-part2/step1/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | #define ll long long 19 | #define pb push_back 20 | #define loop(a) for(int i = 0; i < a; i++) 21 | #define loopv(i,a) for (int i = 0; i < a; i++) 22 | #define rep(i,a,b) for (int i = a; i < b; i++) 23 | #define all(x) (x).begin(), (x).end() 24 | #define prDouble(x) cout << fixed << setprecision(10) << x 25 | #define goog(tno) cout << "Case #" << tno <<": " 26 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 27 | 28 | struct segtree { 29 | int size; 30 | vector tree; 31 | 32 | void build(int n) { 33 | size = 1; 34 | while (size < n) size *= 2; 35 | tree.assign(2*size, 0); 36 | } 37 | 38 | void modify(int l, int r, int v) { 39 | modify(l, r, v, 0, 0, size); 40 | } 41 | 42 | void modify(int l, int r, ll v, int x, int lx, int rx) { 43 | if (lx >= r) return; 44 | if (rx <= l) return; 45 | if (lx >= l && rx <= r) { 46 | tree[x] = ::max(tree[x], v); 47 | return; 48 | } 49 | 50 | int m = (lx + rx) / 2; 51 | modify(l, r, v, 2*x+1, lx, m); 52 | modify(l, r, v, 2*x+2, m, rx); 53 | } 54 | 55 | ll get(int idx) { 56 | return get(idx, 0, 0, size); 57 | } 58 | 59 | ll get(int idx, int x, int lx, int rx) { 60 | if (rx == lx + 1) { 61 | return tree[x]; 62 | } 63 | 64 | int m = (lx + rx) / 2; 65 | if (idx < m) 66 | return ::max(get(idx, 2*x+1, lx, m), tree[x]); 67 | else 68 | return ::max(get(idx, 2*x+2, m, rx), tree[x]); 69 | } 70 | }; 71 | 72 | int main(void) { 73 | int n, m; 74 | cin >> n >> m; 75 | 76 | segtree st; 77 | st.build(n); 78 | 79 | int cmd; 80 | while (m--) { 81 | cin >> cmd; 82 | if (cmd == 1) { 83 | int l, r, v; 84 | cin >> l >> r >> v; 85 | st.modify(l, r, v); 86 | } else { 87 | int i; 88 | cin >> i; 89 | cout << st.get(i) << endl; 90 | } 91 | } 92 | 93 | return 0; 94 | } 95 | -------------------------------------------------------------------------------- /segment-tree-part2/step1/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | #define ll long long 20 | #define pb push_back 21 | #define loop(a) for(int i = 0; i < a; i++) 22 | #define loopv(i,a) for (int i = 0; i < a; i++) 23 | #define rep(i,a,b) for (int i = a; i < b; i++) 24 | #define all(x) (x).begin(), (x).end() 25 | #define prDouble(x) cout << fixed << setprecision(10) << x 26 | #define goog(tno) cout << "Case #" << tno <<": " 27 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 28 | 29 | struct segtree { 30 | int size; 31 | vector tree; 32 | 33 | const ll NO_OP = LLONG_MIN; 34 | 35 | void build(int n) { 36 | size = 1; 37 | while (size < n) size *= 2; 38 | tree.assign(2*size, 0); 39 | } 40 | 41 | void propagate(int x, int lx, int rx) { 42 | if (tree[x] == NO_OP) return; 43 | if (rx == lx + 1) return; 44 | tree[2*x+1] = tree[x]; 45 | tree[2*x+2] = tree[x]; 46 | tree[x] = NO_OP; 47 | } 48 | 49 | void modify(int l, int r, int v) { 50 | modify(l, r, v, 0, 0, size); 51 | } 52 | 53 | void modify(int l, int r, ll v, int x, int lx, int rx) { 54 | propagate(x, lx, rx); 55 | if (lx >= r) return; 56 | if (rx <= l) return; 57 | if (lx >= l && rx <= r) { 58 | tree[x] = v; 59 | return; 60 | } 61 | 62 | int m = (lx + rx) / 2; 63 | modify(l, r, v, 2*x+1, lx, m); 64 | modify(l, r, v, 2*x+2, m, rx); 65 | } 66 | 67 | ll get(int idx) { 68 | return get(idx, 0, 0, size); 69 | } 70 | 71 | ll get(int idx, int x, int lx, int rx) { 72 | propagate(x, lx, rx); 73 | if (rx == lx + 1) { 74 | return tree[x]; 75 | } 76 | 77 | int m = (lx + rx) / 2; 78 | if (idx < m) 79 | return get(idx, 2*x+1, lx, m); 80 | else 81 | return get(idx, 2*x+2, m, rx); 82 | } 83 | }; 84 | 85 | int main(void) { 86 | int n, m; 87 | cin >> n >> m; 88 | 89 | segtree st; 90 | st.build(n); 91 | 92 | int cmd; 93 | while (m--) { 94 | cin >> cmd; 95 | if (cmd == 1) { 96 | int l, r, v; 97 | cin >> l >> r >> v; 98 | st.modify(l, r, v); 99 | } else { 100 | int i; 101 | cin >> i; 102 | cout << st.get(i) << endl; 103 | } 104 | } 105 | 106 | return 0; 107 | } 108 | -------------------------------------------------------------------------------- /segment-tree-part2/step2/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | #define ll long long 20 | #define pb push_back 21 | #define loop(a) for(int i = 0; i < a; i++) 22 | #define loopv(i,a) for (int i = 0; i < a; i++) 23 | #define rep(i,a,b) for (int i = a; i < b; i++) 24 | #define all(x) (x).begin(), (x).end() 25 | #define prDouble(x) cout << fixed << setprecision(10) << x 26 | #define goog(tno) cout << "Case #" << tno <<": " 27 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 28 | 29 | struct segtree { 30 | const ll NO_OP = 0; 31 | const ll EMPTY = LLONG_MAX; 32 | 33 | struct node { 34 | ll modify; 35 | ll value; 36 | }; 37 | 38 | int size; 39 | vector tree; 40 | 41 | ll _modify(ll a, ll b, ll len) { 42 | if (b == NO_OP) return a; 43 | return a + b; 44 | } 45 | 46 | ll _get(ll a, ll b) { 47 | return min(a, b); 48 | } 49 | 50 | void build(int n) { 51 | size = 1; 52 | while (size < n) size *= 2; 53 | tree.assign(2*size, {0, 0}); 54 | } 55 | 56 | void propagate(int x, int lx, int rx) { 57 | if (tree[x].modify == NO_OP || rx == lx + 1) return; 58 | int m = (lx + rx) / 2; 59 | tree[2*x+1].modify = _modify(tree[2*x+1].modify, tree[x].modify, 1); 60 | tree[2*x+1].value = _modify(tree[2*x+1].value, tree[x].modify, m - lx); 61 | tree[2*x+2].modify = _modify(tree[2*x+2].modify, tree[x].modify, 1); 62 | tree[2*x+2].value = _modify(tree[2*x+2].value, tree[x].modify, rx - m); 63 | tree[x].modify = NO_OP; 64 | } 65 | 66 | void update(int l, int r, int v) { 67 | update(l, r, v, 0, 0, size); 68 | } 69 | 70 | void update(int l, int r, int v, int x, int lx, int rx) { 71 | propagate(x, lx, rx); 72 | if (lx >= r) return; 73 | if (rx <= l) return; 74 | if (lx >= l && rx <= r) { 75 | tree[x].modify = _modify(tree[x].modify, v, 1); 76 | tree[x].value = _modify(tree[x].value, v, rx - lx); 77 | } else { 78 | int m = (lx + rx) / 2; 79 | update(l, r, v, 2*x+1, lx, m); 80 | update(l, r, v, 2*x+2, m, rx); 81 | tree[x].value = _get(tree[2*x+1].value, tree[2*x+2].value); 82 | } 83 | } 84 | 85 | ll get(int l, int r) { 86 | return get(l, r, 0, 0, size); 87 | } 88 | 89 | ll get(int l, int r, int x, int lx, int rx) { 90 | propagate(x, lx, rx); 91 | if (lx >= r || rx <= l) return EMPTY; 92 | if (lx >= l && rx <= r) return tree[x].value; 93 | int m = (lx + rx) / 2; 94 | ll v1 = get(l, r, 2*x+1, lx, m); 95 | ll v2 = get(l, r, 2*x+2, m, rx); 96 | return _get(v1, v2); 97 | } 98 | }; 99 | 100 | int main(void) { 101 | int n, m; 102 | cin >> n >> m; 103 | 104 | segtree st; 105 | st.build(n); 106 | 107 | int cmd, l, r, v; 108 | while (m--) { 109 | cin >> cmd; 110 | if (cmd == 1) { 111 | cin >> l >> r >> v; 112 | st.update(l, r, v); 113 | } else { 114 | cin >> l >> r; 115 | cout << st.get(l, r) << endl; 116 | } 117 | } 118 | 119 | return 0; 120 | } 121 | -------------------------------------------------------------------------------- /segment-tree-part2/step2/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | #define ll long long 20 | #define pb push_back 21 | #define loop(a) for(int i = 0; i < a; i++) 22 | #define loopv(i,a) for (int i = 0; i < a; i++) 23 | #define rep(i,a,b) for (int i = a; i < b; i++) 24 | #define all(x) (x).begin(), (x).end() 25 | #define prDouble(x) cout << fixed << setprecision(10) << x 26 | #define goog(tno) cout << "Case #" << tno <<": " 27 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 28 | 29 | struct segtree { 30 | struct node { 31 | ll modify; 32 | ll value; 33 | }; 34 | 35 | int size; 36 | vector tree; 37 | 38 | const ll NO_OP = LLONG_MIN; 39 | const ll EMPTY = (1LL<<31) - 1; 40 | 41 | ll _modify(ll a, ll b) { 42 | if (a == NO_OP) return b; 43 | return a | b; 44 | } 45 | 46 | ll _get(ll a, ll b) { 47 | return a & b; 48 | } 49 | 50 | void build(int n) { 51 | size = 1; 52 | while (size < n) size *= 2; 53 | tree.assign(2*size, { NO_OP, 0 }); 54 | } 55 | 56 | void propagate(int x, int lx, int rx) { 57 | if (tree[x].modify == NO_OP || rx == lx + 1) return; 58 | tree[2*x+1].modify = _modify(tree[2*x+1].modify, tree[x].modify); 59 | tree[2*x+1].value = _modify(tree[2*x+1].value, tree[x].modify); 60 | tree[2*x+2].modify = _modify(tree[2*x+2].modify, tree[x].modify); 61 | tree[2*x+2].value = _modify(tree[2*x+2].value, tree[x].modify); 62 | tree[x].modify = NO_OP; 63 | } 64 | 65 | void update(int l, int r, int v) { 66 | update(l, r, v, 0, 0, size); 67 | } 68 | 69 | void update(int l, int r, int v, int x, int lx, int rx) { 70 | propagate(x, lx, rx); 71 | if (lx >= r) return; 72 | if (rx <= l) return; 73 | if (lx >= l && rx <= r) { 74 | tree[x].modify = _modify(tree[x].modify, v); 75 | tree[x].value = _modify(tree[x].value, v); 76 | } else { 77 | int m = (lx + rx) / 2; 78 | update(l, r, v, 2*x+1, lx, m); 79 | update(l, r, v, 2*x+2, m, rx); 80 | tree[x].value = _get(tree[2*x+1].value, tree[2*x+2].value); 81 | } 82 | } 83 | 84 | ll get(int l, int r) { 85 | return get(l, r, 0, 0, size); 86 | } 87 | 88 | ll get(int l, int r, int x, int lx, int rx) { 89 | propagate(x, lx, rx); 90 | if (lx >= r) return EMPTY; 91 | if (rx <= l) return EMPTY; 92 | if (lx >= l && rx <= r) { 93 | return tree[x].value; 94 | } else { 95 | int m = (lx + rx) / 2; 96 | ll v1 = get(l, r, 2*x+1, lx, m); 97 | ll v2 = get(l, r, 2*x+2, m, rx); 98 | return _get(v1, v2); 99 | } 100 | } 101 | }; 102 | 103 | int main(void) { 104 | int n, m; 105 | cin >> n >> m; 106 | 107 | segtree st; 108 | st.build(n); 109 | 110 | int cmd, l, r, v; 111 | while (m--) { 112 | cin >> cmd; 113 | if (cmd == 1) { 114 | cin >> l >> r >> v; 115 | st.update(l, r, v); 116 | } else { 117 | cin >> l >> r; 118 | cout << st.get(l, r) << endl; 119 | } 120 | } 121 | 122 | return 0; 123 | } 124 | -------------------------------------------------------------------------------- /segment-tree-part2/step2/D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | #define ll long long 20 | #define pb push_back 21 | #define loop(a) for(int i = 0; i < a; i++) 22 | #define loopv(i,a) for (int i = 0; i < a; i++) 23 | #define rep(i,a,b) for (int i = a; i < b; i++) 24 | #define all(x) (x).begin(), (x).end() 25 | #define prDouble(x) cout << fixed << setprecision(10) << x 26 | #define goog(tno) cout << "Case #" << tno <<": " 27 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 28 | 29 | struct segtree { 30 | struct node { 31 | ll modify; 32 | ll value; 33 | }; 34 | 35 | const ll NO_OP = 0; 36 | const ll EMPTY = 0; 37 | 38 | int size; 39 | vector tree; 40 | 41 | ll _modify(ll a, ll b, ll len) { 42 | if (a == NO_OP) return b * len; 43 | return a + b * len; 44 | } 45 | 46 | ll _get(ll a, ll b) { 47 | return a + b; 48 | } 49 | 50 | void build(int n) { 51 | size = 1; 52 | while (size < n) size *= 2; 53 | tree.assign(2*size, {0, 0}); 54 | } 55 | 56 | void propagate(int x, int lx, int rx) { 57 | if (tree[x].modify == NO_OP || rx == lx + 1) return; 58 | int m = (lx + rx) / 2; 59 | tree[2*x+1].modify = _modify(tree[2*x+1].modify, tree[x].modify, 1); 60 | tree[2*x+1].value = _modify(tree[2*x+1].value, tree[x].modify, m - lx); 61 | tree[2*x+2].modify = _modify(tree[2*x+2].modify, tree[x].modify, 1); 62 | tree[2*x+2].value = _modify(tree[2*x+2].value, tree[x].modify, rx - m); 63 | tree[x].modify = NO_OP; 64 | } 65 | 66 | void update(int l, int r, int v) { 67 | update(l, r, v, 0, 0, size); 68 | } 69 | 70 | void update(int l, int r, int v, int x, int lx, int rx) { 71 | propagate(x, lx, rx); 72 | if (lx >= r) return; 73 | if (rx <= l) return; 74 | if (lx >= l && rx <= r) { 75 | tree[x].modify = _modify(tree[x].modify, v, 1); 76 | tree[x].value = _modify(tree[x].value, v, rx - lx); 77 | } else { 78 | int m = (lx + rx) / 2; 79 | update(l, r, v, 2*x+1, lx, m); 80 | update(l, r, v, 2*x+2, m, rx); 81 | tree[x].value = _get(tree[2*x+1].value, tree[2*x+2].value); 82 | } 83 | } 84 | 85 | ll get(int l, int r) { 86 | return get(l, r, 0, 0, size); 87 | } 88 | 89 | ll get(int l, int r, int x, int lx, int rx) { 90 | propagate(x, lx, rx); 91 | if (lx >= r) return EMPTY; 92 | if (rx <= l) return EMPTY; 93 | if (lx >= l && rx <= r) { 94 | return tree[x].value; 95 | } else { 96 | int m = (lx + rx) / 2; 97 | ll v1 = get(l, r, 2*x+1, lx, m); 98 | ll v2 = get(l, r, 2*x+2, m, rx); 99 | return _get(v1, v2); 100 | } 101 | } 102 | }; 103 | 104 | int main(void) { 105 | int n, m; 106 | cin >> n >> m; 107 | 108 | segtree st; 109 | st.build(n); 110 | 111 | int cmd, l, r, v; 112 | while (m--) { 113 | cin >> cmd; 114 | if (cmd == 1) { 115 | cin >> l >> r >> v; 116 | st.update(l, r, v); 117 | } else { 118 | cin >> l >> r; 119 | cout << st.get(l, r) << endl; 120 | } 121 | } 122 | 123 | return 0; 124 | } 125 | -------------------------------------------------------------------------------- /segment-tree-part2/step2/E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | #define ll long long 20 | #define pb push_back 21 | #define loop(a) for(int i = 0; i < a; i++) 22 | #define loopv(i,a) for (int i = 0; i < a; i++) 23 | #define rep(i,a,b) for (int i = a; i < b; i++) 24 | #define all(x) (x).begin(), (x).end() 25 | #define prDouble(x) cout << fixed << setprecision(10) << x 26 | #define goog(tno) cout << "Case #" << tno <<": " 27 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 28 | 29 | struct segtree { 30 | struct node { 31 | ll modify; 32 | ll value; 33 | }; 34 | 35 | const ll NO_OP = LLONG_MIN; 36 | const ll EMPTY = LLONG_MAX; 37 | 38 | int size; 39 | vector tree; 40 | 41 | ll _modify(ll a, ll b, ll len) { 42 | return b; 43 | } 44 | 45 | ll _get(ll a, ll b) { 46 | return min(a, b); 47 | } 48 | 49 | void build(int n) { 50 | size = 1; 51 | while (size < n) size *= 2; 52 | tree.assign(2*size, {0, 0}); 53 | } 54 | 55 | void propagate(int x, int lx, int rx) { 56 | if (tree[x].modify == NO_OP || rx == lx + 1) return; 57 | int m = (lx + rx) / 2; 58 | tree[2*x+1].modify = _modify(tree[2*x+1].modify, tree[x].modify, 1); 59 | tree[2*x+1].value = _modify(tree[2*x+1].value, tree[x].modify, m - lx); 60 | tree[2*x+2].modify = _modify(tree[2*x+2].modify, tree[x].modify, 1); 61 | tree[2*x+2].value = _modify(tree[2*x+2].value, tree[x].modify, rx - m); 62 | tree[x].modify = NO_OP; 63 | } 64 | 65 | void update(int l, int r, int v) { 66 | update(l, r, v, 0, 0, size); 67 | } 68 | 69 | void update(int l, int r, int v, int x, int lx, int rx) { 70 | propagate(x, lx, rx); 71 | if (lx >= r) return; 72 | if (rx <= l) return; 73 | if (lx >= l && rx <= r) { 74 | tree[x].modify = _modify(tree[x].modify, v, 1); 75 | tree[x].value = _modify(tree[x].value, v, rx - lx); 76 | } else { 77 | int m = (lx + rx) / 2; 78 | update(l, r, v, 2*x+1, lx, m); 79 | update(l, r, v, 2*x+2, m, rx); 80 | tree[x].value = _get(tree[2*x+1].value, tree[2*x+2].value); 81 | } 82 | } 83 | 84 | ll get(int l, int r) { 85 | return get(l, r, 0, 0, size); 86 | } 87 | 88 | ll get(int l, int r, int x, int lx, int rx) { 89 | propagate(x, lx, rx); 90 | if (lx >= r) return EMPTY; 91 | if (rx <= l) return EMPTY; 92 | if (lx >= l && rx <= r) { 93 | return tree[x].value; 94 | } else { 95 | int m = (lx + rx) / 2; 96 | ll v1 = get(l, r, 2*x+1, lx, m); 97 | ll v2 = get(l, r, 2*x+2, m, rx); 98 | return _get(v1, v2); 99 | } 100 | } 101 | }; 102 | 103 | int main(void) { 104 | int n, m; 105 | cin >> n >> m; 106 | 107 | segtree st; 108 | st.build(n); 109 | 110 | int cmd, l, r, v; 111 | while (m--) { 112 | cin >> cmd; 113 | if (cmd == 1) { 114 | cin >> l >> r >> v; 115 | st.update(l, r, v); 116 | } else { 117 | cin >> l >> r; 118 | cout << st.get(l, r) << endl; 119 | } 120 | } 121 | 122 | return 0; 123 | } 124 | -------------------------------------------------------------------------------- /segment-tree-part2/step2/F.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | #define ll long long 20 | #define pb push_back 21 | #define loop(a) for(int i = 0; i < a; i++) 22 | #define loopv(i,a) for (int i = 0; i < a; i++) 23 | #define rep(i,a,b) for (int i = a; i < b; i++) 24 | #define all(x) (x).begin(), (x).end() 25 | #define prDouble(x) cout << fixed << setprecision(10) << x 26 | #define goog(tno) cout << "Case #" << tno <<": " 27 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 28 | 29 | struct segtree { 30 | struct node { 31 | ll modify; 32 | ll value; 33 | }; 34 | 35 | const ll NO_OP = LLONG_MIN; 36 | const ll EMPTY = 0; 37 | 38 | int size; 39 | vector tree; 40 | 41 | ll _modify(ll a, ll b, ll len) { 42 | return b * len; 43 | } 44 | 45 | ll _get(ll a, ll b) { 46 | return a + b; 47 | } 48 | 49 | void build(int n) { 50 | size = 1; 51 | while (size < n) size *= 2; 52 | tree.assign(2*size, {0, 0}); 53 | } 54 | 55 | void propagate(int x, int lx, int rx) { 56 | if (tree[x].modify == NO_OP || rx == lx + 1) return; 57 | int m = (lx + rx) / 2; 58 | tree[2*x+1].modify = _modify(tree[2*x+1].modify, tree[x].modify, 1); 59 | tree[2*x+1].value = _modify(tree[2*x+1].value, tree[x].modify, m - lx); 60 | tree[2*x+2].modify = _modify(tree[2*x+2].modify, tree[x].modify, 1); 61 | tree[2*x+2].value = _modify(tree[2*x+2].value, tree[x].modify, rx - m); 62 | tree[x].modify = NO_OP; 63 | } 64 | 65 | void update(int l, int r, int v) { 66 | update(l, r, v, 0, 0, size); 67 | } 68 | 69 | void update(int l, int r, int v, int x, int lx, int rx) { 70 | propagate(x, lx, rx); 71 | if (lx >= r) return; 72 | if (rx <= l) return; 73 | if (lx >= l && rx <= r) { 74 | tree[x].modify = _modify(tree[x].modify, v, 1); 75 | tree[x].value = _modify(tree[x].value, v, rx - lx); 76 | } else { 77 | int m = (lx + rx) / 2; 78 | update(l, r, v, 2*x+1, lx, m); 79 | update(l, r, v, 2*x+2, m, rx); 80 | tree[x].value = _get(tree[2*x+1].value, tree[2*x+2].value); 81 | } 82 | } 83 | 84 | ll get(int l, int r) { 85 | return get(l, r, 0, 0, size); 86 | } 87 | 88 | ll get(int l, int r, int x, int lx, int rx) { 89 | propagate(x, lx, rx); 90 | if (lx >= r) return EMPTY; 91 | if (rx <= l) return EMPTY; 92 | if (lx >= l && rx <= r) { 93 | return tree[x].value; 94 | } else { 95 | int m = (lx + rx) / 2; 96 | ll v1 = get(l, r, 2*x+1, lx, m); 97 | ll v2 = get(l, r, 2*x+2, m, rx); 98 | return _get(v1, v2); 99 | } 100 | } 101 | }; 102 | 103 | int main(void) { 104 | int n, m; 105 | cin >> n >> m; 106 | 107 | segtree st; 108 | st.build(n); 109 | 110 | int cmd, l, r, v; 111 | while (m--) { 112 | cin >> cmd; 113 | if (cmd == 1) { 114 | cin >> l >> r >> v; 115 | st.update(l, r, v); 116 | } else { 117 | cin >> l >> r; 118 | cout << st.get(l, r) << endl; 119 | } 120 | } 121 | 122 | return 0; 123 | } 124 | -------------------------------------------------------------------------------- /segment-tree-part2/step3/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | #define ll long long 20 | #define pb push_back 21 | #define loop(a) for(int i = 0; i < a; i++) 22 | #define loopv(i,a) for (int i = 0; i < a; i++) 23 | #define rep(i,a,b) for (int i = a; i < b; i++) 24 | #define all(x) (x).begin(), (x).end() 25 | #define prDouble(x) cout << fixed << setprecision(10) << x 26 | #define goog(tno) cout << "Case #" << tno <<": " 27 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 28 | 29 | struct segtree { 30 | struct info { 31 | ll seg, pref, suf, sum; 32 | }; 33 | struct node { 34 | info value; 35 | ll modify; 36 | }; 37 | 38 | const ll NO_OP = LLONG_MIN; 39 | 40 | int size; 41 | vector tree; 42 | 43 | void build(int n) { 44 | size = 1; 45 | while (size < n) size *= 2; 46 | tree.assign(2 * size, {{0, 0, 0, 0}, NO_OP}); 47 | } 48 | 49 | info combine(info a, info b) { 50 | return { 51 | max(a.suf + b.pref, max(a.seg, b.seg)), 52 | max(a.pref, a.sum + b.pref), 53 | max(b.suf, a.suf + b.sum), 54 | a.sum + b.sum 55 | }; 56 | } 57 | 58 | void propagate(int x, int lx, int rx) { 59 | if (tree[x].modify == NO_OP || rx == lx + 1) return; 60 | int m = (lx + rx) / 2; 61 | tree[2*x+1].modify = tree[x].modify; 62 | if (tree[x].modify < 0) { 63 | tree[2*x+1].value.seg = tree[2*x+1].value.pref = tree[2*x+1].value.suf = 0; 64 | tree[2*x+1].value.sum = (m - lx) * tree[x].modify; 65 | } else { 66 | tree[2*x+1].value.seg = tree[2*x+1].value.pref = tree[2*x+1].value.suf = tree[2*x+1].value.sum = (m - lx) * tree[x].modify; 67 | } 68 | tree[2*x+2].modify = tree[x].modify; 69 | if (tree[x].modify < 0) { 70 | tree[2*x+2].value.seg = tree[2*x+2].value.pref = tree[2*x+2].value.suf = 0; 71 | tree[2*x+2].value.sum = (rx - m) * tree[x].modify; 72 | } else { 73 | tree[2*x+2].value.seg = tree[2*x+2].value.pref = tree[2*x+2].value.suf = tree[2*x+2].value.sum = (rx - m) * tree[x].modify; 74 | } 75 | tree[x].modify = NO_OP; 76 | } 77 | 78 | void update(int l, int r, ll v) { 79 | update(l, r, v, 0, 0, size); 80 | } 81 | 82 | void update(int l, int r, ll v, int x, int lx, int rx) { 83 | propagate(x, lx, rx); 84 | if (lx >= r) return; 85 | if (rx <= l) return; 86 | if (lx >= l && rx <= r) { 87 | tree[x].modify = v; 88 | if (v < 0) { 89 | tree[x].value.seg = tree[x].value.pref = tree[x].value.suf = 0; 90 | tree[x].value.sum = (rx - lx) * v; 91 | } else { 92 | tree[x].value.seg = tree[x].value.pref = tree[x].value.suf = tree[x].value.sum = (rx - lx) * v; 93 | } 94 | } else { 95 | int m = (lx + rx) / 2; 96 | update(l, r, v, 2*x+1, lx, m); 97 | update(l, r, v, 2*x+2, m, rx); 98 | tree[x].value = combine(tree[2*x+1].value, tree[2*x+2].value); 99 | } 100 | } 101 | 102 | ll get() { 103 | propagate(0, 0, size); 104 | return tree[0].value.seg; 105 | } 106 | }; 107 | 108 | int main(void) { 109 | int n, m; 110 | cin >> n >> m; 111 | 112 | segtree st; 113 | st.build(n); 114 | 115 | int l, r, v; 116 | while (m--) { 117 | cin >> l >> r >> v; 118 | st.update(l, r, v); 119 | cout << st.get() << endl; 120 | } 121 | 122 | return 0; 123 | } 124 | -------------------------------------------------------------------------------- /segment-tree-part2/step3/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | #define ll long long 20 | #define pb push_back 21 | #define loop(a) for(int i = 0; i < a; i++) 22 | #define loopv(i,a) for (int i = 0; i < a; i++) 23 | #define rep(i,a,b) for (int i = a; i < b; i++) 24 | #define all(x) (x).begin(), (x).end() 25 | #define prDouble(x) cout << fixed << setprecision(10) << x 26 | #define goog(tno) cout << "Case #" << tno <<": " 27 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 28 | 29 | struct segtree { 30 | struct node { 31 | int sum; 32 | bool inverse; 33 | }; 34 | 35 | int size; 36 | vector tree; 37 | 38 | void build(int n) { 39 | size = 1; 40 | while (size < n) size *= 2; 41 | tree.assign(2*size, {0, false}); 42 | } 43 | 44 | void propagate(int x, int lx, int rx) { 45 | if (tree[x].inverse == false || rx == lx + 1) return; 46 | int m = (lx + rx) / 2; 47 | tree[2*x+1].inverse = !tree[2*x+1].inverse; 48 | tree[2*x+1].sum = (m - lx) - tree[2*x+1].sum; 49 | tree[2*x+2].inverse = !tree[2*x+2].inverse; 50 | tree[2*x+2].sum = (rx - m) - tree[2*x+2].sum; 51 | tree[x].inverse = false; 52 | } 53 | 54 | void update(int l, int r) { 55 | update(l, r, 0, 0, size); 56 | } 57 | 58 | void update(int l, int r, int x, int lx, int rx) { 59 | propagate(x, lx, rx); 60 | if (lx >= r) return; 61 | if (rx <= l) return; 62 | if (lx >= l && rx <= r) { 63 | tree[x].inverse = true; 64 | tree[x].sum = (rx - lx) - tree[x].sum; 65 | } else { 66 | int m = (lx + rx) / 2; 67 | update(l, r, 2*x+1, lx, m); 68 | update(l, r, 2*x+2, m, rx); 69 | tree[x].sum = tree[2*x+1].sum + tree[2*x+2].sum; 70 | } 71 | } 72 | 73 | int get(int k) { 74 | return get(k, 0, 0, size); 75 | } 76 | 77 | int get(int k, int x, int lx, int rx) { 78 | propagate(x, lx, rx); 79 | if (rx == lx + 1) { 80 | return lx; 81 | } 82 | int m = (lx + rx) / 2; 83 | if (tree[2*x+1].sum <= k) { 84 | return get(k - tree[2*x+1].sum, 2*x+2, m, rx); 85 | } 86 | return get(k, 2*x+1, lx, m); 87 | } 88 | }; 89 | 90 | int main(void) { 91 | int n, m; 92 | cin >> n >> m; 93 | 94 | segtree st; 95 | st.build(n); 96 | 97 | int cmd; 98 | while (m--) { 99 | cin >> cmd; 100 | if (cmd == 1) { 101 | int l, r; 102 | cin >> l >> r; 103 | st.update(l, r); 104 | } else { 105 | int k; 106 | cin >> k; 107 | cout << st.get(k) << endl; 108 | } 109 | } 110 | 111 | return 0; 112 | } 113 | -------------------------------------------------------------------------------- /segment-tree-part2/step3/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | #define ll long long 20 | #define pb push_back 21 | #define loop(a) for(int i = 0; i < a; i++) 22 | #define loopv(i,a) for (int i = 0; i < a; i++) 23 | #define rep(i,a,b) for (int i = a; i < b; i++) 24 | #define all(x) (x).begin(), (x).end() 25 | #define prDouble(x) cout << fixed << setprecision(10) << x 26 | #define goog(tno) cout << "Case #" << tno <<": " 27 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 28 | 29 | struct segtree { 30 | struct node { 31 | int max; 32 | int modify; 33 | }; 34 | 35 | const int NO_OP = INT_MAX; 36 | 37 | int size; 38 | vector tree; 39 | 40 | void build(int n) { 41 | size = 1; 42 | while (size < n) size *= 2; 43 | tree.assign(2 * size, {0, NO_OP}); 44 | } 45 | 46 | int _modify(int a, int b) { 47 | if (a == NO_OP) return b; 48 | return a + b; 49 | } 50 | 51 | void propagate(int x, int lx, int rx) { 52 | if (tree[x].modify == NO_OP || rx == lx + 1) return; 53 | tree[2*x+1].modify = _modify(tree[2*x+1].modify, tree[x].modify); 54 | tree[2*x+1].max = tree[2*x+1].max + tree[x].modify; 55 | tree[2*x+2].modify = _modify(tree[2*x+2].modify, tree[x].modify); 56 | tree[2*x+2].max = tree[2*x+2].max + tree[x].modify; 57 | tree[x].modify = NO_OP; 58 | } 59 | 60 | void update(int l, int r, int v) { 61 | update(l, r, v, 0, 0, size); 62 | } 63 | 64 | void update(int l, int r, int v, int x, int lx, int rx) { 65 | propagate(x, lx, rx); 66 | if (lx >= r) return; 67 | if (rx <= l) return; 68 | if (lx >= l && rx <= r) { 69 | tree[x].modify = v; 70 | tree[x].max += v; 71 | } else { 72 | int m = (lx + rx) / 2; 73 | update(l, r, v, 2*x+1, lx, m); 74 | update(l, r, v, 2*x+2, m, rx); 75 | tree[x].max = max(tree[2*x+1].max, tree[2*x+2].max); 76 | } 77 | } 78 | 79 | int get(int v, int l) { 80 | return get(v, l, 0, 0, size); 81 | } 82 | 83 | int get(int v, int l, int x, int lx, int rx) { 84 | propagate(x, lx, rx); 85 | 86 | if (rx <= l) return -1; 87 | if (tree[x].max < v) return -1; 88 | if (rx == lx + 1) return lx; 89 | 90 | int m = (lx + rx) / 2; 91 | int res = get(v, l, 2*x+1, lx, m); 92 | if (res == -1) 93 | res = get(v, l, 2*x+2, m, rx); 94 | return res; 95 | } 96 | }; 97 | 98 | int main(void) { 99 | int n, m; 100 | cin >> n >> m; 101 | 102 | segtree st; 103 | st.build(n); 104 | 105 | int cmd; 106 | while (m--) { 107 | cin >> cmd; 108 | if (cmd == 1) { 109 | int l, r, v; 110 | cin >> l >> r >> v; 111 | st.update(l, r, v); 112 | } else { 113 | int x, l; 114 | cin >> x >> l; 115 | cout << st.get(x, l) << endl; 116 | } 117 | } 118 | 119 | return 0; 120 | } 121 | -------------------------------------------------------------------------------- /segment-tree-part2/step4/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | using ll = long long; 6 | 7 | struct segtree { 8 | struct node { 9 | ll a, d; 10 | }; 11 | 12 | int size; 13 | vector tree; 14 | 15 | void build(int n) { 16 | size = 1; 17 | while (size < n) size *= 2; 18 | tree.assign(2 * size, {0, 0}); 19 | } 20 | 21 | void propagate(int x, int lx, int rx) { 22 | if (tree[x].a == 0 && tree[x].d == 0) return; 23 | if (rx - lx == 1) return; 24 | 25 | int m = (lx + rx) / 2; 26 | 27 | tree[2*x+1].a += tree[x].a; 28 | tree[2*x+1].d += tree[x].d; 29 | 30 | tree[2*x+2].a += tree[x].a + (m - lx) * tree[x].d; 31 | tree[2*x+2].d += tree[x].d; 32 | 33 | tree[x].a = tree[x].d = 0; 34 | } 35 | 36 | void modify(int l, int r, ll a, ll d) { 37 | modify(l, r, a, d, 0, 0, size); 38 | } 39 | 40 | void modify(int l, int r, ll a, ll d, int x, int lx, int rx) { 41 | propagate(x, lx, rx); 42 | if (lx >= r || rx <= l) return; 43 | if (lx >= l && rx <= r) { 44 | tree[x].a += a + (lx - l) * d; 45 | tree[x].d += d; 46 | } else { 47 | int m = (lx + rx) / 2; 48 | modify(l, r, a, d, 2 * x + 1, lx, m); 49 | modify(l ,r, a, d, 2 * x + 2, m, rx); 50 | } 51 | } 52 | 53 | ll get(int i) { 54 | return get(i, 0, 0, size); 55 | } 56 | 57 | ll get(int i, int x, int lx, int rx) { 58 | propagate(x, lx, rx); 59 | if (rx - lx == 1) { 60 | return tree[x].a; 61 | } 62 | int m = (lx + rx) / 2; 63 | if (i < m) { 64 | return get(i, 2 * x + 1, lx, m); 65 | } else { 66 | return get(i, 2 * x + 2, m, rx); 67 | } 68 | } 69 | }; 70 | 71 | int main(void) { 72 | int n, m; 73 | cin >> n >> m; 74 | 75 | segtree st; 76 | st.build(n); 77 | 78 | int cmd; 79 | while (m--) { 80 | cin >> cmd; 81 | if (cmd == 1) { 82 | int l, r, a, d; 83 | cin >> l >> r >> a >> d; 84 | l--; 85 | st.modify(l, r, a, d); 86 | } else { 87 | int i; 88 | cin >> i; 89 | i--; 90 | cout << st.get(i) << endl; 91 | } 92 | } 93 | 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /segment-tree-part2/step4/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | int MOD = 500000; 6 | 7 | struct segtree { 8 | struct val { 9 | int count; 10 | int sum; 11 | char left; 12 | char right; 13 | }; 14 | 15 | struct node { 16 | char paint; 17 | val value; 18 | }; 19 | 20 | char NO_OP = 'N'; 21 | 22 | int size; 23 | vector tree; 24 | 25 | void build(int n) { 26 | size = 1; 27 | while (size < n) size *= 2; 28 | tree.assign(2 * size, {NO_OP, {0, 0, 'W', 'W'}}); 29 | } 30 | 31 | val combine(val &a, val &b) { 32 | int new_count = a.count + b.count; 33 | if (a.right == 'B' && b.left == 'B') { 34 | new_count--; 35 | } 36 | 37 | return { 38 | new_count, 39 | a.sum + b.sum, 40 | a.left, 41 | b.right 42 | }; 43 | } 44 | 45 | void propagate(int x, int lx, int rx) { 46 | if (tree[x].paint == NO_OP || rx - lx == 1) return; 47 | 48 | int m = (lx + rx) / 2; 49 | 50 | tree[2*x+1].paint = tree[x].paint; 51 | tree[2*x+2].paint = tree[x].paint; 52 | 53 | if (tree[x].paint == 'W') { 54 | tree[2*x+1].value = {0, 0, 'W', 'W'}; 55 | tree[2*x+2].value = {0, 0, 'W', 'W'}; 56 | } else { 57 | tree[2*x+1].value = {1, m - lx, 'B', 'B'}; 58 | tree[2*x+2].value = {1, rx - m, 'B', 'B'}; 59 | } 60 | 61 | tree[x].paint = NO_OP; 62 | } 63 | 64 | void modify(int l, int r, char v) { 65 | modify(l, r, v, 0, 0, size); 66 | } 67 | 68 | void modify(int l, int r, char v, int x, int lx, int rx) { 69 | propagate(x, lx, rx); 70 | if (lx >= r || rx <= l) return; 71 | if (lx >= l && rx <= r) { 72 | if (v == 'W') { 73 | tree[x].paint = 'W'; 74 | tree[x].value = {0, 0, 'W', 'W'}; 75 | } else { 76 | tree[x].paint = 'B'; 77 | tree[x].value = {1, rx - lx, 'B', 'B'}; 78 | } 79 | } else { 80 | int m = (lx + rx) / 2; 81 | modify(l, r, v, 2 * x + 1, lx, m); 82 | modify(l, r, v, 2 * x + 2, m, rx); 83 | tree[x].value = combine(tree[2*x+1].value, tree[2*x+2].value); 84 | } 85 | } 86 | 87 | node info() { 88 | return info(0, 0, size); 89 | } 90 | 91 | node info(int x, int lx, int rx) { 92 | propagate(x, lx, rx); 93 | return tree[0]; 94 | } 95 | }; 96 | 97 | int main(void) { 98 | int n; 99 | cin >> n; 100 | 101 | segtree st; 102 | st.build(1e6); 103 | 104 | char c; 105 | int x, l; 106 | 107 | for (int i = 0; i < n; i++) { 108 | cin >> c >> x >> l; 109 | x += MOD; 110 | 111 | st.modify(x, x + l, c); 112 | auto x = st.info(); 113 | cout << x.value.count << " " << x.value.sum << endl; 114 | } 115 | 116 | return 0; 117 | } 118 | -------------------------------------------------------------------------------- /segment-tree-part2/step4/D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | using ll = long long; 6 | 7 | struct segtree { 8 | struct node { 9 | ll d; 10 | ll s; 11 | ll ws; 12 | }; 13 | 14 | ll size; 15 | vector tree; 16 | 17 | void init(ll n) { 18 | size = 1; 19 | while (size < n) size *= 2; 20 | tree.assign(2 * size, {0, 0, 0}); 21 | } 22 | 23 | void propagate(ll x, ll lx, ll rx) { 24 | if (tree[x].d == 0 || rx - lx == 1) return; 25 | 26 | tree[2*x+1].d += tree[x].d; 27 | tree[2*x+2].d += tree[x].d; 28 | 29 | ll m = (lx + rx) / 2; 30 | 31 | tree[2*x+1].s += (m - lx) * tree[x].d; 32 | tree[2*x+1].ws += tree[x].d * (m - lx) * (m - lx + 1) / 2; 33 | 34 | tree[2*x+2].s += (rx - m) * tree[x].d; 35 | tree[2*x+2].ws += tree[x].d * (rx - m) * (rx - m + 1) / 2; 36 | 37 | tree[x].d = 0; 38 | } 39 | 40 | void modify(ll l, ll r, ll d) { 41 | modify(l, r, d, 0, 0, size); 42 | } 43 | 44 | void modify(ll l, ll r, ll d, ll x, ll lx, ll rx) { 45 | propagate(x, lx, rx); 46 | if (lx >= r || rx <= l) return; 47 | if (lx >= l && rx <= r) { 48 | tree[x].d += d; 49 | tree[x].s += d * (rx - lx); 50 | tree[x].ws += d * (rx - lx) * (rx - lx + 1) / 2; 51 | } else { 52 | ll m = (lx + rx) / 2; 53 | modify(l, r, d, 2 * x + 1, lx, m); 54 | modify(l, r, d, 2 * x + 2, m, rx); 55 | tree[x].s = tree[2 * x + 1].s + tree[2 * x + 2].s; 56 | tree[x].ws = tree[2 * x + 1].ws + tree[2 * x + 2].ws + (m - lx) * tree[2 * x + 2].s; 57 | } 58 | } 59 | 60 | ll query(ll l, ll r) { 61 | return query(l, r, 0, 0, size).ws; 62 | } 63 | 64 | node add(node s1, node s2, ll d) { 65 | if (s1.d == 0 && s1.s == LLONG_MIN && s1.ws == LLONG_MIN) return s2; 66 | if (s2.d == 0 && s2.s == LLONG_MIN && s2.ws == LLONG_MIN) return s1; 67 | return {0, s1.s + s2.s, s1.ws + s2.ws + d * s2.s}; 68 | } 69 | 70 | node query(ll l, ll r, ll x, ll lx, ll rx) { 71 | propagate(x, lx, rx); 72 | if (lx >= r || rx <= l) return {0, LLONG_MIN, LLONG_MIN}; 73 | if (lx >= l && rx <= r) return tree[x]; 74 | ll m = (lx + rx) / 2; 75 | node s1 = query(l, r, 2 * x + 1, lx, m); 76 | node s2 = query(l, r, 2 * x + 2, m, rx); 77 | 78 | return add(s1, s2, m - max(lx, l)); 79 | } 80 | }; 81 | 82 | int main(void) { 83 | int n, m; 84 | cin >> n >> m; 85 | 86 | segtree st; 87 | st.init(n); 88 | 89 | int v; 90 | for (int i = 0; i < n; i++) { 91 | cin >> v; 92 | st.modify(i, i + 1, v); 93 | } 94 | 95 | int t, l, r, d; 96 | while (m--) { 97 | cin >> t >> l >> r; 98 | l--; 99 | if (t == 1) { 100 | cin >> d; 101 | st.modify(l, r, d); 102 | } else { 103 | cout << st.query(l, r) << endl; 104 | } 105 | } 106 | 107 | return 0; 108 | } 109 | -------------------------------------------------------------------------------- /segment-tree-part2/step4/E.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | struct segtree { 7 | struct op { 8 | int min; 9 | int max; 10 | }; 11 | struct node { 12 | op modify; 13 | int value; 14 | }; 15 | int size; 16 | vector tree; 17 | 18 | op NO_OP = {INT_MAX, INT_MIN}; 19 | 20 | void init(int n) { 21 | size = 1; 22 | while (size < n) size *= 2; 23 | tree.assign(2 * size, {NO_OP, 0}); 24 | } 25 | 26 | op _modify(op &a, op &b) { 27 | if (a.min == NO_OP.min && a.max == NO_OP.max) return b; 28 | 29 | if (b.max <= a.min) return {b.max, b.max}; 30 | if (b.min >= a.max) return {b.min, b.min}; 31 | if (b.min <= a.min && a.max <= b.max) return a; 32 | if (a.min <= b.min && b.max <= a.max) return b; 33 | if (b.min <= a.min) return {a.min, b.max}; 34 | return {b.min, a.max}; 35 | } 36 | 37 | int _modify(int a, op &b) { 38 | // make sure a is in the range of b, adjusting it in case it is out of range 39 | return max(min(a, b.max), b.min); 40 | } 41 | 42 | void propagate(int x, int lx, int rx) { 43 | if (tree[x].modify.min == NO_OP.min && tree[x].modify.max == NO_OP.max) return; 44 | if (rx - lx == 1) return; 45 | 46 | tree[2*x+1].modify = _modify(tree[2*x+1].modify, tree[x].modify); 47 | tree[2*x+1].value = _modify(tree[2*x+1].value, tree[x].modify); 48 | tree[2*x+2].modify = _modify(tree[2*x+2].modify, tree[x].modify); 49 | tree[2*x+2].value = _modify(tree[2*x+2].value, tree[x].modify); 50 | 51 | tree[x].modify = NO_OP; 52 | } 53 | 54 | void update(int l, int r, op v) { 55 | update(l, r, v, 0, 0, size); 56 | } 57 | 58 | void update(int l, int r, op v, int x, int lx, int rx) { 59 | propagate(x, lx, rx); 60 | 61 | if (lx >= r || rx <= l) return; 62 | if (lx >= l && rx <= r) { 63 | tree[x].modify = _modify(tree[x].modify, v); 64 | tree[x].value = _modify(tree[x].value, v); 65 | } else { 66 | int m = (lx + rx) / 2; 67 | update(l, r, v, 2 * x + 1, lx, m); 68 | update(l, r, v, 2 * x + 2, m, rx); 69 | tree[x].value = min(tree[2*x+1].value, tree[2*x+2].value); 70 | } 71 | } 72 | 73 | void collect(vector &result) { 74 | collect(result, 0, 0, size); 75 | } 76 | 77 | void collect(vector &result, int x, int lx, int rx) { 78 | if (rx - lx == 1) { 79 | if (lx < result.size()) { 80 | result[lx] = tree[x].value; 81 | } 82 | } else { 83 | propagate(x, lx, rx); 84 | int m = (lx + rx) / 2; 85 | collect(result, 2 * x + 1, lx, m); 86 | collect(result, 2 * x + 2, m, rx); 87 | } 88 | } 89 | }; 90 | 91 | int main(void) { 92 | ios_base::sync_with_stdio(false); 93 | cin.tie(nullptr); 94 | 95 | int n, k; 96 | cin >> n >> k; 97 | 98 | segtree st; 99 | st.init(n+1); 100 | 101 | int t, l, r, h; 102 | while (k--) { 103 | cin >> t >> l >> r >> h; 104 | if (t == 1) { 105 | st.update(l, r+1, {h, INT_MAX}); 106 | } else { 107 | st.update(l, r+1, {INT_MIN, h}); 108 | } 109 | } 110 | 111 | vector result(n); 112 | st.collect(result); 113 | 114 | for (int i = 0; i < n; i++) { 115 | cout << result[i] << endl; 116 | } 117 | 118 | return 0; 119 | } 120 | -------------------------------------------------------------------------------- /suffix-array/step1/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | #define ll long long 19 | #define pb push_back 20 | #define loop(a) for(int i = 0; i < a; i++) 21 | #define loopv(i,a) for (int i = 0; i < a; i++) 22 | #define all(x) (x).begin(), (x).end() 23 | #define prDouble(x) cout << fixed << setprecision(10) << x 24 | #define goog(tno) cout << "Case #" << tno <<": " 25 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 26 | 27 | int main(void) { 28 | string s; 29 | cin >> s; 30 | s += "$"; 31 | int n = s.size(); 32 | 33 | vector p(n), c(n); 34 | { 35 | // k = 0 36 | vector> v(n); 37 | for (int i = 0; i < n; i++) { 38 | v[i] = {s[i], i}; 39 | } 40 | sort(v.begin(), v.end()); 41 | for (int i = 0; i < n; i++) { 42 | p[i] = v[i].second; 43 | } 44 | c[p[0]] = 0; 45 | for (int i = 1; i < n; i++) { 46 | if (v[i].first == v[i-1].first) { 47 | c[p[i]] = c[p[i-1]]; 48 | } else { 49 | c[p[i]] = c[p[i-1]] + 1; 50 | } 51 | } 52 | } 53 | 54 | { 55 | int k = 0; 56 | while ((1 << k) < n) { 57 | vector, int>> v(n); 58 | for (int i = 0; i < n; i++) { 59 | v[i] = {{c[i], c[(i + (1< 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | #define ll long long 19 | #define pb push_back 20 | #define loop(a) for(int i = 0; i < a; i++) 21 | #define loopv(i,a) for (int i = 0; i < a; i++) 22 | #define all(x) (x).begin(), (x).end() 23 | #define prDouble(x) cout << fixed << setprecision(10) << x 24 | #define goog(tno) cout << "Case #" << tno <<": " 25 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 26 | 27 | void count_sort(vector &p, vector &c) { 28 | int n = p.size(); 29 | vector cnt(n); 30 | 31 | for (auto x : c) { 32 | cnt[x]++; 33 | } 34 | 35 | vector pos(n); 36 | pos[0] = 0; 37 | for (int i = 1; i < n; i++) { 38 | pos[i] = pos[i-1] + cnt[i-1]; 39 | } 40 | 41 | vector p_new(n); 42 | for (auto x : p) { 43 | int i = c[x]; 44 | p_new[pos[i]] = x; 45 | pos[i]++; 46 | } 47 | 48 | p = p_new; 49 | } 50 | 51 | int main(void) { 52 | string input; 53 | cin >> input; 54 | input += "$"; 55 | int n = input.size(); 56 | 57 | vector p(n), c(n); 58 | { 59 | // k = 0 60 | vector> a(n); 61 | for (int i = 0; i < n; i++) { 62 | a[i] = {input[i], i}; 63 | } 64 | sort(a.begin(), a.end()); 65 | for (int i = 0; i < n; i++) 66 | p[i] = a[i].second; 67 | 68 | c[p[0]] = 0; 69 | for (int i = 1; i < n; i++) { 70 | if (a[i].first == a[i-1].first) { 71 | c[p[i]] = c[p[i-1]]; 72 | } else { 73 | c[p[i]] = c[p[i-1]] + 1; 74 | } 75 | } 76 | } 77 | 78 | int k = 0; 79 | while ((1 << k) < n) { 80 | for (int i = 0; i < n; i++) { 81 | p[i] = (p[i] - (1< c_new(n); 87 | c_new[p[0]] = 0; 88 | for (int i = 1; i < n; i++) { 89 | pair prev = { c[p[i-1]], c[(p[i-1] + (1< now = { c[p[i]], c[(p[i] + (1< 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | #define ll long long 19 | #define pb push_back 20 | #define loop(a) for(int i = 0; i < a; i++) 21 | #define loopv(i,a) for (int i = 0; i < a; i++) 22 | #define all(x) (x).begin(), (x).end() 23 | #define prDouble(x) cout << fixed << setprecision(10) << x 24 | #define goog(tno) cout << "Case #" << tno <<": " 25 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 26 | 27 | string input; 28 | string search_string; 29 | 30 | bool find_substring(vector &p, int L, int R) { 31 | while (L <= R) { 32 | int mid = (L + R) / 2; 33 | 34 | string tmp = input.substr(p[mid], search_string.size()); 35 | if (tmp == search_string) return true; 36 | 37 | if (tmp < search_string) L = mid + 1; 38 | else R = mid - 1; 39 | } 40 | 41 | return false; 42 | } 43 | 44 | void count_sort(vector &p, vector &c) { 45 | int n = p.size(); 46 | 47 | vector cnt(n); 48 | for (auto x : c) { 49 | cnt[x]++; 50 | } 51 | 52 | vector pos(n); 53 | pos[0] = 0; 54 | for (int i = 1; i < n; i++) { 55 | pos[i] = pos[i-1] + cnt[i-1]; 56 | } 57 | 58 | vector p_new(n); 59 | for (auto x : p) { 60 | int i = c[x]; 61 | p_new[pos[i]] = x; 62 | pos[i]++; 63 | } 64 | 65 | p = p_new; 66 | } 67 | 68 | int main(void) { 69 | cin >> input; 70 | 71 | input += "$"; 72 | int n = input.size(); 73 | 74 | vector p(n), c(n); 75 | { 76 | vector> a(n); 77 | for (int i = 0; i < n; i++) { 78 | a[i] = {input[i], i}; 79 | } 80 | sort(a.begin(), a.end()); 81 | 82 | for (int i = 0; i < n; i++) 83 | p[i] = a[i].second; 84 | 85 | c[p[0]] = 0; 86 | for (int i = 1; i < n; i++) { 87 | if (a[i].first == a[i-1].first) { 88 | c[p[i]] = c[p[i-1]]; 89 | } else { 90 | c[p[i]] = c[p[i-1]] + 1; 91 | } 92 | } 93 | } 94 | 95 | int k = 0; 96 | while ((1 << k) < n) { 97 | for (int i = 0; i < n; i++) { 98 | p[i] = (p[i] - (1 << k) + n) % n; 99 | } 100 | 101 | count_sort(p, c); 102 | 103 | vector c_new(n); 104 | c_new[p[0]] = 0; 105 | for (int i = 1; i < n; i++) { 106 | pair prev = { c[p[i-1]], c[(p[i-1] + (1< now = { c[p[i]], c[(p[i] + (1<> t; 121 | 122 | while (t--) { 123 | cin >> search_string; 124 | 125 | bool found = find_substring(p, 0, p.size() - 1); 126 | if (found) cout << "Yes" << endl; 127 | else cout << "No" << endl; 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /suffix-array/step4/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | #define ll long long 19 | #define pb push_back 20 | #define loop(a) for(int i = 0; i < a; i++) 21 | #define loopv(i,a) for (int i = 0; i < a; i++) 22 | #define all(x) (x).begin(), (x).end() 23 | #define prDouble(x) cout << fixed << setprecision(10) << x 24 | #define goog(tno) cout << "Case #" << tno <<": " 25 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 26 | 27 | void count_sort(vector &p, vector &c) { 28 | int n = p.size(); 29 | 30 | vector cnt(n); 31 | for (auto x : c) { 32 | cnt[x]++; 33 | } 34 | 35 | vector pos(n); 36 | pos[0] = 0; 37 | for (int i = 1; i < n; i++) { 38 | pos[i] = pos[i-1] + cnt[i-1]; 39 | } 40 | 41 | vector p_new(n); 42 | for (auto x : p) { 43 | int i = c[x]; 44 | p_new[pos[i]] = x; 45 | pos[i]++; 46 | } 47 | 48 | p = p_new; 49 | } 50 | 51 | int main(void) { 52 | string input; 53 | cin >> input; 54 | input += "$"; 55 | 56 | int n = input.size(); 57 | vector p(n), c(n); 58 | 59 | { 60 | vector> a(n); 61 | for (int i = 0; i < n; i++) 62 | a[i] = {input[i], i}; 63 | 64 | sort(a.begin(), a.end()); 65 | 66 | for (int i = 0; i < n; i++) 67 | p[i] = a[i].second; 68 | 69 | c[p[0]] = 0; 70 | for (int i = 1; i < n; i++) { 71 | if (a[i].first == a[i-1].first) { 72 | c[p[i]] = c[p[i-1]]; 73 | } else { 74 | c[p[i]] = c[p[i-1]] + 1; 75 | } 76 | } 77 | } 78 | 79 | int k = 0; 80 | while ((1< c_new(n); 88 | c_new[p[0]] = 0; 89 | for (int i = 1; i < n; i++) { 90 | pair prev = { c[p[i-1]], c[(p[i-1] + (1< now = { c[p[i]], c[(p[i] + (1< lcp(n); 104 | k = 0; 105 | for (int i = 0; i < n - 1; i++) { 106 | int pi = c[i]; 107 | int j = p[pi - 1]; 108 | while (input[i+k] == input[j+k]) k++; 109 | lcp[pi] = k; 110 | k = max(k-1, 0); 111 | } 112 | 113 | loop(n) { 114 | cout << p[i] << " "; 115 | } 116 | cout << endl; 117 | 118 | for (int i = 1; i < n; i++) { 119 | cout << lcp[i] << " "; 120 | } 121 | cout << endl; 122 | 123 | return 0; 124 | } 125 | -------------------------------------------------------------------------------- /suffix-array/step5/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | #define ll long long 19 | #define pb push_back 20 | #define loop(a) for(int i = 0; i < a; i++) 21 | #define loopv(i,a) for (int i = 0; i < a; i++) 22 | #define all(x) (x).begin(), (x).end() 23 | #define prDouble(x) cout << fixed << setprecision(10) << x 24 | #define goog(tno) cout << "Case #" << tno <<": " 25 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 26 | 27 | void count_sort(vector &p, vector &c) { 28 | int n = p.size(); 29 | 30 | vector cnt(n); 31 | for (auto x : c) { 32 | cnt[x]++; 33 | } 34 | 35 | vector pos(n); 36 | pos[0] = 0; 37 | for (int i = 1; i < n; i++) { 38 | pos[i] = pos[i-1] + cnt[i-1]; 39 | } 40 | 41 | vector p_new(n); 42 | for (auto x : p) { 43 | int i = c[x]; 44 | p_new[pos[i]] = x; 45 | pos[i]++; 46 | } 47 | 48 | p = p_new; 49 | } 50 | 51 | int main(void) { 52 | string input; 53 | cin >> input; 54 | input += "$"; 55 | 56 | int n = input.size(); 57 | vector p(n), c(n); 58 | 59 | { 60 | vector> a(n); 61 | loop(n) { 62 | a[i] = {input[i], i}; 63 | } 64 | 65 | sort(a.begin(), a.end()); 66 | 67 | loop(n) { 68 | p[i] = a[i].second; 69 | } 70 | 71 | c[p[0]] = 0; 72 | for (int i = 1; i < n; i++) { 73 | if (a[i].first == a[i-1].first) { 74 | c[p[i]] = c[p[i-1]]; 75 | } else { 76 | c[p[i]] = c[p[i-1]] + 1; 77 | } 78 | } 79 | } 80 | 81 | int k = 0; 82 | while ((1< c_new(n); 90 | c_new[p[0]] = 0; 91 | for (int i = 1; i < n; i++) { 92 | pair prev = { c[p[i-1]], c[(p[i-1] + (1< now = { c[p[i]], c[(p[i] + (1< lcp(n); 107 | for (int i = 0; i < n - 1; i++) { 108 | int pi = c[i]; 109 | int j = p[pi - 1]; 110 | while (input[i+k] == input[j+k]) k++; 111 | lcp[pi] = k; 112 | k = max(k - 1, 0); 113 | } 114 | 115 | ll result = 0; 116 | for (int i = 1; i < n; i++) { 117 | result += n - p[i] - 1 - lcp[i]; 118 | } 119 | 120 | cout << result << endl; 121 | 122 | return 0; 123 | } 124 | -------------------------------------------------------------------------------- /suffix-array/step5/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | #define ll long long 19 | #define pb push_back 20 | #define loop(a) for(int i = 0; i < a; i++) 21 | #define loopv(i,a) for (int i = 0; i < a; i++) 22 | #define all(x) (x).begin(), (x).end() 23 | #define prDouble(x) cout << fixed << setprecision(10) << x 24 | #define goog(tno) cout << "Case #" << tno <<": " 25 | #define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL) 26 | 27 | void count_sort(vector &p, vector &c) { 28 | int n = p.size(); 29 | 30 | vector cnt(n); 31 | for (auto x : c) { 32 | cnt[x]++; 33 | } 34 | 35 | vector pos(n); 36 | pos[0] = 0; 37 | for (int i = 1; i < n; i++) { 38 | pos[i] = pos[i-1] + cnt[i-1]; 39 | } 40 | 41 | vector p_new(n); 42 | for (auto x : p) { 43 | int i = c[x]; 44 | p_new[pos[i]] = x; 45 | pos[i]++; 46 | } 47 | 48 | p = p_new; 49 | } 50 | 51 | int main(void) { 52 | string s, t; 53 | cin >> s >> t; 54 | string input = s + "#" + t + "!"; 55 | 56 | int n = input.size(); 57 | vector p(n), c(n); 58 | 59 | { 60 | vector> a(n); 61 | loop(n) { 62 | a[i] = {input[i], i}; 63 | } 64 | 65 | sort(a.begin(), a.end()); 66 | 67 | loop(n) { 68 | p[i] = a[i].second; 69 | } 70 | 71 | c[p[0]] = 0; 72 | for (int i = 1; i < n; i++) { 73 | if (a[i].first == a[i-1].first) { 74 | c[p[i]] = c[p[i-1]]; 75 | } else { 76 | c[p[i]] = c[p[i-1]] + 1; 77 | } 78 | } 79 | } 80 | 81 | int k = 0; 82 | while ((1< c_new(n); 90 | c_new[p[0]] = 0; 91 | for (int i = 1; i < n; i++) { 92 | pair prev = { c[p[i-1]], c[(p[i-1] + (1< now = { c[p[i]], c[(p[i] + (1< lcp(n); 106 | k = 0; 107 | for (int i = 0; i < n - 1; i++) { 108 | int pi = c[i]; 109 | int j = p[pi - 1]; 110 | while (input[i+k] == input[j+k]) k++; 111 | lcp[pi] = k; 112 | k = max(k - 1, 0); 113 | } 114 | 115 | int result = 0; 116 | string out; 117 | 118 | for (int i = 1; i < n; i++) { 119 | if ((p[i] < s.size() && p[i-1] > s.size()) || (p[i] > s.size() && p[i-1] < s.size())) { 120 | if (lcp[i] > result) { 121 | result = lcp[i]; 122 | out = input.substr(p[i], result); 123 | } 124 | } 125 | } 126 | 127 | cout << out << endl; 128 | 129 | return 0; 130 | } 131 | -------------------------------------------------------------------------------- /two-pointers-method/step1/A.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | using namespace std; 19 | 20 | #define ll long long 21 | #define pb push_back 22 | #define loop(a) for(int i = 0; i < a; i++) 23 | #define loopv(i,a) for (int i = 0; i < a; i++) 24 | #define rep(i,a,b) for (int i = a; i < b; i++) 25 | #define all(x) (x).begin(), (x).end() 26 | #define prDouble(x) cout << fixed << setprecision(10) << x 27 | #define goog(tno) cout << "Case #" << tno <<": " 28 | #define fast_io ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0) 29 | 30 | int main(void) { 31 | int n, m; 32 | cin >> n >> m; 33 | 34 | vector a(n); 35 | vector b(m); 36 | vector c(n+m); 37 | 38 | for (int i = 0; i < n; i++) cin >> a[i]; 39 | for (int i = 0; i < m; i++) cin >> b[i]; 40 | 41 | int i = 0, j = 0; 42 | while (i < n || j < m) { 43 | if (j == m || (i < n && a[i] < b[j])) { 44 | c[i+j] = a[i]; 45 | i++; 46 | } else { 47 | c[i+j] = b[j]; 48 | j++; 49 | } 50 | } 51 | 52 | for (auto x : c) { 53 | cout << x << " "; 54 | } 55 | cout << endl; 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /two-pointers-method/step1/B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | using namespace std; 19 | 20 | #define ll long long 21 | #define pb push_back 22 | #define loop(a) for(int i = 0; i < a; i++) 23 | #define loopv(i,a) for (int i = 0; i < a; i++) 24 | #define rep(i,a,b) for (int i = a; i < b; i++) 25 | #define all(x) (x).begin(), (x).end() 26 | #define prDouble(x) cout << fixed << setprecision(10) << x 27 | #define goog(tno) cout << "Case #" << tno <<": " 28 | #define fast_io ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0) 29 | 30 | int main(void) { 31 | int n, m; 32 | cin >> n >> m; 33 | 34 | vector a(n), b(m), res(m); 35 | 36 | loop(n) cin >> a[i]; 37 | loop(m) cin >> b[i]; 38 | 39 | int i = 0; 40 | for (int j = 0; j < m; j++) { 41 | while (i < n && a[i] < b[j]) i++; 42 | res[j] = i; 43 | } 44 | 45 | for (auto x : res) { 46 | cout << x << " "; 47 | } 48 | cout << endl; 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /two-pointers-method/step1/C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | using namespace std; 19 | 20 | #define ll long long 21 | #define pb push_back 22 | #define loop(a) for(int i = 0; i < a; i++) 23 | #define loopv(i,a) for (int i = 0; i < a; i++) 24 | #define rep(i,a,b) for (int i = a; i < b; i++) 25 | #define all(x) (x).begin(), (x).end() 26 | #define prDouble(x) cout << fixed << setprecision(10) << x 27 | #define goog(tno) cout << "Case #" << tno <<": " 28 | #define fast_io ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0) 29 | 30 | int main(void) { 31 | map mem; 32 | 33 | int n, m; 34 | cin >> n >> m; 35 | 36 | vector a(n), b(m); 37 | ll result = 0; 38 | 39 | loop(n) cin >> a[i]; 40 | loop(m) cin >> b[i]; 41 | 42 | int i = 0; 43 | for (int j = 0; j < m; j++) { 44 | if (mem.find(b[j]) == mem.end()) { 45 | while (i < n && a[i] < b[j]) i++; 46 | int c = 0; 47 | while (i < n && a[i] == b[j]) { 48 | i++, c++; 49 | } 50 | mem[b[j]] = c; 51 | result += c; 52 | } else { 53 | result += mem[b[j]]; 54 | } 55 | } 56 | 57 | cout << result << endl; 58 | 59 | return 0; 60 | } 61 | --------------------------------------------------------------------------------