Luogu P3431 POI2005 AUT - The Bus
因为公交车只能往北或者往南走,所以先按(X)坐标排个序,固定(X)坐标顺序。接下来再考虑(Y)坐标。设(F[i](1 leqslant i leqslant k))为选到第(i)个节点时的最大值。因为(X)坐标已经有序,所以(F[i] = max(f[j]) + a[i]),其中(j.Y leqslant i.Y)。如此,可用一个数据结构维护(j.Y leqslant i.Y)中(j)节点(F[j])的最大值。当然,(j)当然是(leqslant i)的。
#include <algorithm>
#include <cstdio>
const int MAXN = 100001;
struct node{
int x, y, v;
bool operator < (const node &a) const{
if(a.x == x) {return y < a.y;}
return x < a.x;
}
}a[MAXN];
struct spread{
int y, id;
bool operator < (const spread &a) const{
return y < a.y;
}
}b[MAXN];
int n, m, k, cnt, ans;
int c[MAXN], f[MAXN];
inline int lowbit(int x) {return x & (-x);}
inline void update(int bgn, int x) {
int iter(bgn);
while(iter <= cnt) {
c[iter] = std::max(c[iter], x);
iter = iter + lowbit(iter);
}
return ;
}
inline int query(int end) {
int iter(end), ans(0);
while(iter) {
ans = std::max(c[iter], ans);
iter = iter - lowbit(iter);
}
return ans;
}
int main() {
scanf("%d%d%d", &n, &m, &k);
for (int i = 1; i <= k; ++i)
scanf("%d%d%d", &a[i].x, &b[i].y, &a[i].v), b[i].id = i;
std::sort(b + 1, b + k + 1);
for (int i = 1; i <= k; ++i) {
if(b[i].y != b[i - 1].y) cnt++;
a[b[i].id].y = cnt;
}
std::sort(a + 1, a + k + 1);
for (int i = 1; i <= k; ++i) {
f[i] = a[i].v + query(a[i].y);
update(a[i].y, f[i]);
ans = std::max(f[i], ans);
}
printf("%d
", ans);
return 0;
}