Submission #483045

#TimeUsernameProblemLanguageResultExecution timeMemory
483045blueRoller Coaster Railroad (IOI16_railroad)C++17
100 / 100
730 ms74744 KiB
#include "railroad.h" #include <vector> #include <set> #include <map> #include <algorithm> #include <iostream> using namespace std; const int INF = 1'000'000'001; int N; set<int> pos; map<int, int> norm; vector<int> act; int K; struct ds { int Z; vector<int> parent; vector<int> subtree; vector<int> mx; vector<int> mn; ds() { ; } ds(int Z_) { Z = Z_; parent = vector<int>(Z); subtree = vector<int>(Z, 1); mx = vector<int>(Z); mn = vector<int>(Z); for(int i = 0; i < Z; i++) parent[i] = mx[i] = mn[i] = i; } int root(int u) { if(parent[u] == u) return u; parent[u] = root(parent[u]); return parent[u]; } bool connected(int u, int v) { return root(u) == root(v); } void join(int u, int v) { u = root(u); v = root(v); if(u == v) return; if(subtree[u] < subtree[v]) swap(u, v); parent[v] = u; subtree[u] += subtree[v]; mx[u] = max(mx[u], mx[v]); mn[u] = min(mn[u], mn[v]); } }; long long plan_roller_coaster(vector<int> s, vector<int> t) { s.push_back(INF); t.push_back(1); N = int(s.size()); for(int i = 0; i < N; i++) { pos.insert(s[i]); pos.insert(t[i]); } int ct = -1; for(int p: pos) { ct++; norm[p] = ct; act.push_back(p); } K = 1+ct; ds DSU(K); for(int i = 0; i < N; i++) { s[i] = norm[s[i]]; t[i] = norm[t[i]]; // DSU.join(s[i], t[i]); } // for(int i = 0; i < K; i++) cerr << i << ' ' << act[i] << '\n'; vector<int> indegree(K, 0), outdegree(K, 0); for(int i = 0; i < N; i++) { outdegree[s[i]]++; indegree[t[i]]++; } set<int> positive, negative; for(int i = 0; i < K; i++) { if(outdegree[i] > indegree[i]) positive.insert(i); else if(outdegree[i] < indegree[i]) negative.insert(i); } // cerr << "positive: "; // for(int p: positive) cerr << p << ' '; // cerr << '\n'; // // cerr << "negative: "; // for(int n: negative) cerr << n << ' '; // cerr << '\n'; long long ans = 0; while(!positive.empty()) { int p = *positive.begin(); int n = *negative.begin(); // cerr << p << ' ' << n << '\n'; int a = min(p, n); int b = max(p, n); while(1) { a = DSU.root(a); if(DSU.mx[a] >= b) break; DSU.join(a, DSU.mx[a]+1); } // DSU.join(p, n); if(n > p) ans += act[n] - act[p]; outdegree[n]++; indegree[p]++; // cerr << "extra edge " << n << ' ' << p << '\n'; // cerr << "ans = " << ans << '\n'; if(outdegree[n] - indegree[n] == 0) negative.erase(n); if(indegree[p] - outdegree[p] == 0) positive.erase(p); } for(int i = 0; i < N; i++) DSU.join(s[i], t[i]); // cerr << "DSU: "; // for(int i = 0; i < K; i++) cerr << i << ' ' << DSU.root(i) << '\n'; vector< pair<int, int> > H; for(int i = 0; i+1 < K; i++) H.push_back(make_pair(i, i+1)); sort(H.begin(), H.end(), [] (pair<int, int> g, pair<int, int> h) { return act[g.second] - act[g.first] < act[h.second] - act[h.first]; }); for(pair<int, int> h: H) { if(!DSU.connected(h.first, h.second)) { ans += act[h.second] - act[h.first]; DSU.join(h.first, h.second); } } // ans += INF; return ans; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...