Submission #684230

#TimeUsernameProblemLanguageResultExecution timeMemory
684230izanbfExamination (JOI19_examination)C++14
0 / 100
3065 ms18284 KiB
#include <bits/stdc++.h> using namespace std; struct Point { int x, y, z; }; struct Query { int a, b, c, id; }; const int B = 850; const int MAXSZ = 6e5+99; int bit[MAXSZ]; // binary/fenwick indexed tree int sz; // bit size int bit_sum(int r) { int sum = 0; for (; r > 0; r -= r&-r) sum += bit[r]; return r; } int bit_sum(int l, int r) { return bit_sum(r) - bit_sum(l-1); } void bit_add(int r, int delta) { for (; r < sz; r += r&-r) bit[r] += delta; } int main() { ios::sync_with_stdio(false); cin.tie(0); int N, Q; cin >> N >> Q; set<int> values; vector<Point> pts(N); for (int i = 0; i < N; ++i) { Point& p = pts[i]; cin >> p.x >> p.y; p.z = p.x + p.y; values.insert(p.x); values.insert(p.y); values.insert(p.z); } vector<Query> qs(Q); for (int i = 0; i < Q; ++i) { Query& q = qs[i]; cin >> q.a >> q.b >> q.c; q.id = i; values.insert(q.a); values.insert(q.b); values.insert(q.c); } unordered_map<int,int> comp; for (int v : values) { comp[v] = comp.size(); } for (Query& q : qs) { q.a = comp[q.a]; q.b = comp[q.b]; q.c = comp[q.c]; } for (Point& p : pts) { p.x = comp[p.x]; p.y = comp[p.y]; p.z = comp[p.z]; } sz = comp.size() + 10; sort(qs.begin(), qs.end(), [](const Query& l, const Query& r) { return l.c < r.c; }); sort(pts.begin(), pts.end(), [](const Point& l, const Point& r) { return l.z < r.z; }); int blocks = (N+B-1)/B; vector<vector<Query>> block_queries(blocks); int j = 0; for (int block = 1; block < blocks; ++block) { int i = B*block; while (j < Q and qs[j].c <= pts[i].z) { block_queries[block-1].push_back(qs[j]); ++j; } } while (j < Q) { block_queries.back().push_back(qs[j]); ++j; } vector<int> ans(Q); for (int block = 0; block < blocks; ++block) { if (block_queries[block].empty()) continue; fill(bit, bit+sz, 0); vector<Point> in_block; in_block.reserve(B); for (int i = B*block; i < N and i < B*(block+1); ++i) { in_block.push_back(pts[i]); } vector<Point> over_block; over_block.reserve(N-B*block); for (int i = B*(block+1); i < N; ++i) { over_block.push_back(pts[i]); bit_add(pts[i].y, 1); } sort(over_block.begin(), over_block.end(), [&](const Point& l, const Point& r) { return l.x > r.x; }); sort(block_queries[block].begin(), block_queries[block].end(), [&](const Query& l, const Query& r) { return l.a < r.a; }); for (const Query& q : block_queries[block]) { int cnt_in = 0; int cnt_over = 0; // points in block for (const Point& p : in_block) { if (p.x >= q.a and p.y >= q.b and p.z >= q.c) ++cnt_in; } // points over block while ((not over_block.empty()) and over_block.back().x < q.a) { const Point& p = over_block.back(); bit_add(p.y, -1); over_block.pop_back(); } cnt_over = bit_sum(q.b, sz-1); ans[q.id] = cnt_in + cnt_over; } } for (int i = 0; i < Q; ++i) { cout << ans[i] << '\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...