点权树的模板题,另外发现树状数组也是可以区间更新的。。

注意在对链进行操作时方向不要搞错

线段树版本

#include<bits/stdc++.h>
using namespace std;
#define maxn 50005
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
struct Edge{int to,next;}edge[maxn<<];
int a[maxn],head[maxn],tot;
int deep[maxn],fa[maxn],son[maxn],num[maxn];
int top[maxn],fp[maxn],p[maxn],pos;
inline void addedge(int u,int v){edge[tot].to=v;edge[tot].next=head[u];head[u]=tot++;}
void dfs1(int u,int pre,int dep){
fa[u]=pre;deep[u]=dep;num[u]=;
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].to;
if(v==pre) continue;
dfs1(v,u,dep+);
num[u]+=num[v];
if(son[u]==- || num[son[u]]<num[v]) son[u]=v;
}
}
void getpos(int u,int sp){
top[u]=sp;p[u]=pos++;fp[p[u]]=u;
if(son[u]==-) return;
getpos(son[u],sp);
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].to;
if(v!=fa[u] && v!=son[u]) getpos(v,v);
}
} int seg[maxn<<];
void build(int l,int r,int rt){
seg[rt]=;
if(l==r) {seg[rt]=a[fp[l]];return;}//注意这里,线段树上坐标为i的点权值是第i个被访问到的点的权值
int m=l+r>>;
build(lson);build(rson);
}
inline void pushdown(int rt){
if(seg[rt]) {
seg[rt<<]+=seg[rt];
seg[rt<<|]+=seg[rt];
seg[rt]=;
}
}
void update(int L,int R,int c,int l,int r,int rt){
if(L<=l && R>=r){seg[rt]+=c;return;}
pushdown(rt);
int m=l+r>>;
if(L<=m) update(L,R,c,lson);
if(R>m) update(L,R,c,rson);
}
int query(int pos,int l,int r,int rt){
if(l==r) return seg[rt];
pushdown(rt);
int m=l+r>>;
if(pos<=m) return query(pos,lson);
else return query(pos,rson);
}
void change(int u,int v,int c){
int f1=top[u],f2=top[v];
while(f1!=f2){
if(deep[f1]<deep[f2]){swap(u,v);swap(f1,f2);}
update(p[f1],p[u],c,,pos,);
u=fa[f1];f1=top[u];
}
if(deep[u]>deep[v]) swap(u,v);
update(p[u],p[v],c,,pos,);
}
void init(){
tot=pos=;pos=;
memset(head,-,sizeof head);
memset(son,-,sizeof son);
}
int main(){
int n,m,q,u,v,k;
while(scanf("%d%d%d",&n,&m,&q)==){
init();
for(int i=;i<=n;i++)scanf("%d",&a[i]);
for(int i=;i<=m;i++){scanf("%d%d",&u,&v);addedge(u,v);addedge(v,u);}
dfs1(,,);getpos(,);build(,pos,);
char op[];
while(q--){
scanf("%s",op);
if(op[]=='I') {scanf("%d%d%d",&u,&v,&k);change(u,v,k);}
else if(op[]=='D'){scanf("%d%d%d",&u,&v,&k);change(u,v,-k);}
else {scanf("%d",&u);printf("%d\n",query(p[u],,pos,));}
}
}
}

