[Luogu] P3431 POI2005 AUT

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;
}
原文地址:https://www.cnblogs.com/manziqi/p/8487410.html