This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
constexpr int INF = 1e9 + 100;
struct SegLeft{
vector<int> X;
int tree[600600], sz;
pair<int, int> buf[10001000];
int lsz;
inline void push(int i, int x){
if (tree[i] <= x) return;
buf[lsz++] = {i, tree[i]};
tree[i] = x;
}
inline void pop(){
--lsz;
tree[buf[lsz].first] = buf[lsz].second;
}
void init(const vector<int> &_X){
X = _X;
sz = X.size();
lsz = 0;
fill(tree, tree+sz*2, INF);
}
void update(int l, int r, int x){
if (l==-INF) l = 0;
else l = lower_bound(X.begin(), X.end(), l) - X.begin();
if (r==INF) r = (int)X.size();
else r = upper_bound(X.begin(), X.end(), r) - X.begin();
for (l+=sz, r+=sz;l<r;l>>=1, r>>=1){
if (l&1){
push(l, x);
l++;
}
if (r&1){
--r;
push(r, x);
}
}
}
int query(int p){
p = lower_bound(X.begin(), X.end(), p) - X.begin();
int ret = INF;
for (p+=sz;p;p>>=1) ret = min(ret, tree[p]);
return ret;
}
void rollback(int lsz0){
while(lsz > lsz0) pop();
}
}treeL;
struct SegRight{
vector<int> X;
int tree[600600], sz;
pair<int, int> buf[10001000];
int lsz;
inline void push(int i, int x){
if (tree[i] >= x) return;
buf[lsz++] = {i, tree[i]};
tree[i] = x;
}
inline void pop(){
--lsz;
tree[buf[lsz].first] = buf[lsz].second;
}
void init(const vector<int> &_X){
X = _X;
sz = X.size();
lsz = 0;
fill(tree, tree+sz*2, -INF);
}
void update(int l, int r, int x){
if (l==-INF) l = 0;
else l = lower_bound(X.begin(), X.end(), l) - X.begin();
if (r==INF) r = (int)X.size();
else r = upper_bound(X.begin(), X.end(), r) - X.begin();
for (l+=sz, r+=sz;l<r;l>>=1, r>>=1){
if (l&1){
push(l, x);
l++;
}
if (r&1){
--r;
push(r, x);
}
}
}
int query(int p){
p = lower_bound(X.begin(), X.end(), p) - X.begin();
int ret = -INF;
for (p+=sz;p;p>>=1) ret = max(ret, tree[p]);
return ret;
}
void rollback(int lsz0){
while(lsz > lsz0) pop();
}
}treeR;
int pos[300300], col[300300], a[300300], b[300300];
int posQ[300300], tQ[300300], ans[300300];
vector<int> T, X, buf[1201200], bufQ[300300];
multiset<int> st[300300];
void insert(int i, int l, int r, int s, int e, int x){
if (r<s || e<l) return;
if (s<=l && r<=e){
buf[i].push_back(x);
return;
}
int m = (l+r)>>1;
insert(i<<1, l, m, s, e, x);
insert(i<<1|1, m+1, r, s, e, x);
}
void dnc(int i, int l, int r){
int szL = treeL.lsz, szR = treeR.lsz;
for (auto &idx:buf[i]){
int c = col[idx], p = pos[idx];
auto iter = st[c].find(p);
auto niter = next(iter);
if (iter==st[c].begin()){
if (niter==st[c].end()){
treeL.update(-INF, INF, -INF);
}
else{
treeR.update(-INF, *niter, *niter);
}
}
else{
auto piter = prev(iter);
if (niter==st[c].end()){
treeL.update(*piter, INF, *piter);
}
else{
int mid = (*piter + *niter) / 2;
treeL.update(*piter, mid, *piter);
treeR.update(mid+1, *niter, *niter);
}
}
st[c].erase(iter);
}
if (l==r){
for (auto &idx:bufQ[l]){
int pl = treeL.query(posQ[idx]);
int pr = treeR.query(posQ[idx]);
if (pl==-INF || pr==INF) ans[idx] = -1;
else ans[idx] = max(posQ[idx]-pl, pr-posQ[idx]);
}
}
else{
int m = (l+r)>>1;
dnc(i<<1, l, m);
dnc(i<<1|1, m+1, r);
}
for (auto &idx:buf[i]) st[col[idx]].insert(pos[idx]);
treeL.rollback(szL);
treeR.rollback(szR);
}
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
int n, k, q;
cin >> n >> k >> q;
for (int i=1;i<=n;i++){
cin >> pos[i] >> col[i] >> a[i] >> b[i];
}
for (int i=1;i<=q;i++){
cin >> posQ[i] >> tQ[i];
T.push_back(tQ[i]);
X.push_back(posQ[i]);
}
sort(T.begin(), T.end());
T.erase(unique(T.begin(), T.end()), T.end());
sort(X.begin(), X.end());
X.erase(unique(X.begin(), X.end()), X.end());
treeL.init(X); treeR.init(X);
for (int i=1;i<=q;i++){
tQ[i] = lower_bound(T.begin(), T.end(), tQ[i]) - T.begin() + 1;
bufQ[tQ[i]].push_back(i);
// printf(" ok t = %d\n", i);
}
for (int i=1;i<=n;i++){
a[i] = lower_bound(T.begin(), T.end(), a[i]) - T.begin() + 1;
b[i] = upper_bound(T.begin(), T.end(), b[i]) - T.begin() + 1;
// printf(" ok remove (%d, %d) and (%d, %d)\n", 1, a[i]-1, b[i], (int)T.size());
insert(1, 1, T.size(), 1, a[i]-1, i);
insert(1, 1, T.size(), b[i], T.size(), i);
}
for (int i=1;i<=n;i++){
st[col[i]].insert(pos[i]);
}
for (int i=1;i<=k;i++){
if (st[i].empty()) {treeL.update(-INF, INF, -INF); continue;}
int p = -INF;
for (auto x:st[i]){
if (p==-INF) treeR.update(-INF, x, x);
else{
int mid = (p+x)/2;
treeL.update(p, mid, p);
treeR.update(mid+1, x, x);
}
p = x;
}
treeL.update(p, INF, p);
}
dnc(1, 1, T.size());
for (int i=1;i<=q;i++) printf("%d\n", ans[i]);
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |