#include <bits/stdc++.h>
#define ALL(x) x.begin(),x.end()
#define pb push_back
#define lb lower_bound
using namespace std;
const int N = 3e5 + 5;
const int M = 1e7 + 5;
struct Query {
int time, pos, shopType, id;
bool isOpen, isQuery;
};
struct Node {
multiset <int> vals;
int lNode, rNode;
Node() {
lNode = rNode = -1;
}
};
int nodes = 1;
Node node[M];
void addSide(Node& tmp) {
tmp.lNode = nodes++;
tmp.rNode = nodes++;
}
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;
}
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;
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';
}
Compilation message
new_home.cpp: In function 'int main()':
new_home.cpp:138:9: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
138 | freopen("0.in", "r", stdin);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~
new_home.cpp:139:9: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
139 | freopen("0.out", "w", stdout);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Incorrect |
262 ms |
562436 KB |
Output isn't correct |
2 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Incorrect |
262 ms |
562436 KB |
Output isn't correct |
2 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Incorrect |
257 ms |
562288 KB |
Output isn't correct |
2 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Incorrect |
274 ms |
562364 KB |
Output isn't correct |
2 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Incorrect |
262 ms |
562436 KB |
Output isn't correct |
2 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Incorrect |
262 ms |
562436 KB |
Output isn't correct |
2 |
Halted |
0 ms |
0 KB |
- |