Submission #1153726

#TimeUsernameProblemLanguageResultExecution timeMemory
1153726Zero_OP새 집 (APIO18_new_home)C++20
0 / 100
5101 ms414788 KiB
#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 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...