Submission #563072

#TimeUsernameProblemLanguageResultExecution timeMemory
563072MazaalaiNew Home (APIO18_new_home)C++17
0 / 100
5061 ms91604 KiB
#include <bits/stdc++.h> #define ALL(x) x.begin(),x.end() #define pb push_back #define lb lower_bound using namespace std; struct Query { int time, pos, shopType, id; bool isOpen, isQuery; }; struct Node { multiset <int> vals; int lNode, rNode; }; int nodes = 1; vector <Node> node; Node emptyNode; void addSide(Node& tmp) { tmp.lNode = nodes++; tmp.rNode = nodes++; node.pb(emptyNode); node.pb(emptyNode); } void update(int l, int r, int L, int R, int val, bool isAdd, int head) { //log^MlogK // cout << '\t' << L << ' ' << R << ' ' << val << ' ' << (isAdd ? "+" : "-") << '\n'; if (l > R || L > r || l > r || L > R) return; if (L <= l && r <= R) { if (isAdd) { node[head].vals.insert(val); } else { node[head].vals.erase(node[head].vals.lb(val)); } return; } int mid = (l+r)>>1; if (node[head].lNode == -1) addSide(node[head]); update(l, mid, L, R, val, isAdd, node[head].lNode); update(mid+1, r, L, R, val, isAdd, node[head].rNode); } int query(int l, int r, int pos, int head) { // logN if (head < 0) return 0; int res = 0; if (node[head].vals.size() > 0) res = max(res, abs(pos - *node[head].vals.begin())); if (node[head].vals.size() > 1) res = max(res, abs(pos - *node[head].vals.rbegin())); int mid = (l+r)>>1; if (pos <= mid) res = max(res, query(l, mid, pos, node[head].lNode)); else res = max(res, query(mid+1, r, pos, node[head].rNode)); return res; } const int N = 3e5 + 5; multiset <int> pos[N]; int shopSz; int segL = 0, segR = 1e8; void updateQuery(Query& query) { // log^MlogK multiset <int>& curSet = pos[query.shopType]; // cout << (query.isOpen ? "ADD" : "REM") << ' ' << query.pos << ' ' << query.shopType << ' ' << query.time << '\n'; // cout << curSet.size() << " -> " ; if (query.isOpen) { curSet.insert(query.pos); auto it = curSet.lb(query.pos); auto itL = it; itL--; auto itR = it; itR++; int a = *itL, b = *it, c = *itR; int mid = (a + c) / 2; int mid1 = (a + b) / 2; int mid2 = (b + c) / 2; if (a != 0 && c != 1e9) { update(segL, segR, a+1, mid, a, 0, 0); update(segL, segR, mid+1, c, c, 0, 0); update(segL, segR, a+1, mid1, a, 1, 0); update(segL, segR, mid1+1, mid2, b, 1, 0); update(segL, segR, mid2+1, c, c, 1, 0); } else if (a != 0) { update(segL, segR, a+1, segR, a, 0, 0); update(segL, segR, a+1, mid1, a, 1, 0); update(segL, segR, mid1+1, b, b, 1, 0); update(segL, segR, b+1, segR, b, 1, 0); } else if (c != 1e9) { update(segL, segR, segL+1, c, c, 0, 0); update(segL, segR, segL+1, b, b, 1, 0); update(segL, segR, b+1, mid2, b, 1, 0); update(segL, segR, mid2+1, c, c, 1, 0); } else { update(segL, segR, segL+1, b, b, 1, 0); update(segL, segR, b+1, segR, b, 1, 0); } } else { auto it = curSet.lb(query.pos); auto itL = it; itL--; auto itR = it; itR++; int a = *itL, b = *it, c = *itR; curSet.erase(it); int mid = (a + c) / 2; int mid1 = (a + b) / 2; int mid2 = (b + c) / 2; if (a != 0 && c != 1e9) { update(segL, segR, a+1, mid1, a, 0, 0); update(segL, segR, mid1+1, mid2, b, 0, 0); update(segL, segR, mid2+1, c, c, 0, 0); update(segL, segR, a+1, mid, a, 1, 0); update(segL, segR, mid+1, c, c, 1, 0); } else if (a != 0) { update(segL, segR, a+1, mid1, a, 0, 0); update(segL, segR, mid1+1, b, b, 0, 0); update(segL, segR, b+1, segR, b, 0, 0); update(segL, segR, a+1, segR, a, 1, 0); } else if (c != 1e9) { update(segL, segR, segL+1, b, b, 0, 0); update(segL, segR, b+1, mid2, b, 0, 0); update(segL, segR, mid2+1, c, c, 0, 0); update(segL, segR, segL+1, c, c, 1, 0); } else { update(segL, segR, segL+1, b, b, 0, 0); update(segL, segR, b+1, segR, b, 0, 0); } } // cout << curSet.size() << '\n'; shopSz += (query.isOpen && curSet.size() == 3); shopSz -= (curSet.size() == 2); } int ans[N]; int n, q, k; int getAns(Query& q) { // logN // cout << "QUERY: " << q.pos << ' ' << q.id << ' ' << q.time << '\n'; // cout << shopSz << ' ' << k << '\n'; if (shopSz < k) return -1; return query(segL, segR, q.pos, 0); } signed main() { // freopen("0.in", "r", stdin); // freopen("0.out", "w", stdout); ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); cin >> n >> k >> q; emptyNode.lNode = emptyNode.rNode = -1; emptyNode.vals.clear(); node.pb(emptyNode); for (int i = 1; i <= k; i++) { // N pos[i].insert(0); pos[i].insert(1e9); } vector <Query> queries; for (int i = 1; i <= n; i++) { // N int x, t, a, b; cin >> x >> t >> a >> b; queries.pb({a, x, t, 0, 1, 0}); queries.pb({b+1, x, t, 0, 0, 0}); } for (int i = 1; i <= q; i++) { // Q int x, t; cin >> x >> t; queries.pb({t, x, 0, i, 0, 1}); } sort(ALL(queries), [&](Query&a, Query&b) { // (N+Q)log(N+Q) return (a.time == b.time ? b.isQuery : a.time < b.time); }); for (auto& query : queries) { // (N+Q)log^MlogK if (!query.isQuery) { updateQuery(query); } else { ans[query.id] = getAns(query); } } for (int i = 1; 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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...