# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
799663 | kirakaminski968 | Roller Coaster Railroad (IOI16_railroad) | C++17 | 0 ms | 0 KiB |
이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include "railroad.h"
#include <bits/stdc++.h>
#define ll long long
using namespace std;
struct dsu{
int par[400005];
void init(int N){
for(int i = 0;i<=N;++i) par[i] = i;
}
int finden(int x) return par[x] = (par[x] == x ? x : finden(x));
bool unite(int x, int y){
x = finden(x); y = finden(y);
if(x == y){
return false;
}
par[y] = x;
return true;
}
}D;
struct edge{
int start, ende, wert;
bool operator<(const edge &e)const{
return wert < e.wert;
}
};
int cnt[400005];
ll plan_roller_coaster(vector<int> s, vector<int> t){
vector<int> merged; int n = (int)s.size();
for(int i = 0;i<n;++i) {merged.push_back(s[i]); merged.push_back(t[i]);}
sort(merged.begin(),merged.end());
merged.resize(unique(merged.begin(),merged.end())-merged.begin());
D.init(merged.size());
for(int i = 0;i<n;++i){
s[i] = lower_bound(merged.begin(),merged.end(),s[i])-merged.begin();
t[i] = lower_bound(merged.begin(),merged.end(),t[i])-merged.begin();
cnt[s[i]]++; cnt[t[i]]--; D.unite(s[i],t[i]);
}
int cur = 1; ll ans = 0;
vector<edge> kanten;
for(int i = merged.size()-1;i>=0;--i){
cur += cnt[i];
if(cur < 0){
ans += -1ll * cur * (merged[i]-merged[i-1]);
cnt[i-1] += cur;
D.unite(i-1,i);
cur = 0;
}
if(cur > 0 && i > 0) D.unite(i,i-1);
else if(cur == 0) kanten.push_back({i-1,i,merged[i]-merged[i-1]});
}
sort(kanten.begin(),kanten.end());
for(auto p : kanten){
if(unite(p.start,p.ende)) ans += p.wert;
}
return ans;
}