# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
1111841 | hungnt | 마상시합 토너먼트 (IOI12_tournament) | C++17 | 0 ms | 0 KiB |
이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
#define BIT(x, k) (((x) >> (k)) & 1)
#define on(x, k) ((x) ^ (1ll << (k)))
#define pii pair<int, int>
#define fi first
#define se second
#define all(x) x.begin(), x.end()
#define ll long long
using namespace std;
const int N = 200005;
int n, ro, point;
vector<int> adj[N];
int a[N], bit[N], pa[N], h[N], par[20][N];
int pre[N], suf[N];
int numNode;
void update(int x, int v)
{
for(; x <= n; x += x & -x) bit[x] += v;
}
int Find_pos(int v)
{
int sum = 0;
int pos = 0;
for(int i= __lg(n); i>= 0; i--)
{
if(pos + (1 << i) < n && sum + bit[pos + (1 << i)] < v)
{
sum += bit[pos + (1 << i)];
pos += (1 << i);
}
}
return pos + 1; // +1 because 'pos' will have position of largest value less than 'v'
}
int Find_par(int u)
{
if(u == pa[u]) return u;
return pa[u] = Find_par(pa[u]);
}
void Union(int u, int v)
{
u = Find_par(u), v = Find_par(v);
if(u == v) return;
if(u < v) swap(u, v);
pa[v] = u;
}
void init()
{
cin >> n >> ro >> point;
for(int i = 1; i < n; i++) cin >> a[i];
for(int i = 1; i <= n; i++) update(i, 1);
for(int i = 1; i <= n + n; i++) pa[i] = i;
int l, r;
vector<int> pos;
numNode = n;
while(ro--)
{
cin >> l >> r;
pos.clear();
numNode++;
for(int i = l; i <= r; i++)
{
int p = Find_pos(i);
pos.push_back(p);
}
for(int x : pos)
{
update(x, -1);
x = Find_par(x);
adj[numNode].push_back(x);
}
update(pos[0], 1);
Union(pos[0], numNode);
}
}
void dfs(int u, int p)
{
par[0][u] = p;
for(int v : adj[u])
if(v != p)
{
h[v] = h[u] + 1;
dfs(v, u);
}
}
void build_lca()
{
dfs(numNode, 0);
for(int i = 1; (1 << i) <= n; i++)
for(int j = 1; j <= n; j++)
par[i][j] = par[i - 1][par[i - 1][j]];
}
int lca(int u, int v)
{
if(h[u] < h[v]) swap(u, v);
int dist = h[u] - h[v];
while (dist)
{
u = par[__builtin_ctz(dist)][u];
dist -= dist & -dist;
}
if(u == v) return n;
for(int i = __lg(n); i >= 0; i--)
if(par[i][u] != par[i][v])
{
u = par[i][u];
v = par[i][v];
}
return par[0][u];
}
void process()
{
build_lca();
for (int i = 2; i <= n; i++) pre[i] = (a[i - 1] > point ? i - 1 : pre[i - 1]);
for (int i = n - 1; i >= 1; i--) suf[i] = (a[i] > point ? i + 1 : suf[i + 1]);
pair <int, int> res = {0, -1};
for (int i = 1; i <= n; i++)
{
int f = h[i];
if (pre[i]) f = min(f, h[i] - h[lca(pre[i], i)]);
if (suf[i]) f = min(f, h[i] - h[lca(suf[i], i)]);
res = max(res, make_pair(f, -i));
}
cout << -res.se;
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
#define TASK "tournament"
if (fopen(TASK".INP", "r"))
{
freopen(TASK".INP", "r", stdin);
freopen(TASK".OUT", "w", stdout);
}
init();
process();
cerr << "\nTime elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << "s\n";
}