이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using namespace std;
#define all(x) x.begin(), x.end()
const int N = 1e6+6;
int mx, ans, n, c, p[N], sz[N], rr[N], ll[N], seg[N*4], seg2[N*4];
pair<int, int> queries[N];
vector<int> higher, lp[N], rp[N];
set<int> st[N];
int findSet(int x) {
return (p[x] == x ? x : p[x] = findSet(p[x]));
}
void unite(int x, int y) {
x = findSet(x);
y = findSet(y);
if (x == y) return;
if (sz[x] < sz[y]) swap(x, y);
p[y] = x;
sz[x] += sz[y];
ll[x] = min(ll[x], ll[y]);
rr[x] = max(rr[x], rr[y]);
}
void build(int p=1, int l=0, int r=n-1) {
if (l == r) {
seg[p] = c;
return;
}
int mid = (l+r) >> 1;
build(p*2, l, mid);
build(p*2+1, mid+1, r);
seg[p] = min(seg[p*2], seg[p*2+1]);
}
void update(int pos, int x, int p=1, int l=0, int r=n-1) {
if (l == r) {
seg[p] = x;
return;
}
int mid = (l+r) >> 1;
if (pos <= mid) update(pos, x, p*2, l, mid);
else update(pos, x, p*2+1, mid+1, r);
seg[p] = min(seg[p*2], seg[p*2+1]);
}
int query(int x, int y, int p=1, int l=0, int r=n-1) {
if (x > y || y < l || r < x) return c;
else if (x <= l && r <= y) {
return seg[p];
}
int mid = (l+r) >> 1;
return min(query(x, y, p*2, l, mid), query(x, y, p*2+1, mid+1, r));
}
void update2(int pos, int x, int p=1, int l=0, int r=n-1) {
if (l == r) {
seg[p] += x;
return;
}
int mid = (l+r) >> 1;
if (pos <= mid) update2(pos, x, p*2, l, mid);
else update2(pos, x, p*2+1, mid+1, r);
seg[p] = seg[p*2] + seg[p*2+1];
}
int query2(int x, int y, int p=1, int l=0, int r=n-1) {
if (x > y || y < l || r < x) return c;
else if (x <= l && r <= y) {
return seg[p];
}
int mid = (l+r) >> 1;
return query2(x, y, p*2, l, mid) + query2(x, y, p*2+1, mid+1, r);
}
int GetBestPosition(int N, int C, int R, int *K, int *S, int *E) {
mx = ans = 0;
n = N;
c = C;
for (int i = 0; i < n; i++) {
p[i] = i;
sz[i] = 1;
ll[i] = rr[i] = i;
}
for (int i = 0; i < n-1; i++) {
if (K[i] > R) higher.push_back(i);
}
for (int i = 0; i < c; i++) {
int x = E[i]-S[i];
int y = S[i];
while (x--) {
y = rr[findSet(y)];
unite(y, y+1);
}
int nwR = rr[findSet(S[i])];
queries[i] = make_pair(S[i], nwR);
lp[S[i]].push_back(i);
rp[nwR].push_back(i);
}
build(); // pongo todo a c
memset(seg2, 0, sizeof(seg2));
for (int i = 0; i < n; i++) {
/*
cuantas batallas gano poniendolo en i?
miro el mas cercano por cada lado que me gana y cojo la primera query que me toca
y que llega mas lejos que ellos con query de minimo en rango
*/
for (int& j : lp[i]) {
st[i].insert(j);
st[queries[j].second].insert(j);
update(i, *st[i].begin());
update(i, *st[queries[j].second].begin());
update2(j, 1);
}
auto it = lower_bound(all(higher), i);
int x = (it == higher.begin() ? -1 : *prev(it));
int y = (it == higher.end() ? n-1 : *it) + 1;
int rd = min(query(0, x), query(y, n-1));
int nwMx = query2(0, rd-1);// rondas con idx < rd que pasan por i
if (nwMx > mx) {
mx = nwMx;
ans = i;
}
for (int& j : rp[i]) {
st[i].erase(j);
st[queries[j].first].erase(j);
update(i, (st[i].empty() ? c : *st[i].begin()));
update(i, (st[queries[j].first].empty() ? c : *st[queries[j].first].begin()));
update2(j, -1);
}
}
return ans;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |