#include <bits/stdc++.h>
using namespace std;
//loops (warning : long long)
#define FOR(i, l, r) for(int i = (l); i < (r); ++i)
#define ROF(i, r, l) for(int i = (r - 1); i >= l; --i)
//pairs, tuples
#define mp make_pair
#define mt make_tuple
#define ff first
#define ss second
//vectors
#define all(v) begin(v), end(v)
#define rall(v) rbegin(v), rend(v)
#define pb push_back
#define eb emplace_back
#define sum_of(v) accumulate(all(v), 0ll)
#define sz(v) (int)v.size()
#define compact(v) v.erase(unique(all(v)), end(v))
//binary search
#define lwb lower_bound
#define upb upper_bound
//other stuffs
#define dbg(x) "[" #x " = " << (x) << "]"
#define file(task) if(fopen(task".inp", "r")){ freopen(task".inp", "r", stdin); freopen(task".out", "w", stdout); }
template<typename T>
bool minimize(T& a, const T& b){
if(a > b) return a = b, true;
return false;
}
template<typename T>
bool maximize(T& a, const T& b){
if(a < b) return a = b, true;
return false;
}
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using db = double;
using pi = pair<int, int>;
using pl = pair<ll, ll>;
using vi = vector<int>;
using vb = vector<bool>;
using vl = vector<ll>;
using vpi = vector<pi>;
using vpl = vector<pl>;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
struct SegmentTreeStack{
struct Node{
multiset<int> S;
Node() : S() {}
void insert(int x){
// if(mn.empty()) mn.pb(x), mx.pb(x);
// else mn.pb(min(mn.back(), x)), mx.pb(max(mx.back(), x));
S.insert(x);
}
void erase(int x){
assert(!S.empty());
S.erase(S.lower_bound(x));
}
int get_max_distance(int x){
if(S.empty()) return 0;
int cur = max(x - *S.begin(), *S.rbegin() - x);
assert(cur >= 0);
return cur;
}
int size(){ return sz(S); }
};
int n;
vector<Node> st;
SegmentTreeStack(int _n) : n(_n), st(n << 2) {
// cout << dbg(n) << '\n';
}
void update_insert(int id, int l, int r, int u, int v, int val){
// cout << id << ' ' << l << ' ' << r << ' ' << u << ' ' << v << ' ' << val << '\n';
if(u <= l && r <= v){
st[id].insert(val);
} else{
int mid = l + r >> 1;
if(u <= mid) update_insert(id << 1, l, mid, u, v, val);
if(mid < v) update_insert(id << 1 | 1, mid + 1, r, u, v, val);
}
}
void update_erase(int id, int l, int r, int u, int v, int val){
if(u <= l && r <= v){
st[id].erase(val);
} else{
int mid = l + r >> 1;
if(u <= mid) update_erase(id << 1, l, mid, u, v, val);
if(mid < v) update_erase(id << 1 | 1, mid + 1, r, u, v, val);
}
}
int query(int id, int l, int r, int pos, int val, int k){
k -= st[id].size();
if(l == r){
assert(k >= 0);
return (k > 0 ? -1 : st[id].get_max_distance(val));
}
int mid = l + r >> 1;
int nxt = (pos <= mid ? query(id << 1, l, mid, pos, val, k) :
query(id << 1 | 1, mid + 1, r, pos, val, k));
if(nxt == -1) return -1;
return max(st[id].get_max_distance(val), nxt);
}
void update_insert(int l, int r, int val){
// cout << "ST insert : " << dbg(l) << dbg(r) << dbg(val) << '\n';
if(l <= r) update_insert(1, 1, n, l, r, val);
}
void update_erase(int l, int r, int val){
// cout << "ST erase : " << dbg(l) << dbg(r) << dbg(val) << '\n';
if(l <= r) update_erase(1, 1, n, l, r, val);
}
};
const int bound = (int)1e8 + 1;
namespace Solver{
const int MAX = 3e5 + 5;
SegmentTreeStack T(0);
int K, n; vi points;
multiset<int> online[MAX];
void init(int _K, vi _points){
K = _K;
points = _points;
n = sz(points) - 2;
T = SegmentTreeStack(n);
FOR(i, 0, K) online[i].insert(0), online[i].insert(n+1);
}
void insert_candidate_range(int l, int r){
//(l, r]
// cout << "insert candidate : " << l << ' ' << r << '\n';
int pos = upper_bound(all(points), (points[l] + points[r]) / 2) - points.begin() - 1;
// cout << dbg(points[l]) << dbg(points[pos]) << dbg(points[r]) << '\n';
T.update_insert(l+1, pos, (l == 0 ? points[r] : points[l]));
T.update_insert(pos+1, r, (r == n+1 ? points[l] : points[r]));
}
void erase_candidate_range(int l, int r){
//(l, r]
// cout << "erase candidate : " << l << ' ' << r << '\n';
int pos = upper_bound(all(points), (points[l] + points[r]) / 2) - points.begin() - 1;
// cout << dbg(points[l]) << dbg(points[pos]) << dbg(points[r]) << '\n';
T.update_erase(l+1, pos, (l == 0 ? points[r] : points[l]));
T.update_erase(pos+1, r, (r == n+1 ? points[l] : points[r]));
}
void insert(int t, int x){
// cout << t << ' ' << x << '\n';
if(sz(online[t]) == 2){
// cout << "First insertion : " << 1 << ' ' << x << ' ' << points[x] << '\n';
// cout << "First insertion : " << x+1 << ' ' << n << ' ' << points[x] << '\n';
// cout << dbg(1) << dbg(x) << dbg(points[x]) << '\n';
insert_candidate_range(0, x);
insert_candidate_range(x, n+1);
} else{
if(online[t].find(x) == online[t].end()){
int L = *prev(online[t].lower_bound(x));
int R = *online[t].upper_bound(x);
// cout << dbg(L) << dbg(R) << dbg(x) << '\n';
erase_candidate_range(L, R);
insert_candidate_range(L, x);
insert_candidate_range(x, R);
}
}
online[t].insert(x);
}
// void erase(int t, int x){
// online[t].erase(online[t].lower_bound(x));
// if(sz(online[t]) == 2){
// T.update(1, x, -1);
// T.update(x+1, n, -1);
// } else{
// if(online[t].find(x) == online[t].end()){
// int L = *prev(online[t].lower_bound(x));
// int R = *online[t].upper_bound(x);
//
// erase_candidate_range(L, x);
// erase_candidate_range(x, R);
// insert_candidate_range(L, R);
// }
// }
// }
int query(int x){
// cout << points[x] << dbg(x) << '\n';
return T.query(1, 1, n, x, points[x], K);
}
}
void testcase(int ntestcase){ //Subtask 3
int N, K, Q;
cin >> N >> K >> Q;
vi points, x(N), t(N);
FOR(i, 0, N){
int a, b;
cin >> x[i] >> t[i] >> a >> b;
--t[i];
points.pb(x[i]);
// assert(a == 1 && b == (int)1e8);
}
vi l(Q), y(Q);
FOR(i, 0, Q){
cin >> l[i] >> y[i];
points.pb(l[i]);
}
points.pb(0); points.pb(bound);
sort(all(points)); compact(points);
Solver::init(K, points);
FOR(i, 0, N){
x[i] = lower_bound(all(points), x[i]) - points.begin();
// cout << dbg(t[i]) << dbg(x[i]) << '\n';
Solver::insert(t[i], x[i]);
}
FOR(i, 0, Q){
l[i] = lower_bound(all(points), l[i]) - points.begin();
cout << Solver::query(l[i]) << '\n';
}
}
int main(){
ios_base::sync_with_stdio(0); cin.tie(0);
// file("task");
if(fopen("task.inp", "r")){
freopen("task.inp", "r", stdin);
}
int T = 1;
//cin >> T;
FOR(i, 0, T) testcase(i);
return 0;
}
Compilation message (stderr)
new_home.cpp: In function 'int main()':
new_home.cpp:259:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
259 | freopen("task.inp", "r", stdin);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
# | 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... |