树链剖分

来源:互联网 发布:淘宝评价好评怎么修改 编辑:程序博客网 时间:2024/06/05 14:58

1、HDU 5052 Yaoge’s maximum profit


#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <queue>#include <vector>#include <stack>#include <map>#include <set>#include <cmath>#include <cctype>#include <bitset>#include <ctime>using namespace std;#define REP(i, n) for (int i = 0; i < (n); ++i)#define lson low, mid, _id<<1#define rson mid+1, high, _id<<1|1typedef long long ll;typedef unsigned long long ull;typedef unsigned int uint;typedef pair<int, int> Pair;const ull mod = 1e9 + 7;const int INF = 0x7fffffff;const int maxn = 5e4 + 10;int T, N, Q, X, Y, Z, edge, id_count;int W[maxn], depth[maxn], son[maxn], top[maxn], size[maxn], father[maxn], id[maxn], key[maxn];int head[maxn], Next[2*maxn], to[2*maxn];ll lans[4*maxn], rans[4*maxn], lazy[4*maxn], Max[4*maxn], Min[4*maxn];void Init(void);void add_edge(int u, int v);void dfs_first(int u, int _father, int _depth);void dfs_second(int u, int _top);void build(int low, int high, int _id);void push_up(int _id);void update(int Left, int Right, ll val, int low, int high, int _id);void push_down(int _id);void Update(int u, int v, ll val);ll slove(int u, int v);ll query(int Left, int Right, int is_left, ll& max_price, ll& min_price, int low, int high, int _id);int main(){#ifdef __AiR_H    freopen("in.txt", "r", stdin);#endif // __AiR_H    scanf("%d", &T);    while (T--) {        scanf("%d", &N);        Init();        for (int i = 1; i <= N; ++i) {            scanf("%d", &W[i]);        }        for (int i = 1; i < N; ++i) {            scanf("%d %d", &X, &Y);            add_edge(X, Y), add_edge(Y, X);        }        dfs_first(1, 0, 1);        dfs_second(1, 1);        build(1, N, 1);        scanf("%d", &Q);        while (Q--) {            scanf("%d %d %d", &X, &Y, &Z);            printf("%I64d\n", slove(X, Y));            Update(X, Y, Z);        }    }    return 0;}ll slove(int u, int v){    ll ans = 0, max_now_left, min_now_left, max_now_right, min_now_right;    ll max_pre_left = 0, min_pre_left = Max[1], max_pre_right = 0, min_pre_right = Max[1];    while (top[u] != top[v]) {        if (depth[top[u]] > depth[top[v]]) {            ans = max(ans, query(id[top[u]], id[u], 1, max_now_left, min_now_left, 1, N, 1));            ans = max(ans, max_now_left - min_pre_left);            ans = max(ans, max_pre_right - min_now_left);            max_pre_left = max(max_pre_left, max_now_left);            min_pre_left = min(min_pre_left, min_now_left);            u = father[top[u]];        } else {            ans = max(ans, query(id[top[v]], id[v], 0, max_now_right, min_now_right, 1, N, 1));            ans = max(ans, max_pre_right - min_now_right);            ans = max(ans, max_now_right - min_pre_left);            max_pre_right = max(max_pre_right, max_now_right);            min_pre_right = min(min_pre_right, min_now_right);            v = father[top[v]];        }    }    if (depth[u] > depth[v]) {        ans = max(ans, query(id[v], id[u], 1, max_now_left, min_now_left, 1, N, 1));        ans = max(ans, max_now_left - min_pre_left);        min_pre_left = min(min_pre_left, min_now_left);        ans = max(ans, max_pre_right - min_pre_left);    } else {        ans = max(ans, query(id[u], id[v], 0, max_now_right, min_now_right, 1, N, 1));        ans = max(ans, max_pre_right - min_now_right);        max_pre_right = max(max_pre_right, max_now_right);        ans = max(ans, max_pre_right - min_pre_left);    }    return ans;}ll query(int Left, int Right, int is_left, ll& max_price, ll& min_price, int low, int high, int _id){    if (low == Left && high == Right) {        max_price = Max[_id], min_price = Min[_id];        if (is_left) {            return lans[_id];        } else {            return rans[_id];        }    }    push_down(_id);    int mid = (low + high) >> 1;    if (Right <= mid) {        return query(Left, Right, is_left, max_price, min_price, lson);    } else if (Left > mid) {        return query(Left, Right, is_left, max_price, min_price, rson);    } else {        ll ans_t, max_left, max_right, min_left, min_right;        ll ans = max(query(Left, mid, is_left, max_left, min_left, lson), query(mid+1, Right, is_left, max_right, min_right, rson));        if (is_left) {            ans_t = max_left - min_right;        } else {            ans_t = max_right - min_left;        }        max_price = max(max_left, max_right), min_price = min(min_left, min_right);        ans_t = max(ans_t, 0ll), ans = max(ans, ans_t);        return ans;    }}void Update(int u, int v, ll val){    while (top[u] != top[v]) {        if (depth[top[u]] < depth[top[v]]) {            swap(u, v);        }        update(id[top[u]], id[u], val, 1, N, 1);        u = father[top[u]];    }    if (depth[u] > depth[v]) {        swap(u, v);    }    update(id[u], id[v], val, 1, N, 1);}void update(int Left, int Right, ll val, int low, int high, int _id){    if (low == Left && high == Right) {        Max[_id] += val, Min[_id] += val, lazy[_id] += val;        return;    }    push_down(_id);    int mid = (low + high) >> 1;    if (Right <= mid) {        update(Left, Right, val, lson);    } else if (Left > mid) {        update(Left, Right, val, rson);    } else {        update(Left, mid, val, lson), update(mid+1, Right, val, rson);    }    push_up(_id);}void push_down(int _id){    if (lazy[_id]) {        Max[_id<<1] += lazy[_id], Min[_id<<1] += lazy[_id], lazy[_id<<1] += lazy[_id];        Max[_id<<1|1] += lazy[_id], Min[_id<<1|1] += lazy[_id], lazy[_id<<1|1] += lazy[_id];        lazy[_id] = 0;    }}void build(int low, int high, int _id){    lazy[_id] = lans[_id] = rans[_id] = 0;    if (low == high) {        Max[_id] = Min[_id] = W[key[low]];        return;    }    int mid = (low + high) >> 1;    build(lson), build(rson);    push_up(_id);}void push_up(int _id){    Max[_id] = max(Max[_id<<1], Max[_id<<1|1]), Min[_id] = min(Min[_id<<1], Min[_id<<1|1]);    lans[_id] = max(Max[_id<<1] - Min[_id<<1|1], max(lans[_id<<1], lans[_id<<1|1]));    rans[_id] = max(Max[_id<<1|1] - Min[_id<<1], max(rans[_id<<1], rans[_id<<1|1]));    if (lans[_id] < 0) {        lans[_id] = 0;    }    if (rans[_id] < 0) {        rans[_id] = 0;    }}void dfs_second(int u, int _top){top[u] = _top;id[u] = ++id_count;key[id[u]] = u;if (son[u] == -1) {return;}dfs_second(son[u], _top);for (int i = head[u]; ~i; i = Next[i]) {int v = to[i];if (v != son[u] && v != father[u]) {dfs_second(v, v);}}}void dfs_first(int u, int _father, int _depth){depth[u] = _depth, father[u] = _father, size[u] = 1;for (int i = head[u]; ~i; i = Next[i]) {int v = to[i];if (v != _father) {dfs_first(v, u, _depth+1);size[u] += size[v];if (son[u] == -1 || size[v] > size[son[u]]) {son[u] = v;}}}}void add_edge(int u, int v){to[edge] = v, Next[edge] = head[u], head[u] = edge++;}void Init(void){memset(head, -1, sizeof(head));memset(son, -1, sizeof(son));edge = id_count = 0;}


0 0
原创粉丝点击