Submission #913882

#TimeUsernameProblemLanguageResultExecution timeMemory
913882AsymmetryRoller Coaster Railroad (IOI16_railroad)C++17
100 / 100
1934 ms126384 KiB
#include<bits/stdc++.h> using namespace std; using LL=long long; #define FOR(i,l,r)for(int i=(l);i<=(r);++i) #define REP(i,n)FOR(i,0,(n)-1) #define ssize(x)int(x.size()) #ifdef DEBUG auto&operator<<(auto&o,pair<auto,auto>p){return o<<"("<<p.first<<", "<<p.second<<")";} auto operator<<(auto&o,auto x)->decltype(x.end(),o){o<<"{";int i=0;for(auto e:x)o<<","+!i++<<e;return o<<"}";} #define debug(X...)cerr<<"["#X"]: ",[](auto...$){((cerr<<$<<"; "),...)<<endl;}(X) #else #define debug(...){} #endif LL plan_roller_coaster(vector<int> s, vector<int> t) { int n = ssize(s); map<int, int> imp; vector<pair<int, int>> edges; REP (i, n) { ++imp[s[i]]; --imp[t[i]]; edges.emplace_back(s[i], t[i]); debug(s[i], t[i]); } const int INF = 1e9; --imp[1]; ++imp[INF]; edges.emplace_back(INF, 1); debug(imp); vector<pair<int, int>> stc; int sum = 0; LL answer = 0; for (auto [speed, delta] : imp) { debug(speed, delta, sum, stc); if (sum > 0 && delta < 0) { while (ssize(stc) && delta) { auto [beg, cnt] = stc.back(); stc.pop_back(); edges.emplace_back(speed, beg); answer += speed - beg; --cnt; ++delta; --sum; if (cnt) stc.emplace_back(beg, cnt); } } else if (sum < 0 && delta > 0) { while (ssize(stc) && delta) { auto [beg, cnt] = stc.back(); stc.pop_back(); edges.emplace_back(beg, speed); --cnt; --delta; ++sum; if (cnt) stc.emplace_back(beg, cnt); } } debug("again", speed, delta, sum, stc); if (delta) { stc.emplace_back(speed, abs(delta)); sum += delta; } else if (ssize(stc) && stc.back().first != speed) { debug("special"); auto [beg, cnt] = stc.back(); stc.pop_back(); if (sum > 0) { edges.emplace_back(speed, beg); answer += speed - beg; } else { edges.emplace_back(beg, speed); } --cnt; if (cnt) stc.emplace_back(beg, cnt); stc.emplace_back(speed, 1); } } assert(sum == 0); debug(edges); debug(answer); map<int, int> color; map<int, vector<int>> graph; for (auto [u, v] : edges) graph[u].emplace_back(v); int m = 0; for (const auto &[i, adj] : graph) { if (!color.count(i)) { function<void(int)> dfs = [&](int v) { color[v] = m; for (int u : graph[v]) if (!color.count(u)) dfs(u); }; dfs(i); ++m; } } debug(color); vector<int> rep(m); iota(rep.begin(), rep.end(), 0); function<int(int)> fin = [&](int v) { if (v != rep[v]) rep[v] = fin(rep[v]); return rep[v]; }; auto uni = [&](int a, int b) { a = fin(a); b = fin(b); if (a == b) return false; rep[b] = a; return true; }; int last = 1; vector<tuple<int, int, int>> sr; for (auto [pos, type] : color) { if (color[last] != type) { sr.emplace_back(pos - last, color[last], type); } last = pos; } sort(sr.begin(), sr.end()); for (auto [cost, a, b] : sr) { debug(cost, a, b); if (uni(a, b)) answer += cost; } return answer; } #ifdef LOCAL int main() { cin.tie(0)->sync_with_stdio(0); int n; cin >> n; vector<int> s(n), t(n); REP (i, n) cin >> s[i] >> t[i]; cout << plan_roller_coaster(s, t) << endl; } #endif
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...