Submission #579459

#TimeUsernameProblemLanguageResultExecution timeMemory
579459vovamrNew Home (APIO18_new_home)C++17
100 / 100
4636 ms330552 KiB
#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> #pragma GCC optimize("-O3") #pragma GCC optimize("unroll-loops") #define fi first #define se second #define ll long long #define ld long double #define sz(x) ((int)(x).size()) #define all(x) (x).begin(), (x).end() #define pb push_back #define mpp make_pair #define ve vector using namespace std; using namespace __gnu_pbds; template<class T> using oset = tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>; const ll inf = 1e18; const int iinf = 1e9; typedef pair<ll, ll> pll; typedef pair<int, int> pii; mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()); template <typename T> inline bool chmin(T& a, T b) { return (a > b ? a = b, 1 : 0); } template <typename T> inline bool chmax(T& a, T b) { return (a < b ? a = b, 1 : 0); } const int N = 1 << 20; map<int,int> mp[N]; multiset<int> fe[N]; int t[N * 2]; int L, R; inline void upd(int v, int vl, int vr, int pos, int type, int prev) { if (vl == vr) { if (mp[vl].find(type) == mp[vl].end()) { mp[vl][type] = prev; fe[vl].insert(prev); } else { fe[vl].erase(fe[vl].find(mp[vl][type])); mp[vl][type] = prev; fe[vl].insert(prev); } t[v] = *fe[vl].begin(); return; } int m = vl + vr >> 1; if (pos <= m) upd(2 * v + 1, vl, m, pos, type, prev); else upd(2 * v + 2, m + 1,vr, pos, type, prev); t[v] = min(t[2 * v + 1], t[2 * v + 2]); } inline void erase(int v, int vl, int vr, int pos, int type) { if (vl == vr) { fe[vl].erase(fe[vl].find(mp[vl][type])); mp[vl].erase(type); if (sz(fe[vl])) t[v] = *fe[vl].begin(); else t[v] = iinf; return; } int m = vl + vr >> 1; if (pos <= m) erase(2 * v + 1, vl, m, pos, type); else erase(2 * v + 2, m + 1, vr, pos, type); t[v] = min(t[2 * v + 1], t[2 * v + 2]); } inline int get(int v, int vl, int vr, int l, int r) { if (vl == l && vr == r) return t[v]; int m = vl + vr >> 1; if (r <= m) return get(2 * v + 1, vl, m, l, r); else if (l > m) return get(2 * v + 2, m + 1, vr, l, r); else return min(get(2 * v + 1, vl, m, l, m), get(2 * v + 2, m + 1, vr, m + 1, r)); } inline int get(int l, int r) { if(l>r){return iinf;}return get(0, L, R, l, r); } inline void upd(int pos, int type, int prev) { upd(0, L, R, pos, type, prev); } inline void erase(int pos, int type) { erase(0, L, R, pos, type); } const int M = 3e5 + 10; ve<int> alt, al; array<int,4> a[M]; array<int,2> f[M]; ve<pii> add[3 * M], del[3 * M], ask[3 * M]; map<int,int> g[M]; int res[M]; inline void solve() { fill(t, t + 2 * N, iinf); al.pb(-iinf); int n, k, q; cin >> n >> k >> q; for (int i = 0; i < n; ++i) { int x, t, l, r; cin >> x >> t >> l >> r; a[i] = {x, t, l, r}; alt.pb(l); alt.pb(r + 1); al.pb(x); } for (int i = 0; i < q; ++i) { int x, t; cin >> x >> t; alt.pb(t); al.pb(x); f[i] = {x, t}; } sort(all(alt)); alt.erase(unique(all(alt)), alt.end()); sort(all(al)); al.pb(iinf); al.erase(unique(all(al)), al.end()); L = 0, R = sz(al) - 1; for (auto &[x, t, l, r] : a) { l = lower_bound(all(alt), l) - alt.begin(); r = lower_bound(all(alt), r + 1) - alt.begin(); x = lower_bound(all(al), x) - al.begin(); } for (auto &[x, t] : f) { t = lower_bound(all(alt), t) - alt.begin(); x = lower_bound(all(al), x) - al.begin(); } int m = sz(alt); for (auto &[x, t, l, r] : a) { add[l].pb({x, t}); del[r].pb({x, t}); } for (int i = 0; i < q; ++i) { auto &[x, t] = f[i]; ask[t].pb({x, i}); } for (int type = 1; type <= k; ++type) add[0].pb({R, type}); for (int curt = 0; curt < m; ++curt) { for (auto &[x, type] : add[curt]) { auto it = g[type].upper_bound(x); if (it != g[type].end()) upd(it->fi, type, x); it = g[type].lower_bound(x); if (it != g[type].begin()) { --it; upd(x, type, it->fi); } else upd(x, type, L); ++g[type][x]; } for (auto &[x, type] : del[curt]) { --g[type][x]; if (!g[type][x]) g[type].erase(x); auto it = g[type].lower_bound(x); int prev = L; if (it != g[type].begin()) { --it; prev = it->fi; } it = g[type].upper_bound(x); if (g[type].count(x)) continue; erase(x, type); if (it != g[type].end()) upd(it->fi, type, prev); } for (auto &[x, id] : ask[curt]) { int l = 0, r = 1e8 + 10, mid, ans = -1; while (l <= r) { mid = l + r >> 1; int re = upper_bound(all(al), al[x] + mid) - al.begin(); int f = get(re, R); if (f == iinf || al[f] >= al[x] - mid) ans = mid, r = mid - 1; else l = mid + 1; } res[id] = ans; } } for (int i = 0; i < q; ++i) cout << res[i] << '\n'; } signed main() { ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); int q = 1; // cin >> q; while (q--) solve(); cerr << fixed << setprecision(3) << "Time execution: " << (double)clock() / CLOCKS_PER_SEC << endl; }

Compilation message (stderr)

new_home.cpp: In function 'void upd(int, int, int, int, int, int)':
new_home.cpp:46:20: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   46 |         int m = vl + vr >> 1;
      |                 ~~~^~~~
new_home.cpp: In function 'void erase(int, int, int, int, int)':
new_home.cpp:59:20: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   59 |         int m = vl + vr >> 1;
      |                 ~~~^~~~
new_home.cpp: In function 'int get(int, int, int, int, int)':
new_home.cpp:66:20: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   66 |         int m = vl + vr >> 1;
      |                 ~~~^~~~
new_home.cpp: In function 'void solve()':
new_home.cpp:162:41: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  162 |                                 mid = l + r >> 1;
      |                                       ~~^~~
#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...