Submission #1301046

#TimeUsernameProblemLanguageResultExecution timeMemory
1301046joshjuiceInspections (NOI23_inspections)C++20
100 / 100
248 ms40932 KiB
#include <bits/stdc++.h> using namespace std; #define int long long #define rep(x, a, b) for(auto x=a;(a<b?x<b:x>b);(a<b?x++:x--)) #define all(a) a.begin(), a.end() #define srtvc(a) sort(all(a)) #define bcsrtvc(a) sort(all(a), greater<__typeof__(a[0])>()) #define ppf pop_front #define ppb pop_back #define pf push_front #define pb push_back #define ef emplace_front #define eb emplace_back #define fr first #define sc second #define pq priority_queue #define pii pair<int, int> #define vc vector #define dq deque #define sz(a) a.size() #define mnto(x,y) x = min(x, (__typeof__(x))y) #define mxto(x,y) x = max(x, (__typeof__(x))y) #define setval(arr, x) memset(arr, x, sizeof(arr)) template<typename T> using vv = vc<vc<T>>; struct Segment { int left, right, last_use; Segment(int _l, int _r, int _lst) : left(_l), right(_r), last_use(_lst) {} bool operator<(const Segment &other) const { return right < other.right; } }; using SSI = set<Segment>::iterator; inline int is_cut(const Segment &cur, const Segment &nex) { if (cur.right < nex.left || cur.left > nex.right) return 1; if (cur.left <= nex.left && nex.right <= cur.right) return 2; if (nex.left <= cur.left && cur.right <= nex.right) return 3; if (nex.left <= cur.left && cur.left <= nex.right && nex.right <= cur.right) return 4; return 5; } int32_t main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int N, M, Q; cin >> N >> M >> Q; vc<int> L(M+1), R(M+1), S(Q+1); rep(i, 1, M+1) cin >> L[i] >> R[i]; rep(i, 1, Q+1) cin >> S[i]; set<Segment> ranges; unordered_map<int, int> cnt_dist; cnt_dist.reserve(M*2); vc<Segment> cuts, to_insert; vc<SSI> to_delete; cuts.reserve(16); to_insert.reserve(16); to_delete.reserve(16); int tim = 0; rep(i, 1, M+1) { Segment nex(L[i], R[i], tim); cuts.clear(); to_insert.clear(); to_delete.clear(); auto it = ranges.lower_bound(Segment(L[i], L[i], 0)); while (it != ranges.end() && it -> left <= R[i]) { cuts.pb(*it); to_delete.pb(it); ++it; } for (auto &d : to_delete) ranges.erase(d); to_insert.pb(nex); for (auto &cur : cuts) { int type = is_cut(cur, nex); if (type == 1) continue; int overlap = 0; int time_dist = nex.last_use - cur.last_use + cur.left - nex.left - 1; switch (type) { case 2: { int ls = cur.left, le = nex.left - 1; int rs = nex.right + 1, re = cur.right; if (ls <= le) to_insert.eb(ls, le, cur.last_use); if (rs <= re) to_insert.eb(rs, re, cur.last_use+rs-ls); overlap = nex.right - nex.left + 1; break; } case 3: { overlap = cur.right - cur.left + 1; break; } case 4: { int rs = nex.right + 1, re = cur.right; if (rs <= re) to_insert.eb(rs, re, cur.last_use+rs-cur.left); overlap = nex.right - cur.left + 1; break; } case 5: { int ls = cur.left, le = nex.left - 1; if (ls <= le) to_insert.eb(ls, le, cur.last_use); overlap = cur.right - nex.left + 1; break; } } cnt_dist[time_dist] += overlap; } for (auto &seg : to_insert) ranges.insert(seg); tim += (R[i] - L[i] + 1); } vc<pii> dists; dists.reserve(sz(cnt_dist)); for (auto &p : cnt_dist) dists.eb(p.fr, p.sc); srtvc(dists); vc<pii> pref; pref.reserve(sz(dists)+1); int tot = 0; pref.eb(-1, 0); for (auto &[dist, cnt] : dists) { tot += cnt; pref.eb(dist, tot); } rep(i, 1, Q+1) { auto it = lower_bound(all(pref), pii(S[i], 0)); if (it == pref.begin()) cout << tot << ' '; else { --it; cout << tot - it -> sc << ' '; } } }
#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...