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;
#define FAST ios_base::sync_with_stdio(false); cin.tie(0);
#define LLINF ((long long) 1e18)//1234567890987654321
#define INF 1234567890ll
#define pb push_back
#define ins insert
#define f first
#define s second
#define db 0
#define EPS (1e-7) //0.0000001 the value
#define PI (acos(-1))
#define MAXN (300006)
#define MAXK 26
#define MAXX 15000006
#define ll long long int
#define ld long double
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); //can be used by calling rng() or shuffle(A, A+n, rng)
#define FOR(ii, ss, ee) for(ll ii = ss; ii < ee; ++ii)
#define space " "
#define cbr cerr << "hi\n"
#define mmst(x, v) memset((x), v, sizeof ((x)))
#define siz(x) ((ll)x.size())
#define ph push
#define btinpct(x) __builtin_popcountll(x)
#define p2(x) (1LL<<(x))
#define all(x) (x).begin(), (x).end()
#define lbd(x, y) lower_bound(all(x), y)
#define ubd(x, y) upper_bound(all(x), y)
typedef pair <ll, ll> pi;
typedef pair <ll, pi> spi;
typedef pair <pi, pi> dpi;
inline ll rand(ll x, ll y) { ++y; return (rng() % (y-x)) + x; } //inclusivesss
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<pi,null_type,less<pi>,rb_tree_tag,tree_order_statistics_node_update> pbds_set;
#define llabs abs
#define sdb __attribute__((optimize("-Ofast"), target("arch=sandybridge")))
ll n, q, k;
tuple <ll, ll, ll, ll, ll> A[MAXN]; // l, type, a, b, i
spi Q[MAXN];
ll ans[MAXN];
multiset <ll> ms[MAXN];
priority_queue <pi, vector<pi>,greater<pi>> pq;
void st1_2() {
sort(Q,Q+q); sort(A,A+n, [] (tuple<ll,ll,ll,ll,ll>x,tuple<ll,ll,ll,ll,ll>y) { return get<2>(x) < get<2>(y); });
ll co = 0;
FOR(i,0,q) {
ll t = Q[i].f, l = Q[i].s.f, ind = Q[i].s.s;
while(co < n && t >= get<2>(A[co])) {
ms[get<1>(A[co])].ins(get<0>(A[co]));
pq.ph(pi(get<3>(A[co]),co));++co;
}
while(pq.size() && pq.top().f < t) ms[get<1>(A[pq.top().s])].erase(ms[get<1>(A[pq.top().s])].find(get<0>(A[pq.top().s]))), pq.pop();
ll anss = -1;
FOR(i,1,k+1) {
if(ms[i].empty()) { anss=INF; continue; }
auto itr = ms[i].lower_bound(l);
ll best = INF;
if(itr != ms[i].end()) best=min(best, *itr-l);
if(itr == ms[i].begin());
else {
--itr;
best=min(best, l-*itr);
}
// assert(best != LLINF);
anss=max(anss,best);
}
if(anss==INF) anss=-1;
ans[ind]=anss;
}
FOR(i,0,q) cout << ans[i] << '\n';
}
map <ll, ll> mp; // x, y
multiset<ll>types[MAXN];
ll STORECO[MAXN];
void check_removal_neg(map<ll,ll>::iterator itr) {
while(itr != mp.end()) {
auto itr2 = next(itr); if(itr2 == mp.end()) break; ll val = itr->f;
if(itr->s - (itr2->f-itr->f) > itr2->s) itr = --mp.erase(itr2);
else { break; }
assert(val == itr->f);
}
}
void add_neg(ll xx, ll val) {
mp[xx] = max(mp[xx],val);
auto itr = mp.lower_bound(xx);
while(itr != mp.end()) {
auto itr2 = next(itr); if(itr2 == mp.end()) break; ll val = itr->f;
if(itr->s - (itr2->f-itr->f) > itr2->s) itr = --mp.erase(itr2);
else { break; }
assert(val == itr->f);
}
if(itr!=mp.begin())check_removal_neg(prev(itr));
return;
}
bool remove_neg(ll &co, ll time) {
while(co < n && get<3>(A[co]) < time) {
ll l,type,a,b,ii; tie(l,type,a,b,ii)=A[co]; ++co;
STORECO[type] --;
if(STORECO[type] <= 0) return 0;
auto itr = types[type].lower_bound(l);//assert(itr!=types[type].end());
if(itr == types[type].begin()) {
assert(next(itr)!=types[type].end());
add_neg(1, *next(itr)-1);
} else if(next(itr) != types[type].end()) {
add_neg(((*next(itr) + *prev(itr) + 1)/2), llabs( ((*next(itr) + *prev(itr) + 1)/2) - *next(itr) ));
}
types[type].erase(itr);
}
return 1;
}
void check_removal_pos(map<ll,ll>::iterator itr) {
while(itr!=mp.begin()) {
auto itr2 = prev(itr); ll val = itr->f;
if(itr->s - (itr->f - itr2->f) > itr2->s) itr=mp.erase(itr2);
else break;
assert(val==itr->f);
}
return;
}
void add_pos(ll xx, ll val) {
mp[xx]=max(mp[xx],val);
auto itr = mp.lower_bound(xx);
while(itr!=mp.begin()) {
auto itr2 = prev(itr); ll val = itr->f;
if(itr->s - (itr->f - itr2->f) > itr2->s) itr=mp.erase(itr2);
else break;
assert(val==itr->f);
}
if(next(itr) != mp.end()) check_removal_pos(next(itr));
return;
}
bool remove_pos(ll &co, ll time) {
while(co < n && get<3>(A[co]) < time) {
ll l,type,a,b,ii; tie(l,type,a,b,ii)=A[co]; ++co;
STORECO[type] --;
if(STORECO[type]<=0) return 0;
auto itr = types[type].lower_bound(l); //assert(itr!=types[type].end());
if(itr == prev(types[type].end())) {
add_pos(INF, INF-*prev(itr));
} else if(itr != types[type].begin()) {
add_pos(((*next(itr) + *prev(itr))/2), llabs( ((*next(itr) + *prev(itr))/2) - *prev(itr) ));
}
types[type].erase(itr);
}
return 1;
}
void st3_4() {
sort(Q,Q+q);
sort(A,A+n,[](tuple<ll,ll,ll,ll,ll>x,tuple<ll,ll,ll,ll,ll>y) { return get<3>(x) < get<3>(y); });
FOR(i,0,n) {
types[get<1>(A[i])].ins(get<0>(A[i])); STORECO[get<1>(A[i])]++; // assert(!duplicate[get<0>(A[i])]); duplicate[get<0>(A[i])] = 1;
}
FOR(K,1,k+1) {
/*sort(all(types[K])); types[K].resize(unique(all(types[K]))-types[K].begin());*/ if(types[K].empty()) { FOR(i,0,q) cout << "-1\n"; exit(0); }
for(auto i = next(types[K].begin()); i != types[K].end(); i++) {
mp[(*i+*prev(i)+1)/2] = max(mp[(*i+*prev(i)+1)/2],llabs(*i-(*i+*prev(i)+1)/2));
}
mp[1]=max(mp[1],*types[K].begin()-1);
}
for(auto itr = mp.begin(); itr != mp.end(); itr ++) {
while(itr != mp.end()) {
auto itr2 = next(itr); if(itr2 == mp.end()) break; ll val = itr->f;
if(itr->s - (itr2->f-itr->f) > itr2->s) itr = --mp.erase(itr2);
else { break; }
assert(val == itr->f);
}
}
ll co = 0; bool stillcan = 1;
FOR(i,0,q) { if(!stillcan) { ans[Q[i].s.s] = -INF; continue; }
ll l = Q[i].s.f, t = Q[i].f; stillcan &= remove_neg(co,t); if(!stillcan) { ans[Q[i].s.s] = -INF; continue; }
auto itr = mp.upper_bound(l);
assert(itr != mp.begin()); // even if size is one, itr will be ms.end()
--itr;
ans[Q[i].s.s] = itr->s - (l-itr->f);
}
mp.clear(); mmst(STORECO,0); FOR(i,1,k+1) types[i].clear(); FOR(i,0,n) { types[get<1>(A[i])].ins(get<0>(A[i])); STORECO[get<1>(A[i])]++; }
FOR(K,1,k+1) {
for(auto i = types[K].begin(); i != prev(types[K].end()); i ++) {
mp[(*i+*next(i))/2] = max(mp[(*i+*next(i))/2],llabs((*i+*next(i))/2-*i));
}
mp[INF]=max(mp[INF],INF-(*--types[K].end()));
}
for(auto itr = mp.begin(); itr != mp.end(); itr ++) {
while(itr!=mp.begin()) {
auto itr2 = prev(itr); ll val = itr->f;
if(itr->s - (itr->f - itr2->f) > itr2->s) itr=mp.erase(itr2);
else break;
assert(val==itr->f);
}
}
co = 0;stillcan = 1;
FOR(i,0,q) { if(!stillcan) { ans[Q[i].s.s] = -INF; continue; }
ll l = Q[i].s.f, t = Q[i].f; stillcan &= remove_pos(co,t); if(!stillcan) { ans[Q[i].s.s] = -INF; continue; }
auto itr = mp.lower_bound(l);
// assert(itr != mp.end());
ans[Q[i].s.s] = max(ans[Q[i].s.s], itr->s - (itr->f-l));
}
FOR(i,0,q)if(ans[i]==-INF){ans[i]=-1;}
FOR(i,0,q) cout << ans[i] << '\n';
}
ll rndm = 5;
// struct node {
// int s,e,m;
// pbds_set v;
// node *l, *r;
// node(ll _S, ll _E) {
// s = _S, e = _E, m = (s+e)/2;
// // v.clear();
// if(s!=e){
// l = new node(s,m);
// r = new node(m+1,e);
// }
// }
// void sdb open(ll x, ll nv) {
// v.ins(pi(nv,rndm++));
// if(s==e) return;
// if(x>m) r->open(x,nv);
// else l->open(x,nv);
// }
// void sdb close(ll x, ll nv) {
// v.erase(v.lower_bound(pi(nv,0)));
// if(s==e) return;
// if(x>m) r->close(x,nv);
// else l->close(x,nv);
// }
// ll sdb rmq(ll x, ll y, ll nv) {
// if(s==x&&e==y) { return val(nv); }
// if(x > m) return r->rmq(x,y,nv);
// else if(y <= m) return l->rmq(x,y,nv);
// else return l->rmq(x,m,nv) + r->rmq(m+1,y,nv);
// }
// inline ll sdb val(ll x) {
// return (v.order_of_key(pi(x,0)));
// }
// // void degug() {
// // if(v.empty()) return;
// // // if(s==e) { assert(siz(v)==1); cerr << s << ' ' << v[0] << '\n'; return; }
// // l->degug();
// // r->degug();
// // }
// } *seg;
pbds_set fw[MAXN];
void open(ll x, ll nv) {
++ x;
for(; x <= n; x+=x&(-x)) fw[x].ins(pi(nv,rndm++));
}
void close(ll x, ll nv) {
++ x;
for(; x <= n; x+=x&(-x)) fw[x].erase(fw[x].lower_bound(pi(nv,0)));
}
ll query(ll x, ll nv) {
ll res = 0;
for(; x; x-=x&(-x)) {
res += fw[x].order_of_key(pi(nv,0));
}
return res;
}
ll rmq(ll x, ll y, ll nv) {
++x,++y;
return query(y,nv) - query(x-1,nv);
}
vector<ll>d;
inline ll sdb solve5(ll l) {
ll st = -1, en = max(d.back()-l+2,l-d[0]+2), mid = 0;
while(en-st > 1) {
mid = (st+en)>>1ll;
ll lower = lbd(d,l-mid)-d.begin();
ll upper = ubd(d,l+mid)-d.begin()-1;
if(lower<=upper&&rmq(lower,upper,lower) >= k) en = mid;
else st = mid;
}
return en;
}
inline void sdb rem(ll k, multiset<ll>::iterator itr) {
if(itr == types[k].begin()||itr==types[k].end()) return;
close(*itr, *prev(itr));
}
inline void sdb add(ll k, multiset<ll>::iterator itr) {
if(itr == types[k].begin()||itr==types[k].end()) return;
open(*itr, *prev(itr));
}
inline void sdb st5() {
sort(Q,Q+q); FOR(i,0,n) d.pb(get<0>(A[i])); sort(all(d)); d.resize(unique(all(d))-d.begin());FOR(i,0,n) { get<4>(A[i]) = lbd(d,get<0>(A[i]))-d.begin(); }
sort(A,A+n,[](tuple<ll,ll,ll,ll,ll>x,tuple<ll,ll,ll,ll,ll>y) { return get<2>(x) < get<2>(y); });
ll co = 0; priority_queue <pi, vector<pi>, greater<pi>> ms; // seg = new node(0, n-1);
FOR(i,1,k+1) types[i].ins(-INF);
FOR(i,0,q) {
ll t = Q[i].f, l = Q[i].s.f, ind = Q[i].s.s;
while(co < n && get<2>(A[co]) <= t) {
if(get<3>(A[co]) < t) { ++co; continue; }
ll type = get<1>(A[co]);
ll i = get<4>(A[co]);
auto itr = types[type].lower_bound(i);
if(itr != types[type].end()) { rem(type, itr); }
types[type].ins(i);
itr = types[type].lower_bound(i);
add(type, itr);
add(type, next(itr));
ms.ph(pi(get<3>(A[co]), co));
++co;
}
while(ms.size() && ms.top().f < t) {
ll i = get<4>(A[ms.top().s]);
ll type = get<1>(A[ms.top().s]);
ms.pop();
auto itr = types[type].find(i); // assert(itr != types[type].begin());
rem(type,itr);
rem(type,next(itr));
itr = types[type].erase(types[type].find(i));
add(type, itr);
}
ans[ind] = solve5(l); if(ans[ind]==max(d.back()-l+2,l-d[0]+2)) ans[ind]=-1;
}
FOR(i,0,q) cout << ans[i] << '\n';
}
int sdb main()
{ // freopen("int","r",stdin);
FAST
cin>>n>>k>>q;
FOR(i,0,n) {
ll a,b,c,d;cin>>a>>b>>c>>d;
A[i]=make_tuple(a,b,c,d,i);
}
FOR(i,0,q) {
ll l,t;
cin>>l>>t;
Q[i]=spi(t,pi(l,i));
}
if(k<=400&&n<=6*1e4&&q<=6*1e4) { st1_2(); return 0; }
else if(n > 6*((ll)1e4)) {
st3_4(); return 0;
}
else { st5(); }
}
/*
*
4 2 4
3 1 1 10
9 2 2 4
7 2 5 7
4 1 8 10
5 3
5 6
5 9
1 10
*
*
*
* to fit st3_4 sol *
4 2 4
3 1 1 10
9 2 1 4
7 2 1 7
4 1 1 10
5 3
5 6
5 9
1 10
*
*Ans:
* 2
* 2
* -1
* -1
*/
# | 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... |