设 为仅考虑前 个位置的答案。
为 区间和, 为完全在 中的演出收益和。
做一个扫描线(或者叫线段树优化 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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?