hdu--3966(树链剖分)

题目链接:hdu--3966

给出n个点的值,还有n-1条边的连接方式,三种操作:

1、I在节点a到b的路径中所有的点都增加x

2、D在节点a到b的路径中所有的点都减少x

3、Q询问第k个节点的值。

将每个节点的值转化为父节点到子节点的边的权值,对于根节点做一个虚拟的父节点0 。进行树链剖分,整合到线段树中之后注意:

更新时,不能只更新a到b上的边的权值,因为那样会使b节点的权值不能被更新到,在更新a到b的段的权值后,应该在更新b到b的权值。

#include 
#include 
#include 
using namespace std ;
#define INF 0x3f3f3f3f
#define int_now int l,int r,int rt
#define now l,r,rt
#define lson l,(l+r)/2,rt<<1
#define rson (l+r)/2+1,r,rt<<1|1
#define maxn 100000
#pragma comment(linker, "/STACK:1024000000,1024000000")
struct node
{
    int u , v ;
    int next ;
} edge[maxn<<1];
int head[maxn] , cnt , vis[maxn] ;
int num[maxn] , dep[maxn] , fa[maxn] , son[maxn] , top[maxn] , w[maxn] , step ;
int cl[maxn<<2] , lazy[maxn<<2] ;
int c[maxn] , belong[maxn] ;
void add(int u,int v)
{
    edge[cnt].u = u ;
    edge[cnt].v = v ;
    edge[cnt].next = head[u] ;
    head[u] = cnt++ ;
    return ;
}
void dfs1(int u)
{
    num[u] = 1 ;
    son[u] = -1 ;
    int i , v ;
    for(i = head[u] ; i != -1 ; i = edge[i].next)
    {
        v = edge[i].v ;
        if( vis[v] ) continue ;
        vis[v] = 1 ;
        dep[v] = dep[u] + 1 ;
        fa[v] = u ;
        dfs1(v) ;
        num[u] += num[v] ;
        if( son[u] == -1 || num[ son[u] ] < num[v] )
            son[u] = v ;
    }
    return ;
}
void dfs2(int u)
{
    if( son[u] == -1 ) return ;
    w[ son[u] ] = step++ ;
    top[ son[u] ] = top[u] ;
    vis[ son[u] ] = 1 ;
    dfs2(son[u]) ;
    int i , v ;
    for(i = head[u] ; i != -1 ; i = edge[i].next)
    {
        v = edge[i].v ;
        if( vis[v] ) continue ;
        vis[v] = 1 ;
        w[v] = step++ ;
        top[v] = v ;
        dfs2(v) ;
    }
    return ;
}
void dfs()
{
    memset(vis,0,sizeof(vis)) ;
    vis[0] = 1 ;
    dep[0] = 1 ;
    fa[0] = -1 ;
    dfs1(0) ;
    memset(vis,0,sizeof(vis)) ;
    vis[0] = 1 ;
    top[0] = 0 ;
    step = 1 ;
    dfs2(0) ;
    return ;
}
void build(int_now)
{
    cl[rt] = lazy[rt] = 0 ;
    if( l == r )
    {
        cl[rt] = c[ belong[l] ] ;
        return ;
    }
    build(lson) ;
    build(rson) ;
    return ;
}
void update(int ll,int rr,int_now,int x)
{
    if( l > rr || r < ll ) return ;
    if( ll <= l && rr >= r )
    {
        lazy[rt] += x ;
        return ;
    }
    update(ll,rr,lson,x) ;
    update(ll,rr,rson,x) ;
}
int query(int k,int_now,int sum)
{
    sum += lazy[rt] ;
    if( l == k && r == k )
    {
        return cl[rt] + sum ;
    }
    if( k <= (l+r)/2 )
        return query(k,lson,sum) ;
    else
        return query(k,rson,sum) ;
}
void solve(int u,int v,int s)
{
    int f1 , f2 ;
    while( u != v )
    {
        if( dep[u] > dep[v] )
            swap(u,v) ;
        f1 = top[u] ;
        f2 = top[v] ;
        if( f1 == f2 )
        {
            update(w[son[u]],w[v],1,step-1,1,s) ;
            v = u ;
        }
        else if( dep[f1] > dep[f2] )
        {
            update(w[f1],w[u],1,step-1,1,s) ;
            u = fa[f1] ;
        }
        else
        {
            update(w[f2],w[v],1,step-1,1,s) ;
            v = fa[f2] ;
        }
    }
    update(w[u],w[u],1,step-1,1,s) ;
    return ;
}
char str[10] ;
int main()
{
    int n , m , p ;
    int i , j  , k ;
    int u , v , s ;
    while( scanf("%d %d %d", &n, &m, &p) != EOF )
    {
        memset(head,-1,sizeof(head)) ;
        cnt = 0 ;
        for(i = 1 ; i <= n ; i++)
            scanf("%d", &c[i]) ;
        add(0,1) , add(1,0) ;
        while( m-- )
        {
            scanf("%d %d", &u, &v) ;
            add(u,v) ;
            add(v,u) ;
        }
        dfs() ;
        for(i = 1 ; i <= n ; i++)
            belong[ w[i] ] = i ;
        build(1,step-1,1) ;
        while( p-- )
        {
            scanf("%s", str) ;
            if( str[0] == 'I' )
            {
                scanf("%d %d %d", &u, &v, &s) ;
                solve(u,v,s) ;
            }
            else if( str[0] == 'D' )
            {
                scanf("%d %d %d", &u, &v, &s) ;
                solve(u,v,-s) ;
            }
            else
            {
                scanf("%d", &i) ;
                printf("%d\n", query(w[i],1,step-1,1,0)) ;
            }
        }
    }
    return 0 ;
}


 

你可能感兴趣的:(数据结构)