Submission #568556

#TimeUsernameProblemLanguageResultExecution timeMemory
568556piOOENew Home (APIO18_new_home)C++17
100 / 100
3784 ms178932 KiB
//#define _GLIBCXX_DEBUG //#pragma GCC optimize("Ofast") //#pragma GCC optimize("unroll-loops") //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") #include <bits/stdc++.h> using namespace std; #include <ext/pb_ds/assoc_container.hpp> using namespace __gnu_pbds; template<typename T> using ordered_set = tree<T, null_type, less < T>, rb_tree_tag, tree_order_statistics_node_update>; template<typename T> using normal_queue = priority_queue <T, vector<T>, greater<>>; mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count()); #define ll long long #define trace(x) cout << #x << ": " << (x) << endl; #define all(x) begin(x), end(x) #define rall(x) rbegin(x), rend(x) #define uniq(x) x.resize(unique(all(x)) - begin(x)) #define ld long double #define sz(s) ((int) size(s)) #define pii pair<int, int> #define mp(x, y) make_pair(x, y) #define int128 __int128 #define pb push_back #define eb emplace_back template<typename T> bool ckmn(T &x, T y) { if (x > y) { x = y; return true; } return false; } template<typename T> bool ckmx(T &x, T y) { if (x < y) { x = y; return true; } return false; } int bit(int x, int b) { return (x >> b) & 1; } int rand(int l, int r) { return (int) ((ll) rnd() % (r - l + 1)) + l; } //soryan za musor sverhu const ll infL = 3e18; const int infI = 1000000000 + 7; const int infM = 2139062143; const int N = 500001; const int mod = 1e9 + 7; const ld eps = 1e-9; #define int ll template<typename T> struct SegTreeDownMax { const T MIN = numeric_limits<T>::min() / 2; vector <T> t; int sz; void init(int n, T x = numeric_limits<T>::min() / 2) { sz = n; t.assign(sz << 1, x); } void st(int i, T v) { int x = i + sz; t[x] = v; x >>= 1; while (x) { t[x] = max(t[x << 1], t[x << 1 | 1]); x >>= 1; } } T get(int l, int r) { l += sz; r += sz; // [l, r) T ans = MIN; while (l < r) { if (l & 1) { //it is a right child ckmx(ans, t[l++]); } if (r & 1) { //this is a left child ckmx(ans, t[--r]); } l >>= 1; r >>= 1; } return ans; } }; template<typename T> struct SegTreeDownMin { const T MAX = numeric_limits<T>::max() / 2; vector <T> t; int sz; void init(int n, T x = numeric_limits<T>::max() / 2) { sz = n; t.assign(sz << 1, x); } void st(int i, T v) { int x = i + sz; t[x] = v; x >>= 1; while (x) { t[x] = min(t[x << 1], t[x << 1 | 1]); x >>= 1; } } T get(int l, int r) { // [l, r) T ans = MAX; l += sz; r += sz; while (l < r) { if (l & 1) { //it is a right child ckmn(ans, t[l++]); } if (r & 1) { //this is a left child ckmn(ans, t[--r]); } l >>= 1; r >>= 1; } return ans; } }; struct Q { int x, t, i, type; Q(int a, int b, int c, int d) { x = a, t = b, i = c, type = d; } Q() = default; }; bool cmp(Q a, Q b) { if (a.t != b.t) return a.t < b.t; return a.type < b.type; } int x[N], a[N], b[N], t[N]; int X[N], T[N], cnt[N]; multiset<int> g[N]; ll ans[N]; signed main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, k, q; cin >> n >> k >> q; vector<Q> v; vector<array<int, 4>> yy; for (int i = 0; i < n; ++i) { cin >> x[i] >> t[i] >> a[i] >> b[i]; --t[i]; v.emplace_back(x[i], b[i], i, 1); v.eb(x[i], a[i], i, -1); } for (int i = 0; i < q; ++i) { cin >> X[i] >> T[i]; yy.pb({X[i], -1, -1, -1}); v.eb(X[i], T[i], i, 0); } SegTreeDownMax<ll> stx; SegTreeDownMin<ll> stm; multiset<ll> L, R; auto dod = [&](int l, int r, int i) { int mid = (l + r) >> 1; yy.pb({mid, l, r, i}); }; auto find = [&](int x, int type) -> int { array nw = {x, type, -1ll, -1ll}; return lower_bound(all(yy), nw) - begin(yy); }; auto add = [&](int l, int r, int i) { int MMid = (l + r) >> 1; array nw = {MMid, l, r, i}; int mid = lower_bound(all(yy), nw) - begin(yy); stx.st(mid, r); stm.st(mid, l); }; auto del = [&](int l, int r, int i) { int MMid = (l + r) >> 1; array nw = {MMid, l, r, i}; int mid = lower_bound(all(yy), nw) - begin(yy); stm.st(mid, stm.MAX); stx.st(mid, stx.MIN); }; auto addR = [&](int x, int i) { R.insert(x); }; auto delR = [&](int x, int i) { R.extract(x); }; auto addL = [&](int x, int i) { L.insert(x); }; auto delL = [&](int x, int i) { L.extract(x); }; sort(all(v), cmp); { int num = 0; for (auto to: v) { if (to.type == -1) { int i = to.i; auto it = g[t[i]].upper_bound(x[i]); if (it != end(g[t[i]])) { dod(x[i], *it, t[i]); } if (it != begin(g[t[i]])) { it = prev(it); dod(*it, x[i], t[i]); } g[t[i]].insert(x[i]); ++cnt[t[i]]; assert(sz(g[t[i]]) == cnt[t[i]]); } else if (to.type == 1) { int i = to.i; auto it = g[t[i]].find(x[i]); assert(it != end(g[t[i]])); if (it != begin(g[t[i]]) && it != prev(end(g[t[i]]))) { dod(*prev(it), *next(it), t[i]); } g[t[i]].erase(it); --cnt[t[i]]; assert(sz(g[t[i]]) == cnt[t[i]]); } } } for (int i = 0; i < k; ++i) { if (!g[i].empty()) { assert(cnt[i]); exit(1); } assert(g[i].empty()); } assert(*max_element(all(cnt)) == 0); sort(all(yy)); uniq(yy); stm.init(sz(yy)); stx.init(sz(yy)); { int num = 0; for (auto to: v) { if (to.type == -1) { int i = to.i; // for (int z : g[t[i]]) cout << z << " "; // cout << endl; auto &st = g[t[i]]; auto it = st.upper_bound(x[i]); // if (it != end(g[t[i]])) { // trace(*it) // } if (it != begin(g[t[i]]) && it != end(g[t[i]])) { del(*prev(it), *it, t[i]); } if (it != end(st)) { add(x[i], *it, t[i]); } else { if (!st.empty()) { delR(*st.rbegin(), t[i]); } addR(x[i], t[i]); } if (it != begin(g[t[i]])) { it = prev(it); add(*it, x[i], t[i]); } else { if (!st.empty()) { delL(*begin(st), t[i]); } addL(x[i], t[i]); } g[t[i]].insert(x[i]); if (cnt[t[i]] == 0) ++num; ++cnt[t[i]]; } else if (to.type == 1) { int i = to.i; auto &st = g[t[i]]; auto it = g[t[i]].find(x[i]); assert(it != end(g[t[i]])); if (it == prev(end(st))) { delR(x[i], t[i]); if (sz(st) != 1) { del(*prev(it), x[i], t[i]); addR(*prev(it), t[i]); } } if (it == begin(st)) { delL(x[i], t[i]); if (sz(st) != 1) { del(x[i], *next(it), t[i]); addL(*next(it), t[i]); } } if (it != begin(st) && it != prev(end(st))){ del(x[i], *next(it), t[i]); del(*prev(it), x[i], t[i]); add(*prev(it), *next(it), t[i]); } g[t[i]].erase(it); --cnt[t[i]]; if (cnt[t[i]] == 0) --num; } else { int i = to.i; if (num != k) { ans[i] = -1; } else { int id = find(X[i], -1); // trace(yy[id][0]) // trace(X[i] - stm.get(id, stx.sz)) // trace(stx.get(0, id) - X[i]) // trace(X[i] - *begin(R)); // trace(*rbegin(L) - X[i]) // assert(!L.empty()); // assert(!R.empty()); // trace(id) ans[i] = max({X[i] - stm.get(id, stx.sz), stx.get(0, id) - X[i], X[i] - *begin(R), *rbegin(L) - X[i]}); assert(ans[i] <= 100000000 && ans[i] >= 0); } } } } for (int i = 0; i < q; ++i) cout << ans[i] << '\n'; return 0; }

Compilation message (stderr)

new_home.cpp: In function 'int main()':
new_home.cpp:242:13: warning: unused variable 'num' [-Wunused-variable]
  242 |         int num = 0;
      |             ^~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...