题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3966

树链剖分的模版,成段更新单点查询。熟悉线段树的成段更新的话就小case啦。

 //树链剖分 边权修改 单点查询
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
const int MAXN = 5e4 + ;
struct data {
int to , next;
}edge[MAXN << ];
int head[MAXN] , cnt , tot;
int top[MAXN] , par[MAXN] , son[MAXN] , size[MAXN] , dep[MAXN];
int id[MAXN] , fid[MAXN]; //id[i]表示i对应在线段树上的位置 fid[i]表示线段树位置是i的叶子 对应的节点
int a[MAXN]; void init() {
tot = cnt = ;
memset(head , - , sizeof(head));
} inline void add(int u , int v) {
edge[tot].next = head[u];
edge[tot].to = v;
head[u] = tot++;
} void dfs1(int u , int p , int d) {
dep[u] = d , size[u] = , son[u] = u , par[u] = p;
for(int i = head[u] ; ~i ; i = edge[i].next) {
int v = edge[i].to;
if(v == p)
continue;
dfs1(v , u , d + );
if(size[v] >= size[son[u]] || son[u] == u)
son[u] = v;
size[u] += size[v];
}
} void dfs2(int u , int p , int t) {
top[u] = t , id[u] = ++cnt;
fid[cnt] = u;
if(son[u] != u)
dfs2(son[u] , u , t);
for(int i = head[u] ; ~i ; i = edge[i].next) {
int v = edge[i].to;
if(v == p || v == son[u])
continue;
dfs2(v , u , v);
}
} struct segtree {
int l , r;
int sum;
}T[MAXN << ]; void pushup(int p) {
if(T[p].sum != ) {
int ls = p << , rs = (p << )|;
T[ls].sum += T[p].sum;
T[rs].sum += T[p].sum;
T[p].sum = ;
}
} void build(int p , int l , int r) {
int mid = (l + r) >> ;
T[p].l = l , T[p].r = r;
T[p].sum = ;
if(l == r) {
T[p].sum = a[fid[l]]; //
return ;
}
build(p << , l , mid);
build((p << )| , mid + , r);
} void updata(int p , int l , int r , int num) {
int mid = (T[p].l + T[p].r) >> ;
if(T[p].l == l && T[p].r == r) {
T[p].sum += num;
return ;
}
pushup(p);
if(r <= mid) {
updata(p << , l , r , num);
}
else if(l > mid) {
updata((p << )| , l , r , num);
}
else {
updata(p << , l , mid , num);
updata((p << )| , mid + , r , num);
}
} int query(int p , int pos) {
int mid = (T[p].l + T[p].r) >> ;
if(T[p].l == T[p].r && T[p].r == pos) {
return T[p].sum;
}
pushup(p);
if(pos <= mid) {
return query(p << , pos);
}
else {
return query((p << )| , pos);
}
} void change(int u , int v , int num) {
int fu = top[u] , fv = top[v];
int sum = ;
while(fu != fv) {
if(dep[fu] > dep[fv]) {
updata( , id[fu] , id[u] , num);
u = par[fu];
fu = top[u];
}
else {
updata( , id[fv] , id[v] , num);
v = par[fv];
fv = top[v];
}
}
if(dep[u] >= dep[v]) {
updata( , id[v] , id[u] , num);
}
else {
updata( , id[u] , id[v] , num);
}
} int main()
{
int n , u , v , m , xx;
while(~scanf("%d %d %d" , &n , &xx , &m)) {
init();
for(int i = ; i <= n ; ++i) {
scanf("%d" , a + i);
}
for(int i = ; i < n ; ++i) {
scanf("%d %d" , &u , &v);
add(u , v);
add(v , u);
}
cnt = ;
dfs1( , , );
dfs2( , , );
build( , , cnt);
char q[];
while(m--) {
scanf("%s" , q);
if(q[] == 'Q') {
scanf("%d" , &xx);
printf("%d\n" , query( , id[xx]));
}
else if(q[] == 'I') {
scanf("%d %d %d" , &u , &v , &xx);
change(u , v , xx);
}
else {
scanf("%d %d %d" , &u , &v , &xx);
change(u , v , -xx);
}
}
}
return ;
}

