1 条题解
-
0
自动搬运
来自洛谷,原作者为

xiezheyuan
明明我已昼夜无间踏尽前路/梦想中的彼岸为何还未到/明明我已奋力无间/天天上路/我不死也为活更好/快要到终点才能知道/又再回到起点重头上路搬运于
2025-08-24 23:00:47,当前版本为作者最后更新于2024-07-12 08:17:09,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
思路
你发现如果要考虑每个点被挖了多少格,那么至少需要 的时间复杂度,难以通过本题。
我们转而考虑挖的深度的差分数组。按照题意,差分数组的每一项只可能是 。我们不妨将 看成一个左括号, 的前一个位置看成一个右括号, 要么是不打括号,要么是一个右括号和一个左括号。
那么这些括号必须匹配。因为假如括号不匹配,那么会出现以下两种情况:
- 左括号不匹配,则最后一个位置会出现不合法的情况。
- 右括号不匹配,则会出现一个位置挖了负数格的情况。
然后对 求前缀和,就转换成了经典问题。参考 CF865D Buy Low Sell High。
但是这道题剩余部分虽然和 Buy Low Sell High 一样,但是思考起来更容易。我们发现可以打左括号的地方一定可以打右括号,要不然的话括号匹配就会出锅。所以我们维护一个堆,每次将合法的左括号丢到堆里面去,然后看这里打一个右括号是否更优即可。
时间复杂度 。
代码
#include <bits/stdc++.h> #define int long long using namespace std; const int N = 2.5e5 + 5; int n, ans, qzh[N], a[N]; priority_queue<int, vector<int>, greater<int> > pq; signed main(){ ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); cin >> n; for(int i=1;i<=n;i++) cin >> a[i]; for(int i=1;i<=n;i++) qzh[i] = qzh[i - 1] + a[i]; for(int i=1;i<=n;i++){ pq.push(qzh[i - 1]); if(qzh[i] - pq.top() > 0){ ans += qzh[i] - pq.top(); pq.pop(); pq.push(qzh[i]); } } cout << ans << '\n'; return 0; } // Written by xiezheyuan
- 1
信息
- ID
- 9331
- 时间
- 3000ms
- 内存
- 512MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者