LightOJ 1348 Aladdin and the Return Journey 树链剖分

来源:互联网 发布:一般网络女主播的收入 编辑:程序博客网 时间:2024/05/16 14:17

树链剖分简单题

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=28982#problem/H

#include <map>#include <set>#include <queue>#include <cmath>#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>using namespace std;const int MAXN = 100010;struct Edge {    int to ;    Edge * next;}E[MAXN*2],*EE;struct Gragh {    Edge * first;}G[MAXN];struct Tree {    int x,y;    int value;    int lazy;}t[MAXN<<2];int pre[MAXN],son[MAXN],siz[MAXN],dep[MAXN],top[MAXN],pos[MAXN],Rank[MAXN];int N,Q,S;int num[MAXN];int idx[MAXN];int tree_idx = 0;int tot ;void Init() {    EE = E;    dep[1] = 1;    pre[1] = 0;    tree_idx = 0;    memset(G,0,sizeof(G));    memset(son,0,sizeof(son));}// void addedge(int u,int v,int value,int id) {//     EE->to = v ; EE->next = G[u].first ; EE->value = value ; EE->id = id ; G[u].first = EE++;//     EE->to = u ; EE->next = G[v].first ; EE->value = value ; EE->id = id ; G[v].first = EE++;// }void addedge(int u,int v) {    EE->to = v ; EE->next = G[u].first ; G[u].first = EE++;    EE->to = u ; EE->next = G[v].first ; G[v].first = EE++;}void dfs1(int u) {    siz[u] = 1;    son[u] = 0;    for(Edge * p = G[u].first ; p ; p = p -> next) {        if(p->to != pre[u]) {            pre[p->to] = u;            dep[p->to] = dep[u] + 1;            dfs1(p->to);            siz[u] += siz[p->to];            if(siz[p->to] > siz[son[u]])                son[u] = p -> to;        }    }}void dfs2(int u,int ancestor) {    top[u] = ancestor;    tree_idx ++;    pos[u] = tree_idx;    if(son[u] != 0) {        dfs2(son[u],ancestor);    }    for(Edge * p = G[u].first ; p ; p = p -> next) {        if(p->to != pre[u] && p->to != son[u]) {            dfs2(p->to,p->to);            // num[pos[p->to]] = p->value;            // idx[p->id] = pos[p->to];        }        // else if(p->to == son[u]) {        //     num[pos[p->to]] = p->value;        //     idx[p->id] = pos[p->to];        // }    }} void Push_Up(int rt) {    t[rt].value = t[rt<<1].value + t[rt<<1|1].value; }void Build(int x,int y,int rt) {    t[rt].x = x ; t[rt].y = y; t[rt].lazy = 0;     if(x == y) {        t[rt].value = Rank[x];        return ;    }    int mid = (x + y) >> 1;    Build(x,mid,rt<<1);    Build(mid+1,y,rt<<1|1);    Push_Up(rt);}void Update(int rt,int position,int value) {    if(t[rt].x == t[rt].y) {        t[rt].value = value;        return ;    }    int mid = (t[rt].x + t[rt].y) >> 1;    if(mid >= position) {        Update(rt<<1,position,value);    }    else {        Update(rt<<1|1,position,value);    }    Push_Up(rt);}int Query(int rt,int left,int right) {    if(left <= t[rt].x && right >= t[rt].y) {        return t[rt].value;    }    int ans = 0;    int mid = (t[rt].x + t[rt].y) >> 1;    // Push_Down(rt);    if(mid >= left) {        ans += Query(rt<<1,left,right);    }     if(mid < right){        ans += Query(rt<<1|1,left,right);    }    return ans;}// void Change(int x,int y,int lazy) {//     //printf("lazy : %d\n",lazy);//     while(top[x] != top[y]) {//         if(dep[top[x]] < dep[top[y]]) swap(x,y);//         Update(1,pos[top[x]],pos[x],lazy);//         x = pre[top[x]];//     }//     if(dep[x] > dep[y]) swap(x,y);//     Update(1,pos[x],pos[y],lazy);// }int Query_Tree(int x,int y) {    int ans = 0;    while(top[x] != top[y]) {        if(dep[top[x]] < dep[top[y]]) swap(x,y);        ans += Query(1,pos[top[x]],pos[x]);        x = pre[top[x]];    }    //if(x == y) return ans;    if(dep[x] > dep[y]) swap(x,y);    ans += Query(1,pos[x],pos[y]);    return ans;}// void print_tree(int rt) {//     printf("x : %d y : %d lazy : %d\n",t[rt].x,t[rt].y,t[rt].lazy);//     if(t[rt].x == t[rt].y) {//         printf("%d ",t[rt].value);//         return ;//     }//     print_tree(rt<<1);//     print_tree(rt<<1|1);// }int ReadInt() {    char c = getchar();    while(c > '9' || c < '0') c = getchar();    int ret = 0;    while(c <= '9' && c >= '0') {        ret = ret * 10 + c - '0';        c = getchar();    }    return ret;}void input() {    int u,v,value;    for(int i = 1 ; i <= N ; i++) {        scanf("%d",num+i);    }    for(int i = 1 ; i <= N - 1 ; i++) {        scanf("%d %d",&u,&v);        u ++ ; v ++ ;        addedge(u,v);    }    dfs1(1);    dfs2(1,1);    for(int i = 1 ; i <= N ; i++) {        Rank[pos[i]] = num[i];    }    Build(1,N,1);    int op;    scanf("%d",&Q);    for(int i = 1 ; i <= Q ; i ++) {        scanf("%d",&op) ;        if(op == 1) {            scanf("%d %d",&u,&value);            u ++;            Update(1,pos[u],value);        }        else {            scanf("%d %d",&u,&v);            u ++; v++;            printf("%d\n",Query_Tree(u,v));        }        //print_tree(1);        //puts("");    }}int main(void) {    freopen("a.in","r",stdin);    int T;    int casenum = 1;    scanf("%d",&T);    while(T--) {        printf("Case %d:\n",casenum++);        scanf("%d",&N);        Init();        input();        //solve();    }    return 0;}
0 0
原创粉丝点击