POJ 3162 Walking Race——树形dp+尺取+线段树

来源:互联网 发布:淘宝收获日面具 编辑:程序博客网 时间:2024/06/18 14:54

RMQ蜜汁MLE??可能是写挫了,不过尺取+线段是nlogn就过了

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int INF = 0x3f3f3f3f;const int maxn = 1e6 + 10;int n, m, tot, head[maxn], dp[maxn][3], x[maxn];struct Edge {    int to, cost, next;}edge[maxn<<1];void init() {    tot = 0;    memset(head, -1, sizeof(head));}void addedge(int u, int v, int cost) {    ++tot;    edge[tot].to = v, edge[tot].cost = cost, edge[tot].next = head[u];    head[u] = tot;}void dfs1(int u, int p) {    for (int i = head[u]; i != -1; i = edge[i].next) {        int v = edge[i].to;        if (v == p) continue;        dfs1(v, u);    }    int pos = 0;    for (int i = head[u]; i != -1; i = edge[i].next) {        int v = edge[i].to, cost = edge[i].cost;        if (v == p) continue;        if (dp[u][0] < dp[v][0] + cost) {            dp[u][0] = dp[v][0] + cost;            pos = v;        }    }    for (int i = head[u]; i != -1; i = edge[i].next) {        int v = edge[i].to, cost = edge[i].cost;        if (v == p || v == pos) continue;        dp[u][1] = max(dp[u][1], dp[v][0] + cost);    }}void dfs2(int u, int p) {    for (int i = head[u]; i != -1; i = edge[i].next) {        int v = edge[i].to, cost = edge[i].cost;        if (v == p) continue;        dp[v][2] = max(dp[u][2], ((dp[v][0] + cost == dp[u][0]) ? dp[u][1] : dp[u][0])) + cost;        dfs2(v, u);    }}struct SegTree {    int val[2][maxn<<2];    void pushup(int root) {        val[0][root] = max(val[0][root<<1], val[0][root<<1|1]);        val[1][root] = min(val[1][root<<1], val[1][root<<1|1]);    }    void build(int l, int r, int root) {        if (l == r) {            val[0][root] = max(dp[l][0], dp[l][2]);            val[1][root] = max(dp[l][0], dp[l][2]);            return;        }        int mid = (l + r)>>1;        build(l, mid, root<<1); build(mid + 1, r, root<<1|1);        pushup(root);    }    int query(int l, int r, int root, int ql, int qr, int index) {        if (ql <= l && r <= qr) return val[index][root];        int mid = (l + r)>>1;        int ans;        if (index == 0) ans = 0; else ans = INF;        if (ql <= mid) {            if (index == 0) {                ans = max(ans, query(l, mid, root<<1, ql, qr, index));            }            else {                ans = min(ans, query(l, mid, root<<1, ql, qr, index));            }        }        if (mid < qr) {            if (index == 0) {                ans = max(ans, query(mid + 1, r, root<<1|1, ql, qr, index));            }            else {                ans = min(ans, query(mid + 1, r, root<<1|1, ql, qr, index));            }        }        return ans;    }}segtree;int solve() {    for (int i = 1; i <= n; i++) x[i] = max(dp[i][0], dp[i][2]);    int l = 1, r = 0, maxv = 0, minv = INF, ans = 0;    for (int i = 1; i <= n; i++) {        r++;        maxv = max(maxv, x[i]), minv = min(minv, x[i]);        while (l  <= r && maxv - minv > m) {            l++;            maxv = segtree.query(1, n, 1, l, r, 0);            minv = segtree.query(1, n, 1, l, r, 1);        }        ans = max(ans, r - l + 1);    }    return ans;}int main() {    int v, cost;    while (~scanf("%d %d", &n, &m)) {        init();        for (int i = 1; i <= n - 1; i++) {            scanf("%d %d", &v, &cost);            addedge(i + 1, v, cost); addedge(v, i + 1, cost);        }        memset(dp, 0, sizeof(dp));        dfs1(1, -1);        dfs2(1, -1);        segtree.build(1, n, 1);        printf("%d\n", solve());    }    return 0;}


原创粉丝点击