题目链接: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. NodeJS常用库说明

    underscore:1.合并json async:1.异步编程同步化

  2. 1641. Duties

    1641 枚举 #include <iostream> #include<cstdio> #include<cstring> #include<algorit ...

  3. hdu 2986 Ballot evaluation (模拟)

    题目 上次比赛的题目,好长时间了. 这几天感冒了很难受, 直到现在才整理, 上次比赛的时候,出了各种错误,   ,,,样例都没过,题目读的也很差,今天做的时候, 看了一下网上的,发现一个代码特别简洁, ...

  4. UVa 1648 (推公式) Business Center

    题意: 有一种奇怪的电梯,每次只能向上走u个楼层或者向下走d个楼层 现在有m个这种电梯,求恰好n次能够到达的最小楼层数(必须是正数),最开始默认位于第0层. 分析: 假设电梯向上走x次,则向下走n-x ...

  5. macro names must be identifiers

    1.错把 #include 写成了 #define 会报这个错 2.定义一个不存在的宏业会报这个错,如加了-DANDRO 而ANDRO不存在

  6. POJ 1904 King's Quest ★(强连通分量:可行完美匹配边)

    题意 有n个女生和n个男生,给定一些关系表示男生喜欢女生(即两个人可以结婚),再给定一个初始匹配,表示这个男生和哪个女生结婚,初始匹配必定是合法的.求每个男生可以和哪几个女生可以结婚且能与所有人不发生 ...

  7. 【转】【Android】对话框 AlertDialog -- 不错不错

    原文网址:http://blog.csdn.net/feng88724/article/details/6171450 本讲介绍一下Android基本组件:对话框AlertDialog. API: j ...

  8. mysql中出现的Data truncated for column

    mysql中想一个数据库中插入一条记录时,有可能因为好多原因,会出现Data truncated for column XXXXX的错误,这是因为你的数据类型的长度不一致导致的,仔细查看一下数据类型的 ...

  9. C#中使用visio控件

    C#中使用visio控件 2012-08-25 18:14:19|  分类: 技术相关|举报|字号 订阅     其实就是C#访问VISIO的自动化模型,以前做了不少C#和Excle及word 的交互 ...

  10. [转] AE中如何由IFeature 如何获取所对应的FeatureClass

    转载的原文 AE中如何由IFeature 如何获取所对应的FeatureClass   先获取FeatureClass,然后遍历Map中所有的FeatureLayer,然后比较 FeatureClas ...