[Luogu] P3431 POI2005 AUT - The Bus
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\n", ans);
return 0;
}