Submission #354431

#TimeUsernameProblemLanguageResultExecution timeMemory
35443112tqianNew Home (APIO18_new_home)C++17
100 / 100
3999 ms167656 KiB
#include <bits/stdc++.h> using namespace std; #define f1r(i, a, b) for (int i = a; i < b; i++) #define f0r(i, a) f1r(i, 0, a) #define trav(t, a) for (auto& t : a) #define pb push_back #define eb emplace_back #define mp make_pair #define f first #define s second #define sz(x) (int)(x).size() #define all(x) (x).begin(), (x).end() typedef vector<int> vi; typedef long long ll; typedef vector<ll> vl; typedef pair<int, int> pi; typedef vector<pi> vpi; typedef pair<ll, ll> pl; typedef vector<pl> vpl; const int N = 3e5 + 1; const int M = (1 << 21); const int INF = 1e9; template <class T> bool ckmin(T& a, T b) { return a > b ? a = b, 1 : 0; } template <class T> bool ckmax(T& a, T b) { return a < b ? a = b, 1 : 0; } int get_pos(vi& v, int x) { return upper_bound(all(v), x) - v.begin(); } template <int N> struct SegmentTree { vector<array<int, 4>> todo; // loc to loc, time to time vi num; int mn[N]; void build(int ind, int L, int R) { mn[ind] = 2 * INF; if (L == R) return; int M = (L + R) >> 1; build(2*ind, L, M); build(2*ind+1, M+1, R); } void build() { num.pb(-INF); trav(a, todo) num.pb(a[2]), num.pb(a[3]+1); sort(all(num)); num.erase(unique(all(num)), num.end()); build(1, 0, sz(num)-1); } void modify(int x, int y, int t, int ind, int L, int R) { if (R < x || y < L) return; if (x <= L && R <= y) { ckmin(mn[ind], t); return; } int M = (L + R) >> 1; modify(x, y, t, 2*ind, L, M); modify(x, y, t, 2*ind+1, M+1, R); } void modify(int x, int y, int t) { modify(get_pos(num, x), get_pos(num, y), t, 1, 0, sz(num)-1); } int query(int x, int ind, int L, int R) { int ret = mn[ind]; if (L != R) { int M = (L + R) >> 1; if (x <= M) { ckmin(ret, query(x, 2*ind, L, M)); } else { ckmin(ret, query(x, 2*ind+1, M+1, R)); } } return ret; } int query(int x) { return query(get_pos(num, x), 1, 0, sz(num)-1); } }; int n, k, q; int ans[N]; // stores answers map<pi, int> type[N]; vector<array<int, 5>> mod; // modifications vector<array<int, 3>> query; // queries SegmentTree<M> S[2]; void insert(int x, pair<pi, int> a, pair<pi, int> b) { if (a.f.f == -INF && b.f.f == INF) { S[0].todo.pb({INF, -INF, a.s, x}); S[1].todo.pb({-INF, INF, a.s, x}); } else { int m = (a.f.f+b.f.f) >> 1; S[0].todo.pb({m, a.f.f, a.s, x}); S[1].todo.pb({m+1, b.f.f, a.s, x}); } } pair<pi, int> get_next(map<pi, int>& a, map<pi, int>::iterator b) { b = next(b); if (b == a.end()) return {{INF, -1}, 1}; else return *b; } void init() { cin.tie(0)->sync_with_stdio(); cin >> n >> k >> q; f0r(i, n) { int x, t, a, b; cin >> x >> t >> a >> b; mod.push_back({a, 1, t, x, i}); mod.push_back({b+1, -1, t, x, i}); } f1r(i, 1, k+1) { type[i][{-INF, -1}] = 1; } sort(all(mod)); trav(a, mod) { pi t = {a[3], a[4]}; if (a[1] == 1) { // adding something type[a[2]][t] = 0; auto it = type[a[2]].find(t); insert(a[0]-1, *prev(it), get_next(type[a[2]], it)); // adds the things that ended prev(it)->s = it->s = a[0]; // this is when they started a new thing } else { // removing something auto it = type[a[2]].find(t); insert(a[0]-1, *prev(it), *it); insert(a[0]-1, *it, get_next(type[a[2]], it)); prev(it)->s = a[0]; // set previous time type[a[2]].erase(it); // get rid of thing } } f1r(i, 1, k+1) { insert(1e8, *type[i].begin(), get_next(type[i], type[i].begin())); // set the remainder that didn't get removed, which is the negative infinity // this is so we don't ever have nothing? // figure this out } f0r(i, q) { int l, y; cin >> l >> y; query.pb({l, y, i}); } } void solve0() { sort(query.rbegin(), query.rend()); S[0].build(); sort(all(S[0].todo)); trav(a, query) { while (sz(S[0].todo)) { auto x = S[0].todo.back(); if (x[0] < a[0]) break; // doesn't affect S[0].modify(x[2], x[3], x[1]); S[0].todo.pop_back(); } ckmax(ans[a[2]], a[0]-S[0].query(a[1])); } } void solve1() { reverse(all(query)); S[1].build(); sort(S[1].todo.rbegin(), S[1].todo.rend()); trav(a, query) { while (sz(S[1].todo)) { auto x = S[1].todo.back(); if (x[0] > a[0]) break; // doesn't apply S[1].modify(x[2], x[3], -x[1]); S[1].todo.pop_back(); } ckmax(ans[a[2]], -S[1].query(a[1])-a[0]); } } int main() { init(); solve0(); solve1(); f0r(i, q) { if (ans[i] > 1e8) cout << -1; else cout << ans[i]; cout << '\n'; } return 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...