题解:P11598 [NOISG 2018 Finals] Safety
Loyal_Soldier · · 题解
思路
设
答案就是
显然,
我们考虑使用 slope trick 优化。
对于一个分段下凸函数
- 如果
x < L ,斜率为负。 - 如果
x\in [L, R] ,斜率为0 。 - 如果
x > R ,斜率为正。
那么对于本题,我们维护两个拐点集合
那么对于取
对拐点的影响就是负斜率拐点向右移动
对于绝对值操作,就是在
对拐点的影响就是往
考虑使用一个大根堆维护
但是我们不便每次操作
设
代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN = 3e5 + 10;
int n, H, h[MAXN];
int ans, lzy;
priority_queue <int> a;
priority_queue <int, vector <int>, greater <int> > b;
signed main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> n >> H;
int ans = 0;
for (int i = 1; i <= n; i++) {
cin >> h[i];
lzy += H;
a.push(h[i] + lzy);
b.push(h[i] - lzy);
int x = a.top() - lzy, y = b.top() + lzy;
while (x > y) {
a.pop(), b.pop();
ans += abs(x - y);
a.push(y + lzy);
b.push(x - lzy);
x = a.top() - lzy, y = b.top() + lzy;
}
}
cout << ans << '\n';
return 0;
}