제출 #241841

#제출 시각아이디문제언어결과실행 시간메모리
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;
}

컴파일 시 표준 에러 (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...