# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
1107329 | qwerasdfzxcl | Tortoise (CEOI21_tortoise) | C++17 | 0 ms | 0 KiB |
This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
constexpr int INF = 1e9 + 100;
int a[500500];
struct Seg {
int tree[2002000], lazy[2002000];
void init(int i, int l, int r, const vector<int> &V) {
lazy[i] = 0;
if (l==r) {tree[i] = V[l]; return;}
int m = (l+r)/2;
init(i<<1, l, m, V);
init(i<<1|1, m+1, r, V);
tree[i] = min(tree[i<<1], tree[i<<1|1]);
}
void propagate(int i, int l, int r) {
tree[i] += lazy[i];
if (l!=r) lazy[i<<1] += lazy[i], lazy[i<<1|1] += lazy[i];
lazy[i] = 0;
}
void update(int i, int l, int r, int s, int e, int x) {
propagate(i, l, r);
if (r<s || e<l) return;
if (s<=l && r<=e) {
lazy[i] += x;
propagate(i, l, r);
return;
}
int m = (l+r)/2;
update(i<<1, l, m, s, e, x);
update(i<<1|1, m+1, r, s, e, x);
tree[i] = min(tree[i<<1], tree[i<<1|1]);
}
int query(int i, int l, int r, int s, int e) {
propagate(i, l, r);
if (r<s || e<l) return INF;
if (s<=l && r<=e) return tree[i];
int m = (l+r)/2;
return min(query(i<<1, l, m, s, e), query(i<<1|1, m+1, r, s, e));
}
}tree;
int main() {
int n;
scanf("%d", &n);
for (int i=1;i<=n;i++) scanf("%d", a+i);
a[0] = a[n+1] = -1;
ll ans = 0;
for (int i=1;i<=n;i++) ans += max(a[i], 0);
if (ans==0) {
printf("0\n");
return 0;
}
priority_queue<array<int, 3>, vector<array<int, 3>>, greater<array<int, 3>>> pq;
vector<int> V;
for (int i=0,j=0;i<=n;i=j) {
if (a[i]!=-1){j = i+1; continue;}
j = i+1;
while(j <= n && a[j]!=-1) j++;
int ti = i==0?-INF:i, tj = j==n+1?INF:j;
int r = -1, mx = -1, idx = -1;
for (int k=i+1;k<j;k++) if (a[k] > 0) {
r = k;
if (mx < min(k-ti, tj-k)) {
mx = min(k-ti, tj-k);
idx = k;
}
}
if (r < 0) continue;
V.push_back(r-1);
ans--;
for (int k=i+1;k<j;k++) if (a[k] > 0){
int c = k==idx?a[k]-1:a[k];
if (c==0) continue;
if (k-ti <= tj-k) pq.push({k-ti, (int)V.size()-1, c});
else pq.push({tj-k, (int)V.size()-1, c});
}
}
int sz = V.size();
tree.init(1, 0, sz-1, V);
while(!pq.empty()) {
auto [w, i, c] = pq.top(); pq.pop();
if (tree.query(1, 0, sz-1, i, sz-1) < w*2) continue;
ans--;
tree.update(1, 0, sz-1, i, sz-1, -w*2);
if (c > 1) pq.push({w, i, c-1});
}
printf("%lld\n", ans);
}