# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
254272 | karma | 휴가 (IOI14_holiday) | C++14 | 0 ms | 0 KiB |
이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
#define pb emplace_back
#define ll long long
#define fi first
#define se second
#define mp make_pair
#define int int64_t
using namespace std;
const int N = int(1e5) + 7;
typedef pair<ll, int> pii;
pii operator + (const pii& x, const pii& y) {
return pii(x.fi + y.fi, x.se + y.se);
}
struct TSegment {
vector<int> l, h;
vector<pii> st;
TSegment() {}
void init(int n) {
l.resize(4 * n + 4);
h.resize(l.size());
st.resize(l.size());
build(1, 0, n - 1);
}
void reset() {
fill(st.begin(), st.end(), pii(0, 0));
}
void build(int x, int low, int high) {
l[x] = low, h[x] = high, st[x] = pii(0, 0);
if(l[x] == h[x]) return;
int mid = low + high >> 1;
build(x << 1, low, mid);
build(x << 1 | 1, mid + 1, high);
}
void upd(int x, int pos, int val, int s) {
if(l[x] > pos || h[x] < pos) return;
if(l[x] == h[x]) {
st[x].fi += val;
st[x].se += s;
return;
}
upd(x << 1, pos, val, s);
upd(x << 1 | 1, pos, val, s);
st[x] = st[x << 1] + st[x << 1 | 1];
}
ll get(int x, int k) {
if(k < 0) return 0;
if(k >= st[x].se) return st[x].fi;
if(l[x] == h[x]) return 0;
if(st[x << 1].se >= k) return get(x << 1, k);
return st[x << 1].fi + get(x << 1 | 1, k - st[x << 1].se);
}
} it;
const int M = 3 * N;
ll f[2][M], g[2][M];
int s;
vector<int> id, pos, val;
int L = -1, R = -1;
pair<ll, ll> cost(int d, int l, int r) {
if(L == -1 && R == -1) L = l, R = L - 1;
while(L < l) it.upd(1, pos[L], -val[L], -1), ++L;
while(L > l) --L, it.upd(1, pos[L], val[L], 1);
while(R > r) it.upd(1, pos[R], -val[R], -1), --R;
while(R < r) ++R, it.upd(1, pos[R], val[R], 1);
return mp(it.get(1, d - r + l), it.get(1, d - 2 * (r - l)));
}
void dp(int cur, int l, int r, int optl, int optr) {
if(l > r || optl > optr) return;
int m = l + r >> 1, optm = optl;
ll cf, cg;
f[cur][m] = 0, g[cur][m] = 0;
for(int i = optl; i <= optr; ++i) {
tie(cf, cg) = cost(m, s, i);
if(cf > f[cur][m]) optm = i, f[cur][m] = cf;
if(cg > g[cur][m]) g[cur][m] = cg;
}
dp(cur, l, m - 1, optl, optm);
dp(cur, m + 1, r, optm, optr);
}
void dpg(int cur, int l, int r, int optl, int optr) {
if(l > r || optl > optr) return;
int m = l + r >> 1, optm = optl;
ll cf, cg;
g[cur][m] = 0;
for(int i = optl; i <= optr; ++i) {
tie(cf, cg) = cost(m, s, i);
if(cg > g[cur][m]) optm = i, g[cur][m] = cg;
}
dpg(cur, l, m - 1, optl, optm);
dpg(cur, m + 1, r, optm, optr);
}
ll findMaxAttraction(int n, int start, int d, int attraction[]) {
val.resize(n); pos.resize(n);
id.resize(n); iota(id.begin(), id.end(), 0);
copy(attraction, attraction + n, val.begin());
sort(id.begin(), id.end(), [&](const int& x, const int& y) {
return val[x] > val[y];
});
for(int i = 0; i < n; ++i) pos[id[i]] = i;
it.init(n);
s = start + 1; dp(0, 0, d, s, n - 1);
dpg(0, 0, d, s, n - 1);
for(int i = n - 1; i >= 0; --i) val[i] = attraction[n - i - 1];
sort(id.begin(), id.end(), [&](const int& x, const int& y) {
return val[x] > val[y];
});
for(int i = 0; i < n; ++i) pos[id[i]] = i;
it.reset(); L = R = -1;
s = n - start - 1; dp(1, 0, d, s, n - 1);
dpg(1, 0, d, s, n - 1);
ll res = max(f[0][d - 1], f[1][d]);
for(int i = 0; i <= d; ++i){
if(d - i - 2 >= 0) {
res = max(res, g[0][i] + f[1][d - i - 2]);
}
if(d - i - 1 >= 0) res = max(res, f[0][i] + g[1][d - i - 1]);
}
return res;
}
//int a[N];
//
//int32_t main() {
// ios_base::sync_with_stdio(0);
// cin.tie(0), cout.tie(0);
// #define Task "test"
// if(fopen(Task".inp", "r")) {
// freopen(Task".inp", "r", stdin);
// freopen(Task".out", "w", stdout);
// }
// int n, start, d;
// cin >> n >> start >> d;
// for(int i = 0; i < n; ++i) cin >> a[i];
// cout << findMaxAttraction(n, start, d, a);
//}