Man Down problem solving report (hdu3016 dynamic planning line segment tree sorting)
Algorithm design
Sample code
# include <cstdio>
# include <cstring>
# include <algorithm>
const int N = one hundred and ten thousand , L = one hundred and ten thousand , INF = 0x7fffffff ; int n; struct a_d { int h, l, r, v; int ld, rd; // left down to } a[N]; inline bool cmp (a_d a, a_d b) { return a.h < b.h; } struct node { int l, r; int f; node *lc, *rc; } mem[ two * L]; node *memp; node *root; node * init ( int l, int r) { node *p = memp++; p->l = l; p->r = r; p->f = zero ; if (l == r) { p->lc = p->rc = NULL ; } else { int mid = (l + r) >> one ; p->lc = init (l, mid); p->rc = init (mid + one , r); } return p; } inline void push_down (node *p) { if (p->f) { p->lc->f = p->f; p->rc->f = p->f; p->f = zero ; } } void change (node *p, int l, int r, int f) { if (l <= p->l && p->r <= r) { p->f = f; return ; } push_down (p); int mid = (p->l + p->r) >> one ; if (l <= mid) change (p->lc, l, r, f); if (mid < r) change (p->rc, l, r, f); } int query (node *p, int i) { if (i == p->l && p->r == i) { return p->f; } push_down (p); int mid = (p->l + p->r) >> one ; if (i <= mid) return query (p->lc, i); return query (p->rc, i); } int d[N]; inline int max ( int a, int b) { if (a > b) return a; else return b; } int main () { // freopen("input.txt", "r", stdin);
while ( scanf ( "%d" , &n) != EOF) { for ( int i = one ; i <= n; ++ i) scanf ( "%d%d%d%d" , &a[i].h, &a[i].l, &a[i].r, &a[i].v); a[ zero ].v = zero ; std:: sort (a + one , a + n + one , cmp); //
// for (int i = 1; i <= n; ++i) printf("%d %d %d\n", i, a[i].l, a[i].r); printf("\n"); memp = mem; root = init ( zero , one hundred thousand and ten ); for ( int i = one ; i <= n; ++ i) { // printf("%d %d %d\n", i, a[i].l, a[i].r); a[i].ld = query (root, a[i].l); //Note that there is no+1 - 1 a[i].rd = query (root, a[i].r); change (root, a[i].l, a[i].r, i); } //
// for (int i = 1; i <= n; ++i) printf("%d %d %d\n", i, a[i].ld, a[i].rd);
for ( int i = zero ; i <= n; ++ i) d[i] = -INF; d[n] = one hundred + a[n].v; for ( int i = n; i; -- i) { if (d[i] <= zero ) continue ; d[a[i].ld] = max (d[a[i].ld], d[i] + a[a[i].ld].v); d[a[i].rd] = max (d[a[i].rd], d[i] + a[a[i].rd].v); } if (d[ zero ] > zero ) printf ( "%d\n" , d[ zero ]); else printf ( "-1\n" ); } return zero ; }