树状数组版本。。果然还是树状数组快一点啊

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define MAXN 50010
using namespace std;
struct Edge{
int to, next;
}edge[MAXN*];
int head[MAXN], tot;
int deep[MAXN];
int fa[MAXN];
int son[MAXN];
int p[MAXN];
int fp[MAXN];
int top[MAXN];
int num[MAXN];
int pos;
int c[MAXN], n;//树状数组的
void init()
{
tot=;
memset(head,-,sizeof(head));
pos=;//树状数组,编号从1开始
memset(son,-,sizeof(son));
memset(c,,sizeof(c));
}
void addedge(int u,int v)
{
edge[tot].to=v;edge[tot].next=head[u];head[u]=tot++;
}
void dfs1(int u, int pre, int d){
deep[u] = d;
fa[u] = pre;
num[u] = ;
for(int i = head[u]; i != -; i = edge[i].next){
int v = edge[i].to;
if (v != pre){//v不能是父节点
dfs1(v, u, d+);
num[u] += num[v];
if (son[u]==-||num[v]>num[son[u]])
son[u] = v;
}
}
}
void getpos(int u, int sp){
top[u] = sp;
p[u] = pos++;
fp[p[u]] = u;
if (son[u] == -)
return;
getpos(son[u], sp);
for(int i = head[u]; i != -; i = edge[i].next){
int v = edge[i].to;
if (v != fa[u] && v != son[u])
getpos(v, v);
}
} //树状数组
int lowbit(int i){
return i&(-i);
}
int sum(int i){
int s = ;
while(i<=n){
s += c[i];
i +=lowbit(i);
}
return s;
}
void add(int i, int val){
while(i>){
c[i]+=val;
i-=lowbit(i);
}
}
void change(int u, int v, int val){
int f1 = top[u], f2 = top[v];
while(f1 != f2){
if (deep[f1]<deep[f2]){
swap(f1, f2);
swap(u, v);
}
add(p[u], val);//树状数组的区间更新原理
add(p[f1]-, -val);//这儿得减去一个东西
u = fa[f1];
f1 = top[u];
}
if(deep[u]>deep[v])
swap(u,v);//默认u是v的祖先
add(p[u]-, -val);
add(p[v], val);
}
int a[MAXN];
int main(){
int M, P;
while(~scanf("%d%d%d", &n, &M, &P)){
int u, v;
int C1, C2, K;
char op[];
init();
for(int i = ; i<=n; i++)
scanf("%d", &a[i]);
while(M--){
scanf("%d%d", &u, &v);
addedge(u, v);
addedge(v, u);
}
dfs1(, , );
getpos(, );
while(P--){
scanf("%s", op);
if (op[]=='Q'){
scanf("%d", &u);
printf("%d\n", sum(p[u])+a[u]);
}
else {
scanf("%d%d%d", &C1, &C2, &K);
if (op[]=='D')
K = -K;
change(C1, C2, K);
}
}
}
}

hdu3966 树链剖分点权模板+线段树区间更新/树状数组区间更新单点查询的更多相关文章

  1. 树链剖分边权模板spoj375

    树链剖分是树分解成多条链来解决树上两点之间的路径上的问题 如何求出树链:第一次dfs求出树上每个结点的大小和深度和最大的儿子,第二次dfs就能将最大的儿子串起来并hash(映射)到线段树上(或者其他数 ...

  2. 刷题总结——骑士的旅行(bzoj4336 树链剖分套权值线段树)

    题目: Description 在一片古老的土地上,有一个繁荣的文明. 这片大地几乎被森林覆盖,有N座城坐落其中.巧合的是,这N座城由恰好N-1条双 向道路连接起来,使得任意两座城都是连通的.也就是说 ...

  3. 计蒜客 38229.Distance on the tree-1.树链剖分(边权)+可持久化线段树(区间小于等于k的数的个数)+离散化+离线处理 or 2.树上第k大(主席树)+二分+离散化+在线查询 (The Preliminary Contest for ICPC China Nanchang National Invitational 南昌邀请赛网络赛)

    Distance on the tree DSM(Data Structure Master) once learned about tree when he was preparing for NO ...

  4. BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分 - 点权剖分 - 单点权修改)

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1036 树链剖分模版题,打的时候注意点就行.做这题的时候,真的傻了,单词拼错检查了一个多小时 ...

  5. Luogu 2590 [ZJOI2008]树的统计 / HYSBZ 1036 [ZJOI2008]树的统计Count (树链剖分,LCA,线段树)

    Luogu 2590 [ZJOI2008]树的统计 / HYSBZ 1036 [ZJOI2008]树的统计Count (树链剖分,LCA,线段树) Description 一棵树上有n个节点,编号分别 ...

  6. 【bzoj4999】This Problem Is Too Simple! 树链剖分+动态开点线段树

    题目描述 给您一颗树,每个节点有个初始值. 现在支持以下两种操作: 1. C i x(0<=x<2^31) 表示将i节点的值改为x. 2. Q i j x(0<=x<2^31) ...

  7. POJ3237 Tree 树链剖分 边权

    POJ3237 Tree 树链剖分 边权 传送门:http://poj.org/problem?id=3237 题意: n个点的,n-1条边 修改单边边权 将a->b的边权取反 查询a-> ...

  8. Qtree3题解(树链剖分(伪)+线段树+set)

    外话:最近洛谷加了好多好题啊...原题入口 这题好像是SPOJ的题,挺不错的.看没有题解还是来一篇... 题意: 很明显吧.. 题解: 我的做法十分的暴力:树链剖分(伪)+线段树+\(set\)... ...

  9. POJ2763 Housewife Wind 树链剖分 边权

    POJ2763 Housewife Wind 树链剖分 边权 传送门:http://poj.org/problem?id=2763 题意: n个点的,n-1条边,有边权 修改单边边权 询问 输出 当前 ...

