Submission #659015

#TimeUsernameProblemLanguageResultExecution timeMemory
659015600MihneaNew Home (APIO18_new_home)C++17
100 / 100
4484 ms175708 KiB
bool home = 0; #include <bits/stdc++.h> using namespace std; struct MinSegmentTree { vector<int> tree; int nn; void upd(int v, int tl, int tr, int i, int x) { if (tr < i || i < tl) { return; } if (tl == tr) { assert(tl == i); assert(tr == i); tree[v] = x; return; } int tm = (tl + tr) / 2; upd(2 * v, tl, tm, i, x); upd(2 * v + 1, tm + 1, tr, i, x); tree[v] = min(tree[2 * v], tree[2 * v + 1]); } int getmin(int v, int tl, int tr, int l, int r) { if (tr < l || r < tl) { return (int) 1e9 + 7; } if (l <= tl && tr <= r) { return tree[v]; } int tm = (tl + tr) / 2; return min(getmin(2 * v, tl, tm, l, r), getmin(2 * v + 1, tm + 1, tr, l, r)); } void init(int n) { nn = n; tree.clear(); tree.resize(4 * (n + 7), (int) 1e9 + 7); } void upd(int i, int x) { assert(0 <= i && i < nn); upd(1, 0, nn - 1, i, x); } int getmin(int l, int r) { if (l > r) { return (int) 1e9 + 7; } assert(0 <= l && l <= r && r < nn); return getmin(1, 0, nn - 1, l, r); } }; struct Store { int x; int type; int first_time; int last_time; }; struct Query { int x; int t; }; const int N = (int) 3e5 + 7; int n; int k; int q; vector<int> whereType[N]; Store stores[N]; Query queries[N]; bool negative[N]; vector<int> events; int getTimeOfEvent(int i) { if (i >= 1) { assert(1 <= i && i <= n); return stores[i].first_time; } else { i *= -1; assert(1 <= i && i <= n); return stores[i].last_time + 1; } } bool cmpEvents(int i, int j) { return getTimeOfEvent(i) < getTimeOfEvent(j); } struct Position { int i; }; bool operator < (Position a, Position b) { int i = a.i, j = b.i; if (stores[i].x == stores[j].x) { return i < j; } else { return stores[i].x < stores[j].x; } } struct Segment { int first_time; int last_time; int x1; int x2; }; struct RelaxSegment { int first_time; int last_time; int limit; int x; }; vector<RelaxSegment> rels[2]; vector<Segment> segments; void addSegment(int first_time, int last_time, int i, int j) { assert(1 <= i && i <= n + 2); assert(1 <= j && j <= n + 2); if (first_time > last_time) { return; } assert(0 <= first_time && first_time <= last_time && last_time < q); assert(stores[i].x <= stores[j].x); segments.push_back({first_time, last_time, stores[i].x, stores[j].x}); } vector<RelaxSegment> relaxSegments; int getTimeOfRelaxSegmentEvent(int i) { if (i >= 1) { i--; assert(0 <= i && i < (int) relaxSegments.size()); return relaxSegments[i].first_time; } else { i *= -1; i--; assert(0 <= i && i < (int) relaxSegments.size()); return relaxSegments[i].last_time + 1; } } bool cmpRelaxSegmentEvents(int i, int j) { return getTimeOfRelaxSegmentEvent(i) < getTimeOfRelaxSegmentEvent(j); } int print[N]; int small[N]; int main() { if (home) { freopen ("input.txt", "r", stdin); } else { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); } { /// Read cin >> n >> k >> q; for (int i = 1; i <= n; i++) { cin >> stores[i].x >> stores[i].type >> stores[i].first_time >> stores[i].last_time; } for (int i = 1; i <= q; i++) { cin >> queries[i].x >> queries[i].t; } } { /// Normalize time vector<int> interestingTimes; for (int i = 1; i <= q; i++) { interestingTimes.push_back(queries[i].t); } sort(interestingTimes.begin(), interestingTimes.end()); interestingTimes.resize(unique(interestingTimes.begin(), interestingTimes.end()) - interestingTimes.begin()); for (int i = 1; i <= q; i++) { queries[i].t = lower_bound(interestingTimes.begin(), interestingTimes.end(), queries[i].t) - interestingTimes.begin(); } int y = 0; for (int i = 1; i <= n; i++) { stores[i].first_time = lower_bound(interestingTimes.begin(), interestingTimes.end(), stores[i].first_time) - interestingTimes.begin(); stores[i].last_time = lower_bound(interestingTimes.begin(), interestingTimes.end(), stores[i].last_time + 1) - interestingTimes.begin() - 1; if (stores[i].first_time <= stores[i].last_time) { stores[++y] = stores[i]; } } n = y; } { /// Some more computation for (int i = 1; i <= n; i++) { whereType[stores[i].type].push_back(i); } stores[n + 1].x = -((int) 1e8 + 7); stores[n + 2].x = +((int) 2e8 + 7); for (int type = 1; type <= k; type++) { set<Position> positions; map<pair<int, int>, int> sinceWhen; positions.insert({n + 1}); positions.insert({n + 2}); sinceWhen[{n + 1, n + 2}] = 0; events.clear(); for (auto &i : whereType[type]) { events.push_back(+i); events.push_back(-i); } sort(events.begin(), events.end(), cmpEvents); int l_events = 0; while (l_events < (int) events.size()) { int r_events = l_events; while (r_events + 1 < (int) events.size() && getTimeOfEvent(events[r_events + 1]) == getTimeOfEvent(events[r_events])) { r_events++; } int current_time = getTimeOfEvent(events[l_events]); for (int iter_events = l_events; iter_events <= r_events; iter_events++) { int i = events[iter_events]; if (i >= 1) { assert(1 <= i && i <= n); positions.insert({i}); auto it = positions.find({i}); assert(it != positions.end()); auto nxt = it; auto ant = it; nxt++; assert(nxt != positions.end()); assert(ant != positions.begin()); ant--; addSegment(sinceWhen[{ant->i, nxt->i}], current_time - 1, ant->i, nxt->i); assert(sinceWhen.count({ant->i, nxt->i})); sinceWhen.erase({ant->i, nxt->i}); assert(!sinceWhen.count({ant->i, nxt->i})); sinceWhen[{ant->i, it->i}] = current_time; sinceWhen[{it->i, nxt->i}] = current_time; } else { i *= -1; assert(1 <= i && i <= n); assert(positions.count({i})); auto it = positions.find({i}); assert(it != positions.end()); auto nxt = it; auto ant = it; nxt++; assert(nxt != positions.end()); assert(ant != positions.begin()); ant--; assert(!sinceWhen.count({ant->i, nxt->i})); sinceWhen[{ant->i, nxt->i}] = current_time; assert(sinceWhen.count({ant->i, nxt->i})); addSegment(sinceWhen[{ant->i, it->i}], current_time - 1, ant->i, it->i); assert(sinceWhen.count({ant->i, it->i})); sinceWhen.erase({ant->i, it->i}); addSegment(sinceWhen[{it->i, nxt->i}], current_time - 1, it->i, nxt->i); assert(sinceWhen.count({it->i, nxt->i})); sinceWhen.erase({it->i, nxt->i}); positions.erase({i}); } } l_events = r_events + 1; } for (auto &it : sinceWhen) { addSegment(it.second, q - 1, it.first.first, it.first.second); } } } { /// Some other Brute for (auto &segment : segments) { int t1 = segment.first_time; int t2 = segment.last_time; int x1 = segment.x1; int x2 = segment.x2; int xmid = (x1 + x2) / 2; int xmid2 = (x1 + x2 + 1) / 2; rels[0].push_back({t1, t2, xmid, x1}); rels[1].push_back({t1, t2, -xmid2, -x2}); } for (int inv = 0; inv <= 1; inv++) { for (int iq = 1; iq <= q; iq++) { small[iq] = (int) 1e9 + 7; } relaxSegments = rels[inv]; MinSegmentTree tree; tree.init((int) relaxSegments.size()); sort(relaxSegments.begin(), relaxSegments.end(), [&] (RelaxSegment a, RelaxSegment b) { return a.limit > b.limit; }); vector<int> relaxSegmentEvents; for (int i = 0; i < (int) relaxSegments.size(); i++) { relaxSegmentEvents.push_back((i + 1)); relaxSegmentEvents.push_back(-(i + 1)); } sort(relaxSegmentEvents.begin(), relaxSegmentEvents.end(), cmpRelaxSegmentEvents); int p = 0; vector<int> ord; for (int iq = 1; iq <= q; iq++) { ord.push_back(iq); } sort(ord.begin(), ord.end(), [&] (int i, int j) { return queries[i].t < queries[j].t; }); /*int l_events = 0; while (l_events < (int) relaxSegmentEvents.size()) { int r_events = l_events; while (r_events + 1 < (int) relaxSegmentEvents.size() && getTimeOfRelaxSegmentEvent(relaxSegmentEvents[r_events + 1]) == getTimeOfRelaxSegmentEvent(relaxSegmentEvents[r_events])) { r_events++; } int current_time = getTimeOfRelaxSegmentEvent(events[l_events]); for (int iter_events = l_events; iter_events <= r_events; iter_events++) { int i = relaxSegmentEvents[iter_events]; if (i >= 1) { i--; assert(0 <= i && i < (int) relaxSegments.size()); } else { i *= -1; i--; assert(0 <= i && i < (int) relaxSegments.size()); } } l_events = r_events + 1; }*/ for (auto &iq : ord) { while (p < (int) relaxSegmentEvents.size() && getTimeOfRelaxSegmentEvent(relaxSegmentEvents[p]) <= queries[iq].t) { int i = relaxSegmentEvents[p++]; if (i >= 1) { i--; assert(0 <= i && i < (int) relaxSegments.size()); /// add tree.upd(i, relaxSegments[i].x); } else { i *= -1; i--; assert(0 <= i && i < (int) relaxSegments.size()); tree.upd(i, (int) 1e9 + 7); /// delete } } int cnt = 0, L = 0, R = (int) relaxSegments.size() - 1; while (L <= R) { int m = (L + R) / 2; if (queries[iq].x <= relaxSegments[m].limit) { cnt = m + 1; L = m + 1; } else { R = m - 1; } } if (cnt >= 1) { small[iq] = tree.getmin(0, cnt - 1); } } for (int iq = 1; iq <= q; iq++) { print[iq] = max(print[iq], queries[iq].x - small[iq]); queries[iq].x *= -1; } } for (int iq = 1; iq <= q; iq++) { int maxDist = print[iq]; if (maxDist > (int) 1e8) { maxDist = -1; } cout << maxDist << "\n"; } } if (0) { /// Brute for (int iq = 1; iq <= q; iq++) { int maxDist = 0; for (int t = 1; t <= k; t++) { int minDist = (int) 1e9 + 7; for (auto &i : whereType[t]) { if (stores[i].first_time <= queries[iq].t && queries[iq].t <= stores[i].last_time) { minDist = min(minDist, abs(stores[i].x - queries[iq].x)); } } maxDist = max(maxDist, minDist); } if (maxDist == (int) 1e9 + 7) { maxDist = -1; } cout << maxDist << "\n"; } } return 0; }

Compilation message (stderr)

new_home.cpp: In function 'int main()':
new_home.cpp:162:13: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  162 |     freopen ("input.txt", "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...