Submission #241841

#TimeUsernameProblemLanguageResultExecution timeMemory
241841godwindRoller Coaster Railroad (IOI16_railroad)C++14
100 / 100
623 ms70496 KiB
#include "railroad.h" #include <iostream> #include <vector> #include <algorithm> #include <random> #include <set> #include <map> #include <queue> #include <cstring> #include <cmath> #include <bitset> #include <iomanip> #include <functional> using namespace std; template<typename T> void uin(T &a, T b) { if (b < a) a = b; } #define all(v) v.begin(), v.end() const long long INF = 1e18 + 228; const int OGO = 1000 * 1000 * 1000 + 228; const int N = 400 * 1000 + 228; long long dp[(1 << 17) + 17][16]; int p[N], siz[N]; void init(int n) { for (int i = 1; i <= n; ++i) { p[i] = i; siz[i] = 1; } } int getp(int v) { if (v == p[v]) return v; p[v] = getp(p[v]); return p[v]; } void join(int u, int v) { u = getp(u); v = getp(v); if (u != v) { if (siz[u] > siz[v]) swap(u, v); p[u] = v; siz[v] += siz[u]; } } struct Edge { int u, v, w; Edge() {} Edge(int _u, int _v, int _w) { u = _u; v = _v; w = _w; } }; bool operator<(Edge A, Edge B) { return A.w < B.w; } vector<int> crd; vector<int> g[N], gr[N]; int pref[N]; bool used[N]; void dfs(int v, int start) { join(v, start); used[v] = 1; for (int to : gr[v]) { if (!used[to]) { dfs(to, start); } } } int Get(int i) { return lower_bound(all(crd), i) - crd.begin() + 1; } void AddEdge(int from, int to) { from = Get(from); to = Get(to); g[from].emplace_back(to); ++pref[from]; --pref[to]; gr[from].emplace_back(to); gr[to].emplace_back(from); } long long plan_roller_coaster(vector<int> s, vector<int> t) { int n = (int)s.size(); if (n <= -15) { for (int i = 0; i < (1 << n); ++i) { for (int j = 0; j < n; ++j) { dp[i][j] = INF; } } for (int fir = 0; fir < n; ++fir) { dp[1 << fir][fir] = 0; } for (int mask = 0; mask < (1 << n); ++mask) { for (int last = 0; last < n; ++last) { if (dp[mask][last] != INF) { for (int new_last = 0; new_last < n; ++new_last) { if ((mask >> new_last) & 1) continue; long long cur = dp[mask][last] + max(0, t[last] - s[new_last]); uin(dp[mask | (1 << new_last)][new_last], cur); } } } } long long answer = INF; for (int last = 0; last < n; ++last) { uin(answer, dp[(1 << n) - 1][last]); } return answer; } else { // subtask 3 crd.clear(); for (int i = 0; i < n; ++i) { crd.emplace_back(s[i]); crd.emplace_back(t[i]); } crd.emplace_back(OGO); sort(crd.begin(), crd.end()); crd.erase(unique(crd.begin(), crd.end()), crd.end()); int sz = (int)crd.size(); for (int i = 0; i < n; ++i) { AddEdge(s[i], t[i]); } AddEdge(OGO, 1); long long answer = 0; vector< Edge > edges; for (int i = 1; i < sz; ++i) { pref[i] += pref[i - 1]; if (pref[i] > 0) { answer += (long long)pref[i] * (long long)(crd[i] - crd[i - 1]); gr[i].emplace_back(i + 1); gr[i + 1].emplace_back(i); } else { if (pref[i] != 0) { gr[i].emplace_back(i + 1); gr[i + 1].emplace_back(i); } } edges.emplace_back( i, i + 1, crd[i] - crd[i - 1] ); } sort(all(edges)); int comps = 0; init(sz); for (int i = 1; i <= sz; ++i) { if (!used[i]) { dfs(i, i); } } for (auto e : edges) { int u = e.u, v = e.v, w = e.w; if (getp(u) != getp(v)) { answer += w; join(u, v); } } return answer; } return 0; }

Compilation message (stderr)

railroad.cpp: In function 'long long int plan_roller_coaster(std::vector<int>, std::vector<int>)':
railroad.cpp:157:7: warning: unused variable 'comps' [-Wunused-variable]
   int comps = 0;
       ^~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...