Submission #216398

#TimeUsernameProblemLanguageResultExecution timeMemory
216398IOrtroiiiSweeping (JOI20_sweeping)C++14
100 / 100
7884 ms357200 KiB
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 500500 * 3;

int N, M, Q;
int pc = 0;
pair<int, int> pts[MAXN];
pair<int, int> ans[MAXN];
bool moved[MAXN];

struct Solver {
   int root[MAXN];
   vector<int> vals;
   vector<vector<int>> comps;
   void reset() {
      vals.clear();
      comps.clear();
   }
   int add(int val, int realId) {
      int id = int(vals.size());
      vals.emplace_back(val);
      comps.emplace_back();
      if (realId != -1) {
         root[realId] = id;
         comps[id].emplace_back(realId);
      }
      return id;
   }
   int merge(int v, int u) {
      if (int(comps[v].size()) < int(comps[u].size())) {
         swap(v, u);
      }
      vals[v] = max(vals[v], vals[u]);
      for (int z : comps[u]) {
         root[z] = v;
         comps[v].emplace_back(z);
      }
      return v;
   }
   int value(int x) { return vals[root[x]]; }
} xs, ys;

void getReal(int id) {
   pts[id].first = xs.value(id);
   pts[id].second = ys.value(id);
}

void solve(int x, int y, vector<tuple<int, int, int>> qs) {
   if (qs.empty()) return;
   int len = N - x - y;
   if (!len) {
      for (auto q : qs) {
         if (get<0>(q) == 1) {
            ans[get<2>(q)] = {x, y};
         }
      }
      return;
   }
   int nx = x + (len + 1) / 2;
   int ny = y + (len + 2) / 2;
   vector<tuple<int, int, int>> uq;
   vector<tuple<int, int, int>> rq;
   multiset<pair<int, int>> xms;
   multiset<pair<int, int>> yms;
   xs.reset(), ys.reset();
   for (auto q : qs) {
      if (get<0>(q) == 1) {
         int pid = get<1>(q);
         int qid = get<2>(q);
         if (pts[pid].second >= ny) {
            uq.emplace_back(q);
         } else if (pts[pid].first >= nx) {
            rq.emplace_back(q);
         } else {
            getReal(pid);
            ans[qid] = pts[pid];
         }
      } else if (get<0>(q) == 2) {
         int len = get<1>(q);
         if (len >= ny) {
            int nv = xs.add(N - len, -1);
            while (xms.size() && xms.begin()->first <= N - len) {
               int v = xms.begin()->second;
               xms.erase(xms.begin());
               nv = xs.merge(nv, v);
            }
            uq.emplace_back(q);
            xms.emplace(xs.vals[nv], nv);
         } else {
            while (yms.size() && yms.begin()->first <= len) {
               int v = yms.begin()->second;
               yms.erase(yms.begin());
               for (int z : ys.comps[v]) {
                  if (!moved[z]) {
                     moved[z] = true;
                     getReal(z);
                     pts[z].first = N - len;
                     rq.emplace_back(4, z, 0);
                  }
               }
            }
            rq.emplace_back(q);
         }
      } else if (get<0>(q) == 3) {
         int len = get<1>(q);
         if (len >= nx) {
            int nv = ys.add(N - len, -1);
            while (yms.size() && yms.begin()->first <= N - len) {
               int v = yms.begin()->second;
               yms.erase(yms.begin());
               nv = ys.merge(nv, v);
            }
            rq.emplace_back(q);
            yms.emplace(ys.vals[nv], nv);
         } else {
            while (xms.size() && xms.begin()->first <= len) {
               int v = xms.begin()->second;
               xms.erase(xms.begin());
               for (int z : xs.comps[v]) {
                  if (!moved[z]) {
                     moved[z] = true;
                     getReal(z);
                     pts[z].second = N - len;
                     uq.emplace_back(4, z, 0);
                  }
               }
            }
            uq.emplace_back(q);
         }
      } else {
         int z = get<1>(q);
         moved[z] = false;
         if (pts[z].second >= ny) {
            moved[z] = true;
            uq.emplace_back(q);
         } else if (pts[z].first >= nx) {
            moved[z] = true;
            rq.emplace_back(q);
         } else {
            int xv = xs.add(pts[z].first, z);
            int yv = ys.add(pts[z].second, z);
            xms.emplace(xs.vals[xv], xv);
            yms.emplace(ys.vals[yv], yv);
         }
      }
   }
   solve(x, ny, uq);
   solve(nx, y, rq);
}

vector<int> asks;

int main() {
   ios_base::sync_with_stdio(false);
   cin >> N >> M >> Q;
   vector<tuple<int, int, int>> qs;
   for (int i = 1; i <= M; ++i) {
      int x, y;
      cin >> x >> y;
      pts[++pc] = {x, y};
      qs.emplace_back(4, pc, 0);
   }
   for (int i = 1; i <= Q; ++i) {
      int op;
      cin >> op;
      if (op == 1) {
         int id;
         cin >> id;
         qs.emplace_back(1, id, i);
         asks.emplace_back(i);
      } else if (op < 4) {
         int len;
         cin >> len;
         qs.emplace_back(op, len, 0);
      } else {
         int x, y;
         cin >> x >> y;
         pts[++pc] = {x, y};
         qs.emplace_back(4, pc, 0);
      }
   }
   solve(0, 0, qs);
   for (int id : asks) {
      cout << ans[id].first << " " << ans[id].second << "\n";
   }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...