「题解」洛谷 P7867 「EVOI-RD1」马戏团
设 \(f_i\) 为仅考虑前 \(i\) 个位置的答案。
\(f_i=\max\{f_j-sum(j+1,i)+calc(j+1,i),f_{i-1}\}\)
\(sum(j+1,i)\) 为 \(c\) 区间和,\(calc(i,j)\) 为完全在 \([i,j]\) 中的演出收益和。
做一个扫描线(或者叫线段树优化 dp)即可解决。
#include<iostream>
#include<cstdio>
#include<vector>
#include<set>
#include<algorithm>
#define pb push_back
#define mp std::make_pair
#define fir first
#define sec second
typedef std::pair<int, int> pii;
typedef std::vector<int> veci;
typedef std::vector<pii> vecpii;
typedef long long ll;
ll Abs(ll x) { return x < 0 ? -x : x; }
ll Max(ll x, ll y) { return x > y ? x : y; }
template <typename T>
T& read(T& r) {
r = 0; bool w = 0; char ch = getchar();
while(ch < '0' || ch > '9') w = ch == '-' ? 1 : 0, ch = getchar();
while(ch >= '0' && ch <= '9') r = r * 10 + (ch ^ 48), ch = getchar();
return r = w ? -r : r;
}
const int N = 2000100;
int n, m;
ll c[N], f[N];
#define ls tree[x].lson
#define rs tree[x].rson
#define tl tree[x].l
#define tr tree[x].r
int trnt;
struct SGT {
int l, r, lson, rson;
ll mx, tag;
}tree[N << 1];
inline void pushup(int x) { tree[x].mx = Max(tree[ls].mx, tree[rs].mx); }
inline void pushdown(int x) {
if(tree[x].tag) {
ll p = tree[x].tag;
tree[ls].mx += p; tree[rs].mx += p;
tree[ls].tag += p; tree[rs].tag += p;
tree[x].tag = 0;
}
}
int build(int l, int r) {
int x = ++trnt;
tl = l; tr = r;
if(l == r) return x;
ls = build(l, (l+r)>>1); rs = build(tree[ls].r+1, r);
pushup(x); return x;
}
void modify(int x, int l, int r, ll v) {
if(tl >= l && tr <= r) {
tree[x].mx += v;
tree[x].tag += v;
return ;
}
int mid = (tree[x].l + tree[x].r) >> 1;
pushdown(x);
if(mid >= l) modify(ls, l, r, v);
if(mid < r) modify(rs, l, r , v);
pushup(x);
}
ll query(int x, int l, int r) {
if(tl >= l && tr <= r) return tree[x].mx;
int mid = (tree[x].l + tree[x].r) >> 1; ll sumq = 0;
pushdown(x);
if(mid >= l) sumq = Max(sumq, query(ls, l, r));
if(mid < r) sumq = Max(sumq, query(rs, l, r));
pushup(x);
return sumq;
}
void Modify(int l, int r, ll v) { modify(1, l+1, r+1, v); }
ll Query(int l, int r) { return query(1, l+1, r+1); }
#undef ls
#undef rs
#undef tl
#undef tr
struct Node {
int l, r;
ll v;
}q[N];
bool cmp(Node x, Node y) {
return x.r < y.r;
}
signed main() {
read(n); read(m);
for(int i = 1; i <= n; ++i) read(c[i]);
build(1, n+1);
for(int i = 1; i <= m; ++i) read(q[i].l), read(q[i].r), read(q[i].v);
std::sort(q + 1, q + m + 1, cmp);
int top = 1;
for(int i = 1; i <= n; ++i) {
Modify(0, i-1, -c[i]);
while(q[top].r == i && top <= m) {
Modify(0, q[top].l-1, q[top].v);
++top;
}
f[i] = Query(0, i-1);
f[i] = Max(f[i], f[i-1]);
Modify(i, i, f[i]);
}
printf("%lld\n", f[n]);
return 0;
}