#include <bits/stdc++.h>
#define ALL(x) x.begin(),x.end()
#define pb push_back
#define lb lower_bound
#define int long long
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 (max(l, L) > min(r, 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) / 2;
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) / 2;
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';
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
277 ms |
640776 KB |
Output is correct |
2 |
Incorrect |
291 ms |
640516 KB |
Output isn't correct |
3 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
277 ms |
640776 KB |
Output is correct |
2 |
Incorrect |
291 ms |
640516 KB |
Output isn't correct |
3 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Incorrect |
558 ms |
687676 KB |
Output isn't correct |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Incorrect |
592 ms |
682496 KB |
Output isn't correct |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
277 ms |
640776 KB |
Output is correct |
2 |
Incorrect |
291 ms |
640516 KB |
Output isn't correct |
3 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
277 ms |
640776 KB |
Output is correct |
2 |
Incorrect |
291 ms |
640516 KB |
Output isn't correct |
3 |
Halted |
0 ms |
0 KB |
- |