【思路要点】
- 较为简单的模拟费用流问题。
- 可以参考 W C 2019 WC2019 WC2019 第一课堂陈江伦的《模拟费用流问题》课件。
- 时间复杂度 O ( N L o g N ) O(NLogN) O(NLogN) 。
【代码】
#include<bits/stdc++.h> using namespace std; const int MAXN = 2e5 + 5; const long long INF = 1e18; typedef long long ll; typedef long double ld; typedef unsigned long long ull; template <typename T> void chkmax(T &x, T y) {x = max(x, y); } template <typename T> void chkmin(T &x, T y) {x = min(x, y); } template <typename T> void read(T &x) { x = 0; int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; x *= f; } template <typename T> void write(T x) { if (x < 0) x = -x, putchar('-'); if (x > 9) write(x / 10); putchar(x % 10 + '0'); } template <typename T> void writeln(T x) { write(x); puts(""); } int n, cost[MAXN]; ll pos[MAXN]; priority_queue <ll, vector <ll>, greater <ll>> Dest, From; int main() { read(n); for (int i = 2; i <= n; i++) read(pos[i]), pos[i] += pos[i - 1]; for (int i = 1; i <= n; i++) read(cost[i]); __int128 ans = n; ans *= INF; for (int i = 1; i <= n; i++) { if (!From.empty() && -INF + pos[i] + From.top() < 0) { ans += -INF + pos[i] + From.top(); ll y = From.top(); From.pop(); From.push(INF - pos[i]); Dest.push(-y - 2 * pos[i]); } else Dest.push(-INF - pos[i]); for (int j = 1; j <= 2; j++) { if (!Dest.empty() && cost[i] + pos[i] + Dest.top() < 0) { ans += cost[i] + pos[i] + Dest.top(); ll y = Dest.top(); Dest.pop(); Dest.push(-cost[i] - pos[i]); From.push(-y - 2 * pos[i]); } else From.push(cost[i] - pos[i]); } } writeln(ans); return 0; }