[hdu 3966 Aragorn's Story] 点权树链剖分

来源:互联网 发布:网络吐槽节目排行榜 编辑:程序博客网 时间:2024/04/29 11:09

[hdu 3966 Aragorn’s Story] 点权树链剖分

题目链接:[hdu 3966 Aragorn’s Story]
题意描述: 给定一个N个点的树,以及树上的点对应的初始权值。接下来有P次操作,操作一:将顶点u到顶点v的路径上的所有点权±x,操作二:求顶点u上的权值。
解题思路:点权的树链剖分以及区间更新和单点求值。

/****************************>>>>HEADFILES<<<<****************************/#include <set>#include <map>#include <list>#include <cmath>#include <queue>#include <vector>#include <cstdio>#include <string>#include <cstring>#include <iomanip>#include <iostream>#include <sstream>#include <algorithm>using namespace std;/****************************>>>>>DEFINE<<<<<*****************************/#define fst             first#define snd             second#define root            1, N, 1#define lson            l, mid, (rt << 1)#define rson            mid + 1, r, (rt << 1 | 1)#define __mid__         int mid = (l + r) >> 1#define PB(a)           push_back(a)#define MP(a,b)         make_pair(a,b)#define FIN             freopen("input.txt","r",stdin)#define FOUT            freopen("output.txt","w",stdout)//#pragma comment(linker, "/STACK:1024000000,1024000000")typedef __int64         LL;const int INF = 0x3f3f3f3f;const int MAXN = 50000 + 5;/****************************>>>>SEPARATOR<<<<****************************/int N, M, P, A[MAXN];struct Edge {    int v, next;    Edge() {}    Edge(int v, int next) : v(v), next(next) {}} edge[MAXN << 1];int head[MAXN], ESZ;int siz[MAXN], top[MAXN], fa[MAXN], son[MAXN], dep[MAXN], tid[MAXN], rk[MAXN], id;int seg[MAXN << 2], tag[MAXN << 2];void init() {    ESZ = 0;    id = 0;    memset(head, -1, sizeof(head));    memset(son, -1, sizeof(son));}void add_edge(int u, int v) {    edge[ESZ] = Edge(v, head[u]);    head[u] = ESZ ++;}void dfs1(int u, int pre, int k) {    int v;    siz[u] = 1;    fa[u] = pre;    dep[u] = k;    for(int i = head[u]; ~i; i = edge[i].next) {        v = edge[i].v;        if(v == pre) continue;        dfs1(v, u, k + 1);        siz[u] += siz[v];        if(son[u] == -1 || siz[son[u]] < siz[v]) son[u] = v;    }}void dfs2(int u, int tp) {    int v;    tid[u] = ++ id;    rk[tid[u]] = u;    top[u] = tp;    if(son[u] == -1) return;    dfs2(son[u], tp);    for(int i = head[u]; ~i; i = edge[i].next) {        v = edge[i].v;        if(v == fa[u] || v == son[u]) continue;        dfs2(v, v);    }}inline void pushUp(const int& rt) {    seg[rt] = seg[rt << 1] + seg[rt << 1 | 1];}inline void pushDown(int w, const int& rt)  {    if(tag[rt]) {        seg[rt << 1] += (w - (w >> 1)) * tag[rt];        seg[rt << 1 | 1] += (w >> 1) * tag[rt];        tag[rt << 1] += tag[rt];        tag[rt << 1 | 1] += tag[rt];        tag[rt] = 0;    }}void build(int l, int r, int rt) {    tag[rt] = 0;    if(l == r) {        seg[rt] = A[rk[l]];        return;    }    __mid__;    build(lson);    build(rson);    pushUp(rt);}int query(const int& p, int l, int r, int rt) {    if(l == r) {        tag[rt] = 0;        return seg[rt];    }    __mid__;    pushDown(r - l + 1, rt);    return p <= mid ? query(p, lson) : query(p, rson);}void update(const int& L, const int& R, const int& x, int l, int r, int rt) {    if(L <= l && r <= R) {        seg[rt] += (r - l + 1) * x;        tag[rt] += x;        return;    }    __mid__;    pushDown(r - l + 1, rt);    if(L <= mid) update(L, R, x, lson);    if(R > mid) update(L, R, x, rson);    pushUp(rt);}void modify(int u, int v, int x) {    int f1 = top[u], f2 = top[v];    while(f1 != f2) {        if(dep[f1] < dep[f2]) {            swap(u, v);            swap(f1, f2);        }        update(tid[f1], tid[u], x, 1, id, 1);        u = fa[f1], f1 = top[u];    }    if(dep[u] > dep[v]) swap(u, v);    update(tid[u], tid[v], x, 1, id, 1);}char op[5];int main() {#ifndef ONLINE_JUDGE    FIN;#endif // ONLINE_JUDGE    int u, v, x;    while(~scanf("%d %d %d", &N, &M, &P)) {        init();        for(int i = 1; i <= N; i ++) {            scanf("%d", &A[i]);        }        for(int i = 1; i <= M; i ++) {            scanf("%d %d", &u, &v);            add_edge(u, v);            add_edge(v, u);        }        dfs1(1, -1, 1);        dfs2(1, 1);        build(1, id, 1);        while(P --) {            scanf("%s", op);            if(op[0] == 'Q') {                scanf("%d", &u);                printf("%d\n", query(tid[u], 1, id, 1));            } else {                scanf("%d %d %d", &u, &v, &x);                if(op[0] == 'D') x = -x;                modify(u, v, x);            }        }    }    return 0;}
1 0
原创粉丝点击