Submission #969756

#TimeUsernameProblemLanguageResultExecution timeMemory
969756happypotatoOvertaking (IOI23_overtaking)C++17
19 / 100
22 ms3160 KiB
#include "overtaking.h" #include <bits/stdc++.h> using namespace std; #define ll long long #define pii pair<int, int> #define pll pair<ll, ll> #define ff first #define ss second #define pb push_back ll L; ll speed; map<ll, pll> ans[1001]; void debugmp(int ptr) { cerr << "Outputting map " << ptr << endl; for (pair<ll, pll> cur : ans[ptr]) { cerr << "[" << cur.ff << ", " << cur.ss.ff << "] -> " << cur.ss.ss << endl; } cerr << "End of map " << ptr << endl << endl; } void init(int L_, int N, vector<long long> T, vector<int> W, int X, int m, vector<int> S) { vector<ll> s(m); for (int i = 0; i < m; i++) s[i] = S[i]; L = L_; speed = X; vector<pll> blocks; for (int i = 0; i < N; i++) { if (W[i] <= speed) continue; blocks.pb({T[i], W[i]}); } map<ll, pll> tmp; auto discretise = [&](int ptr) { tmp.clear(); ll prev = -1e18; pll range = {-1, -1}; for (map<ll, pll>::iterator it = ans[ptr].begin(); it != ans[ptr].end(); ++it) { if (it->ss.ss == prev && range.ss + 1 >= it->ff) { tmp[range.ff].ff = max(tmp[range.ff].ff, it->ss.ff); range.ss = tmp[range.ff].ff; continue; } if (range.ff != -1) { tmp[range.ff].ff = min(tmp[range.ff].ff, it->ff - 1); } tmp[it->ff] = it->ss; range = {it->ff, it->ss.ff}; prev = it->ss.ss; } ans[ptr].clear(); ans[ptr] = tmp; }; map<ll, ll> mp; for (int i = 1; i < m; i++) { ans[i].clear(); sort(blocks.begin(), blocks.end(), [&](const pll &lhs, const pll &rhs) { if (lhs.ff != rhs.ff) return lhs.ff < rhs.ff; return lhs.ss > rhs.ss; }); mp.clear(); ll dt = s[i] - s[i - 1]; for (int j = 0; j < (int)(blocks.size()); j++) { ll t = blocks[j].ff, w = blocks[j].ss; map<ll, ll>::iterator it = mp.upper_bound(t); if (it != mp.begin()) { --it; if (it->ss >= t + w * dt) { if (it->ff < t) t = it->ss; else t += w * dt; blocks[j].ff = t; continue; } } mp[t] = t + w * dt; t += w * dt; blocks[j].ff = t; } // for (auto &[t, w] : blocks) cerr << t << ' ' << w << endl; for (map<ll, ll>::iterator it = mp.begin(); it != mp.end(); ++it) { // cerr << it->ff << ' ' << it->ss << endl; ll st = it->ff + 1, en = it->ss - speed * dt; map<ll, ll>::iterator it2 = it; ++it2; if (it2 != mp.end()) en = min(en, it2->ff); if (st <= en) ans[i][st] = {en, it->ss}; } discretise(i); // debugmp(i); } auto merge = [&](int l, int r) { int mid = (l + r) >> 1; int pl = l, pr = mid + 1; // cerr << l << ' ' << r << ' ' << pl << ' ' << pr << endl; // debugmp(pl); debugmp(pr); for (map<ll, pll>::iterator it = ans[pl].begin(); it != ans[pl].end(); ++it) { ll nx = it->ss.ss + speed * (s[r] - s[mid]); map<ll, pll>::iterator it2 = ans[pr].upper_bound(it->ss.ss); if (it2 != ans[pr].begin()) { --it2; if (it2->ff <= it->ss.ss && it->ss.ss <= it2->ss.ff) { nx = it2->ss.ss; } } it->ss.ss = nx; } discretise(pl); // cerr << "RESULT 1:" << endl; debugmp(pl); for (map<ll, pll>::iterator it = ans[pr].begin(); it != ans[pr].end(); ++it) { ll tl = it->ff, tr = it->ss.ff; tl -= speed * (s[mid] - s[l - 1]); tr -= speed * (s[mid] - s[l - 1]); // cerr << tl << ' ' << tr << ' ' << it->ss.ss << endl; bool checked = false; while (true) { map<ll, pll>::iterator it2 = ans[pl].lower_bound(tl); if (!checked) { checked = true; if (it2 == ans[pl].begin()) continue; --it2; if (it2->ss.ss > it->ss.ss) { tl = 0; tr = -1; break; } if (it2->ss.ff + 1 < tl) continue; } if (it2 == ans[pl].end()) break; // cerr << it2->ff << ' ' << it2->ss.ff << ' ' << it2->ss.ss << endl; if (it2->ff > tr + 1) break; // have intersection // cerr << "CHECKING:\n"; // cerr << tl << ' ' << tr << ' ' << it->ss.ss << endl; // cerr << it2->ff << ' ' << it2->ss.ff << ' ' << it2->ss.ss << endl; if (it2->ss.ss <= it->ss.ss) { if (it2->ss.ss < it->ss.ss) { if (it2->ss.ff >= tl) exit(1); it2->ss.ff = min(it2->ss.ff, tl - 1); } else { tl = min(tl, it2->ff); tr = max(tr, it2->ss.ff); ans[pl].erase(it2); } } else { tr = min(tr, it2->ff - 1); break; } } // cerr << tl << ' ' << tr << endl; if (tl <= tr) { ans[pl][tl] = {tr, it->ss.ss}; } } discretise(pl); // cerr << "RESULT 2:" << endl; debugmp(pl); }; auto recur = [&](auto&& self, int l, int r) { if (l == r) return; int mid = (l + r) >> 1; self(self, l, mid); self(self, mid + 1, r); merge(l, r); }; recur(recur, 1, m - 1); // cerr << "FINAL:" << endl; debugmp(1); // cerr << "END OF FINAL" << endl; return; } long long arrival_time(long long x) { map<ll, pll>::iterator it = ans[1].upper_bound(x); if (it != ans[1].begin()) { --it; if (it->ff <= x && x <= it->ss.ff) return it->ss.ss; } return x + L * speed; }
#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...