Submission #1049187

#TimeUsernameProblemLanguageResultExecution timeMemory
1049187kostia244Sweeping (JOI20_sweeping)C++17
100 / 100
10564 ms779428 KiB
#include <bits/stdc++.h> #define all(x) begin(x), end(x) using namespace std; using ll = long long; struct Query { int type, v, x, y; }; struct RectSweep { map<int, vector<int>> CtoP[2]; vector<array<int, 2>> pts; vector<int> real_id; map<int, int> local_id; vector<int> pt_color[2]; vector<int> col_coord[2]; void addPoint(array<int, 2> P, int id) { for(int i = 0; i < 2; i++) { CtoP[i][P[i]].push_back(pts.size()); if(CtoP[i][P[i]].size() == 1) { pt_color[i].push_back(col_coord[i].size()); col_coord[i].push_back(P[i]); } else { pt_color[i].push_back(pt_color[i][CtoP[i][P[i]][0]]); } } real_id.push_back(id); local_id[id] = pts.size(); pts.push_back(P); } void combine(vector<int> &a, vector<int> &b, int dir) { if(a.size() < b.size()) swap(a, b); for(auto &i : b) { a.push_back(i); pt_color[dir][i] = pt_color[dir][a[0]]; } } void sweep(int dir, int lim) {//coord_dir max= while(CtoP[dir].size() && CtoP[dir].begin()->first < lim) { combine(CtoP[dir][lim], CtoP[dir].begin()->second, dir); CtoP[dir].erase(CtoP[dir].begin()); int col = pt_color[dir][CtoP[dir][lim][0]]; col_coord[dir][col] = lim; } } vector<array<int, 3>> extract(int dir, int lim) {//delete coord_dir <= lim vector<array<int, 3>> res; while(CtoP[dir].size() && CtoP[dir].begin()->first <= lim) { for(auto i : CtoP[dir].begin()->second) { if(real_id[i] != -1) { int X = col_coord[0][pt_color[0][i]]; int Y = col_coord[1][pt_color[1][i]]; res.push_back({real_id[i], X, Y}); real_id[i] = -1 - dir; } } CtoP[dir].erase(CtoP[dir].begin()); } return res; } array<int, 2> getPoint(int rid) { if(!local_id.count(rid)) return {-1, -1};//never inserted int lid = local_id[rid]; if(real_id[lid] < 0) return {-1, -1};//point already extracted return {col_coord[0][pt_color[0][lid]], col_coord[1][pt_color[1][lid]]}; } }; void test_rs() { RectSweep rs; rs.addPoint({3, 3}, 100); rs.addPoint({0, 0}, 1); rs.sweep(0, 10); for(auto [i, x, y] : rs.extract(1, 0)) cout << i << " " << x << " " << y << "; "; cout << endl; rs.addPoint({0, 0}, 10); rs.sweep(1, 12); rs.sweep(0, 3); for(auto [i, x, y] : rs.extract(0, 9)) cout << i << " " << x << " " << y << "; "; cout << endl; for(auto [i, x, y] : rs.extract(0, 10)) cout << i << " " << x << " " << y << "; "; cout << endl; exit(0); } void solve(int n, vector<Query> queries, vector<array<int, 2>> &ans, int start_x, int start_y) { if(queries.empty()) return; // cout << "_____"<<endl; // cout << n << " " << queries.size() << " cc " << start_x << " " << start_y << endl; // for(auto &q : queries) { // cout << q.type << " " << q.v << " " << q.x << " " << q.y << endl; // } int r = n / 2; array<vector<Query>, 2> push;//0 for top, 1 for right map<int, int> point_dir; RectSweep rc; for(auto q : queries) { if(q.type == 1) { auto [x, y] = rc.getPoint(q.v); if(x >= 0) { ans[q.x] = {start_x + x, start_y + y}; // cout << q.x << " :: " << q.v << " " << start_x << " " << start_y << " " << x << " " << y << endl; } else { assert(point_dir.count(q.v)); push[point_dir[q.v]].push_back(q); } } if(q.type == 2 || q.type == 3) { int dir = 3 - q.type; int len = q.v; // For all P[dir]<=len, P[dir ^ 1] = n - len if(n - len > r) {//go up/right for(auto [id, x, y] : rc.extract(dir, len)) { point_dir[id] = dir; (dir ? x : y) = n - len; push[dir].push_back(Query{4, id, x, y}); } push[dir].push_back(q); } else {//P[dir ^ 1] max= n-len for all rc.sweep(dir ^ 1, n - len); q.v -= r + 1; if(q.v >= 0) push[dir ^ 1].push_back(q); } } if(q.type == 4) { if(q.y > r) { point_dir[q.v] = 0; push[0].push_back(q); } else if(q.x > r) { point_dir[q.v] = 1; push[1].push_back(q); } else { // cout << "Add " << q.x << " " << q.y << " " << q.v << endl; rc.addPoint({q.x, q.y}, q.v); // cout << rc.getPoint(q.v)[1] << endl; } } } for(int c = 0; c < 2; c++) { for(auto &q : push[c]) { if(q.type == 4) { (c ? q.x : q.y) -= r+1; } } } solve(n - r - 1, push[0], ans, start_x, start_y + r + 1); solve(n - r - 1, push[1], ans, start_x + r + 1, start_y); } int main() { cin.tie(0)->sync_with_stdio(0); // test_rs(); int n, m, q; int num_points = 0, num_ask = 0; cin >> n >> m >> q; vector<Query> queries(m + q); for(int x, y, i = 0; i < m; i++) { cin >> x >> y; queries[i] = Query{4, num_points++, x, y}; } for(int i = 0; i < q; i++) { cin >> queries[m+i].type; if(queries[m+i].type == 4) { cin >> queries[m+i].x >> queries[m+i].y; queries[m+i].v = num_points++; } else { cin >> queries[m + i].v; queries[m + i].v -= (queries[m+i].type == 1); if(queries[m+i].type == 1) { queries[m+i].x = num_ask++; } } } vector<array<int, 2>> answers(num_ask); solve(n, queries, answers, 0, 0); for(auto [x, y] : answers) { cout << x << ' ' << y << '\n'; } }

Compilation message (stderr)

sweeping.cpp: In function 'void test_rs()':
sweeping.cpp:85:5: warning: this 'for' clause does not guard... [-Wmisleading-indentation]
   85 |     for(auto [i, x, y] : rs.extract(1, 0)) cout << i << " " << x << " " << y << "; "; cout << endl;
      |     ^~~
sweeping.cpp:85:87: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'
   85 |     for(auto [i, x, y] : rs.extract(1, 0)) cout << i << " " << x << " " << y << "; "; cout << endl;
      |                                                                                       ^~~~
sweeping.cpp:89:5: warning: this 'for' clause does not guard... [-Wmisleading-indentation]
   89 |     for(auto [i, x, y] : rs.extract(0, 9)) cout << i << " " << x << " " << y << "; "; cout << endl;
      |     ^~~
sweeping.cpp:89:87: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'
   89 |     for(auto [i, x, y] : rs.extract(0, 9)) cout << i << " " << x << " " << y << "; "; cout << endl;
      |                                                                                       ^~~~
sweeping.cpp:90:5: warning: this 'for' clause does not guard... [-Wmisleading-indentation]
   90 |     for(auto [i, x, y] : rs.extract(0, 10)) cout << i << " " << x << " " << y << "; "; cout << endl;
      |     ^~~
sweeping.cpp:90:88: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'
   90 |     for(auto [i, x, y] : rs.extract(0, 10)) cout << i << " " << x << " " << y << "; "; cout << endl;
      |                                                                                        ^~~~
#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...