# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
331008 | Kujoh | 휴가 (IOI14_holiday) | C++17 | 0 ms | 0 KiB |
이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
/** Kujoh **/
#include <bits/stdc++.h>
#define fi first
#define se second
#define FOR(i,a,b) for(int i = a; i <= b; i++)
#define pb push_back
#define taskname "holiday"
#define fastio ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1e5 + 7;
struct Data{
int l, r, from, to;
};
int n, start, d;
ll a[N];
ll b[N];
int pos[N];
ll fL[3 * N], fR[3 * N];
pii gL[3 * N], gR[3 * N];
pair<ll, int> st[4 * N];
void update(int id, int l, int r, int i, ll val){
if(l == r){
st[id] = {val, 1};
}
else{
int mid = (l + r) / 2;
if(i <= mid) update(id * 2, l, mid, i, val);
else update(id * 2 + 1, mid + 1, r, i, val);
st[id].fi = st[id * 2].fi + st[id * 2 + 1].fi;
st[id].se = st[id * 2].se + st[id * 2 + 1].se;
}
}
ll get(int id, int l, int r, int re){
if(re == st[id].se) return st[id].fi;
if(re == 0) return 0;
int mid = (l + r) / 2;
if(st[id * 2].se >= re) return get(id * 2, l, mid, re);
else{
return st[id * 2].fi + get(id * 2 + 1, mid + 1, r, re - st[id * 2].se);
}
}
void Prepare(int id){
vector<Data> curLevels, nextLevels;
curLevels.pb({1, d, start, n});
while(!curLevels.empty()){
FOR(i, 1, 4 * N - 1) st[i] = {0, 0};
int st = start;
int cur = 0;
for(auto p : curLevels){
ll val = 0;
int cnt = n;
int mid = (p.l + p.r) / 2;
int best = p.to;
for(; st <= p.to; st++){
if(st > cur) update(1, 1, n, pos[st], a[st]);
cur = max(cur, st);
int remain = mid - (st - start);
if(remain < 0) break;
remain = min(remain, st - start + 1);
ll tmp = get(1, 1, n, remain);
if(tmp > val){
val = tmp;
best = st;
cnt = remain;
}
}
st--;
if(id)fR[mid] = val;
else fL[mid] = val;
if(id)gR[mid] = {best - start, cnt};
else gL[mid] = {best - start, cnt};
if(mid > p.l) nextLevels.pb({p.l, mid - 1, p.from, best});
if(mid < p.r) nextLevels.pb({mid + 1, p.r, best, p.to});
}
curLevels = nextLevels;
nextLevels.clear();
}
}
int main()
{
fastio;
//freopen(taskname".inp", "r", stdin);
//freopen(taskname".out", "w", stdout);
cin >> n >> start >> d;
start++;
FOR(i, 1, n){
cin >> a[i];
b[i] = i;
}
sort(b + 1, b + n + 1, [](int i, int j){
return a[i] > a[j];
});
FOR(i, 1, n) pos[b[i]] = i;
Prepare(1);
if(start == 1){
cout << fR[d];
return 0;
}
else{
start = n - start + 1;
reverse(a + 1, a + n + 1);
FOR(i, 1, n) b[i] = i;
sort(b + 1, b + n + 1, [](int i, int j){
return a[i] > a[j];
});
FOR(i, 1, n) pos[b[i]] = i;
start++;
Prepare(0);
}
ll res = max(fL[d - 1], fR[d]);
FOR(i, 1, d){
int pos = gR[i].fi;
int re = d - 2 * pos - 1 - gR[i].se;
if(re > 0)res = max(res, fR[i] + fL[re]);
if(i > 1){
pos = gL[i - 1].fi;
re = d - 2 * pos - 2 - gL[i - 1].se;
if(re > 0) res = max(res, fL[i - 1] + fR[re]);
}
}
cout << res;
return 0;
}