bzoj4034: [HAOI2015]树上操作

题目链接

bzoj4034: [HAOI2015]树上操作

题解

树剖线段树

代码

#include<bits/stdc++.h>
using namespace std; 
inline int read() { 
    int x = 0,f = 1; 
    char c = getchar(); 
    while(c < '0' ||c > '9'){if(c == '-')f= -1; c = getchar();} 
    while(c <= '9' &&c >= '0')x = x * 10 + c- '0',c = getchar(); 
    return x * f; 
} 
#define int long long
const int maxn = 200007; 
int n,m,val[maxn]; 
struct node { 
    int u,v,next;
} edge[maxn << 1]; 
int head[maxn],num; 
inline void add_edge(int u,int v) { 
    edge[++ num].v = v; edge[num].next = head[u];head[u] = num ; 
} 
int fa[maxn],deep[maxn],siz[maxn],son[maxn]; 
void dfs1(int x) { 
    deep[x] = deep[fa[x]] + 1;siz[x] = 1;  
    for(int i = head[x];i ;i = edge[i].next) { 
        int v = edge[i].v; 
        if(deep[v]) continue; 
        fa[v] = x; dfs1(v); 
        siz[x] += siz[v]; 
        if(siz[v] > siz[son[x]] || !son[x]) son[x] = v; 
    } 
}    
int pos[maxn],_pos,sop[maxn],top[maxn]; 
void dfs2(int x,int topfa) { 
    top[x] = topfa;pos[x] = ++_pos;sop[_pos] = x; 
    if(!son[x]) return ;
    dfs2(son[x],topfa); 
    for(int i = head[x];i;i = edge[i].next) { 
        int v = edge[i].v; 
        if(v == son[x] || v == fa[x]) continue; 
        dfs2(v,v); 
    } 
} 
#define lc rt << 1 
#define rc rt << 1 | 1 
int sum[maxn << 2],tag[maxn << 2]; 
inline void update(int rt) {sum[rt] = sum[lc] + sum[rc]; } 
void build(int rt,int l,int r) { 
    if(l == r) { 
        sum[rt] = val[sop[l]];return ;  
    } 
    int mid = l + r >> 1; 
    build(lc,l,mid); build(rc,mid + 1,r); 
    return update(rt); 
} 
inline void pushdown(int rt,int l,int r) { 
    int mid = l + r >> 1; 
    tag[lc] += tag[rt];tag[rc] += tag[rt]; 
    sum[lc] += (mid - l + 1) * tag[rt]; 
    sum[rc] += (r - mid) * tag[rt]; 
    tag[rt] = 0; 
} 
int T_query(int rt,int l,int r,int tl,int tr ){ 
    if(l >= tl && r <= tr) return sum[rt]; 
    if(tag[rt] != 0) pushdown(rt,l,r); 
    int mid = l + r >> 1,Ret = 0 ; 
    if(tl <= mid) Ret += T_query(lc,l,mid,tl,tr);  
    if(tr > mid)  Ret += T_query(rc,mid + 1,r,tl,tr); 
    return Ret;  
} 
void T_modify(int rt,int l,int r,int tl,int tr,int a) { 
    if(l >= tl && r <= tr) { 
        sum[rt] += (r - l + 1) * a; 
        tag[rt] += a; return ; 
    } 
    if(tag[rt] != 0)pushdown(rt,l,r); 
    int mid = l + r >> 1; 
    if(tl <= mid) T_modify(lc,l,mid,tl,tr,a); 
    if(tr > mid)  T_modify(rc,mid + 1,r,tl,tr,a); 
    update(rt); 
} 
int Q(int x) { 
    int ret = 0 ;
    for(;top[x] != 1;x = fa[top[x]]) 
        ret += T_query(1,1,n,pos[top[x]],pos[x]); 
    ret += T_query(1,1,n,pos[top[x]],pos[x]); 
    return ret; 
} 
void M1(int x,int a) { T_modify(1,1,n,pos[x],pos[x],a);  }  
void M2(int x,int a) {  T_modify(1,1,n,pos[x],pos[x] + siz[x] - 1,a); }    
main() { 
    n = read(),m = read(); 
    for(int i = 1;i <= n;++ i) val[i] = read(); 
    for(int u,v,i = 1;i < n;++ i) { 
        u = read(); v = read(); 
        add_edge(u,v); add_edge(v,u); 
    } 
    dfs1(1);  
    dfs2(1,1); 
    build(1,1,n); 
    for(int type,x,a;m --;) { 
        type = read(); 
        if(type == 1) { 
            x = read(); a = read(); 
            M1(x,a); 
        } else if(type == 2) { 
            x = read(); a = read(); 
            M2(x,a);    
        } else { 
            x = read(); 
            printf("%lld\n",Q(x)) ;  
        } 
    } 
    return 0; 
} 
posted @ 2018-07-09 08:16  zzzzx  阅读(130)  评论(0编辑  收藏  举报