Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <set>
- using std::cout;
- using std::endl;
- using std::vector;
- using std::pair;
- class DisjointSets {
- private:
- vector<int> parents;
- vector<int> sizes;
- public:
- DisjointSets(int size) : parents(size), sizes(size, 1) {
- for (int i = 0; i < size; i++) {
- parents[i] = i;
- }
- }
- int get_rep(int n) {
- return parents[n] == n ? n : (parents[n] = get_rep(parents[n]));
- }
- bool link(int n1, int n2) {
- n1 = get_rep(n1);
- n2 = get_rep(n2);
- if (n1 == n2) {
- return false;
- }
- if (sizes[n1] < sizes[n2]) {
- std::swap(n1, n2);
- }
- sizes[n1] += sizes[n2];
- parents[n2] = n1;
- return true;
- }
- };
- /**
- * https://codeforces.com/edu/course/2/lesson/7/2/practice/contest/289391/problem/C
- * (sample input omitted due to length)
- */
- int main() {
- int employee_num;
- int query_num;
- std::cin >> employee_num >> query_num;
- DisjointSets company(employee_num);
- std::set<pair<int, int>> ranges; // inclusive
- for (int q = 0; q < query_num; q++) {
- int type;
- int arg1, arg2;
- std::cin >> type >> arg1 >> arg2;
- arg1--;
- arg2--;
- if (type == 1) {
- company.link(arg1, arg2);
- } else if (type == 2) {
- int start = ranges.begin()->first;
- if (ranges.empty()
- || arg2 < start
- || ranges.rbegin()->second < arg1) {
- for (int i = arg1 + 1; i <= arg2; i++) {
- company.link(i, i - 1);
- }
- ranges.insert({arg1, arg2});
- continue;
- }
- vector<pair<int, int>> unneeded;
- pair<int, int> new_int{arg1, arg2};
- pair<int, int> to_merge{arg1, arg2};
- pair<int, int> range1{-1, -1};
- if (arg1 > start) {
- range1 = *--ranges.upper_bound({arg1, 0});
- if (range1.first <= arg1 && arg1 <= range1.second) {
- new_int.first = range1.first;
- to_merge.first = range1.second;
- unneeded.push_back(range1);
- }
- }
- pair<int, int> range2 = *--ranges.upper_bound({arg2, 0});
- if (range1 == range2 && range1.first <= arg1 && arg2 <= range1.second) {
- continue;
- }
- if (range2.first <= arg2 && arg2 <+ range2.second) {
- new_int.second = range2.second;
- to_merge.second = range2.first;
- unneeded.push_back(range2);
- }
- auto it = ranges.lower_bound({to_merge.first, 0});
- for (int i = to_merge.first + 1; i <= to_merge.second; i++) {
- company.link(i, i - 1);
- if (i == it->first) {
- i = it->second;
- unneeded.push_back(*it);
- it++;
- }
- }
- for (const pair<int, int>& r : unneeded) {
- ranges.erase(r);
- }
- ranges.insert(new_int);
- // cout << ranges << endl;
- } else if (type == 3) {
- bool same = company.get_rep(arg1) == company.get_rep(arg2);
- cout << (same ? "YES" : "NO") << '\n';
- }
- }
- }
Add Comment
Please, Sign In to add comment