随机推荐

  1. Nginx核心配置文件常用参数详解

    Nginx核心配置文件常用参数详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 关于Nginx权威文档的话童鞋们可以参考Nginx官方文档介绍:http://nginx.org/ ...

  2. JavaSE学习总结(十)—— JDBC与面向对象测试

    一.题目 请使用MySQL+JDBC+JAVASE控制台完成一个图书管理系统(Libs),实现添加图书,查询图书,根据图书编号查询图书三个功能. 二.要求 1.必须有菜单 2.至少3个以上的字段(编号 ...

  3. Swift学习笔记8--Optional Chaining

    Optional Chaining 自判断链接(Optional Chaining)是一种可以请求和调用属性.方法及子脚本的过程,它的自判断性体现于请求或调用的目标当前可能为空(  nil ).如果自 ...

  4. js中闭包的概念和用法

    闭包:主要的作用是 封装变量,收敛权限.防止变量被污染.比如Jquery框架就运用了大量的闭包.为什么呢? 问个问题?框架是如何来避免你声明的变量和它自带的变量不发生的冲突的?????很明显,需要闭包 ...

  5. webapi框架搭建-webapi异常处理

    webapi框架搭建系列博客 前言 上一篇我们已经完成了项目的日志管理,在项目开发中日志会经常记录程序中的异常,供后续问题排查使用.本篇讲如何在webapi里加入异常处理机制. 目的和原则 1.程序任 ...

  6. HDU - 3521 An easy Problem(矩阵快速幂)

    http://acm.hdu.edu.cn/showproblem.php?pid=3521 题意 对于矩阵A,求e^A的值. 分析 这个定眼一看好像很熟悉,就是泰勒展开,可惜自己的高数已经还给老师了 ...

  7. SpringMVC学习笔记_02

    1.springmvc对多视图的支持 (1)导入xml格式视图支持的jar包   注意:springmvc本身就支持xml格式,所以不用导入其他支持的jar包了. (2)在springmvc.xml中 ...

  8. 字符串数字转换成对应的Double数值

    一,介绍 前面实现了字符串转换成整形数值.参考这里: 它不支持小数,不支持符号(正.负号) 现在实现一个更复杂一点字符串转换成数值的程序. 它支持“浮点字符串”转换成对应的浮点数值,如: " ...

  9. FastReport 套打全攻略

    http://blog.csdn.net/jinzhili/article/details/500263 FastReport 套打全攻略  2005-7-13 22:10  原创//以设计套打行为6 ...

  10. android AsyncHttpClient使用

    1.www.github.com下载jar包 loopj/android-async-http 将下载好的文件导入项目中 2.main.xml <?xml version="1.0&q ...