HDU 3966 Aragorn's Story (树链点权剖分,成段修改单点查询)的更多相关文章

  1. HDU 3966 Aragorn's Story 树链剖分+树状数组 或 树链剖分+线段树

    HDU 3966 Aragorn's Story 先把树剖成链,然后用树状数组维护: 讲真,研究了好久,还是没明白 树状数组这样实现"区间更新+单点查询"的原理... 神奇... ...

  2. Hdu 3966 Aragorn's Story (树链剖分 + 线段树区间更新)

    题目链接: Hdu 3966 Aragorn's Story 题目描述: 给出一个树,每个节点都有一个权值,有三种操作: 1:( I, i, j, x ) 从i到j的路径上经过的节点全部都加上x: 2 ...

  3. HDU 3966 Aragorn's Story(树链剖分)(线段树区间修改)

    Aragorn's Story Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  4. HDU 3966 Aragorn's Story 树链剖分+BIT区间修改/单点询问

    Aragorn's Story Description Our protagonist is the handsome human prince Aragorn comes from The Lord ...

  5. HDU 3966 Aragorn's Story 树链拋分

    一.写在前面 终于开始开坑link-cut-tree这个了,对于网上找到的大佬的前进路线,进行了一番研发,发现实际上可以实现对于树链拋分的制作.经历了若干长时间之后终于打了出来(为什么每次学什么东西都 ...

  6. HDU 3966 Aragorn's Story (树链剖分入门题)

    树上路径区间更新,单点查询. 线段树和树状数组都可以用于本题的维护. 线段树: #include<cstdio> #include<iostream> #include< ...

  7. HDU 3966 Aragorn's Story 树链剖分

    Link: http://acm.hdu.edu.cn/showproblem.php?pid=3966 这题注意要手动扩栈. 这题我交g++无限RE,即使手动扩栈了,但交C++就过了. #pragm ...

  8. hdu 3966 Aragorn's Story : 树链剖分 O(nlogn)建树 O((logn)²)修改与查询

    /** problem: http://acm.hdu.edu.cn/showproblem.php?pid=3966 裸板 **/ #include<stdio.h> #include& ...

  9. hdu 3966 Aragorn's Story 树链剖分 按点

    Aragorn's Story Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

随机推荐

  1. 函数lock_rec_bitmap_reset

    /*********************************************************************//** Resets the record lock bi ...

  2. ffmpeg基础与编译_在VS2008下调试output_example.c(详细步骤)

    注意:这个是编译Debug版本的.必要资源:FFMPEG SDK 3.2(已经编译好的,可以去http://www.bairuitech.com/html/ruanjianxiazai/ffmpeg/ ...

  3. oracle查询某个用户下的所有视图

    SYS>select view_name from dba_views where owner = 'NS_RAS3'; VIEW_NAME--------------------------- ...

  4. 通过Instant Client包来使用SQL*PLUS

    1.首先下载两个程序包: Instant Client Package - Basic(或Instant Client Package - Basic Lite)包 Instant Client Pa ...

  5. 【WEB】jsp向servlet传参中文乱码问题解决

    传参方式:POST.GET.link方式 servlet向jsp传中文参数msg if(username.equals("") || password.euqals("& ...

  6. 【转】linux : waitpid函数

    原文网址:http://blog.csdn.net/jifengszf/article/details/3067841 [waitpid系统调用]       功能描述: 等待进程改变其状态.所有下面 ...

  7. setFocusable、setEnabled、setClickable区别

    setClickable  设置为true时,表明控件可以点击,如果为false,就不能点击:“点击”适用于鼠标.键盘按键.遥控器等:注意,setOnClickListener方法会默认把控件的set ...

  8. ASIHTTPREQUEST 文档

    http://blog.csdn.net/ysysbaobei/article/details/17026577 Please note that I am no longer working on ...

  9. 【LeetCode 215】Kth Largest Element in an Array

    Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...

  10. jenkins 命令行 CLI jenkins-cli.jar

    部署好jenkins后,一般都是通过jenkins提供的web界面来操作jenkins. 而有些场景则需要通过命令来操作jenkins,例如通过脚本操作jenkins. 在jenkins提供的web界 ...