Original link:https://www.shuizilong.com/house/archives/codeton-round-5/

Problem E. Tenzing and Triangle
As long as you can write violent dp, you will be 90% successful!
Might as well add up all the points first and consider how much you can optimally save by covering. A useful property that we have found is that the areas covered by the triangles need not overlap, and thus seem to allow simple 1D/1D dynamic programming.
Here we use a tree array, which can maintain the cost of the triangle coverage area.
#include <lastweapon/io>
#include <lastweapon/fenwicktree>
using namespace lastweapon;
const int N = int(2e5) + 9;
int n, k, A; vector<PII> P[N]; LL f[N];
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("/Users/minakokojima/Documents/GitHub/ACM-Training/Workspace/out.txt", "w", stdout);
#endif
RD(n,k,A); LL z = 0;
REP(i,n) {
int x, y, c; RD(x, y, c);
z += c; P[kx].PB({y, c});
}
fenwick_tree<int> T(k+1);
REP(i, k+1) {
for (auto p: P[i]) T.add(p.fi, p.se);
checkMax(f[i], (LL)T. sum(0, i+1) - A*i);
REP(j, i) checkMax(f[i], f[j] + T.sum(j+1, i+1) - A*(ij-1));
}
cout << z - f[k] << endl;
}
Further, we put this transfer and separation into the line segment tree to find rmq.
#include <lastweapon/io>
using namespace lastweapon;
const int N = int(2e5) + 9;
const int NN = 4*N;
int n, k, A; vector<PII> P[N]; int f[N];
struct SegTree {
#define lx (x<<1)
#define rx(lx|1)
#define ml ((l+r)>>1)
#define mr (ml+1)
#define lc lx,l,ml
#define rc rx,mr,r
#define rt 1,0,k
int T[NN], D[NN];
void add(int x, int d) {
D[x] += d;
T[x] += d;
}
void rls(int x) {
//return;
if (D[x]) {
add(lx, D[x]);
add(rx, D[x]);
D[x] = 0;
}
}
void upd(int x) {
T[x] = max(T[lx], T[rx]);
}
void Build(int x, int l, int r) {
if (l == r) {
T[x] = A*l;
} else {
Build(lc);
Build(rc);
upd(x);
}
}
int Add(int x, int l, int r, const int p, const int d) {
if (l == r) {
T[x] += d;
} else {
rls(x);
if (p < mr) Add(lc, p, d);
else Add(rc, p, d);
upd(x);
}
}
void Add(int x, int l, int r, const int a, const int b, const int d) {
if (b < l || r < a) return;
if (a <= l && r <= b) {
add(x, d);
} else {
rls(x);
Add(lc, a, b, d);
Add(rc, a, b, d);
upd(x);
}
}
int Query(int x, int l, int r, const int a, const int b) {
if (b < l || r < a) return 0;
if (a <= l && r <= b) {
return T[x];
} else {
rls(x);
return max(Query(lc, a, b), Query(rc, a, b));
}
}
} T;
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("/Users/minakokojima/Documents/GitHub/ACM-Training/Workspace/out.txt", "w", stdout);
#endif
RD(n,k,A); int z = 0; REP(i, n) {
int x, y, c; RD(x, y, c); z += c;
P[kx].PB({y, c});
}
T.Build(rt);
REP(i, k+1) {
if (i) T.Add(rt, i, f[i-1]);
for (auto p: P[i]) T.Add(rt, 0, p.fi, p.se);
checkMax(f[i], T.Query(rt, 0, i) - A*i);
}
cout << z - f[k] << endl;
}
This article is transferred from:https://www.shuizilong.com/house/archives/codeton-round-5/
This site is only for collection, and the copyright belongs to the original author.