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

题意:一颗树上,每个点有权值,定义三种操作:

1)I操作表示从a到b节点之间的节点都加上一个值

2)D操作表示从a到b节点之间的节点的都减去一个权值

3)Q操作询问a节点当前的值。

分析:树链剖分裸题,在树上修改点权及询问点权,将树上信息映射到线段上后,就是一道水线段树题了。

#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdlib>
#include <stack>
#include <vector>
#include <set>
#include <map>
#define LL long long
#define mod 10007
#define inf 0x3f3f3f3f
#define N 100010
#define FILL(a,b) (memset(a,b,sizeof(a)))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
struct edge
{
int to,next;
edge(){}
edge(int to,int next):to(to),next(next){}
}e[N<<];
int head[N<<],tot;
int top[N];//top[v]表示v所在的重链的顶端节点
int fa[N];//父亲节点
int dep[N];//深度
int sz[N];//si[v]表示以v为根节点的子树的节点数
int son[N];//重儿子
int p[N];//p[v]表示v与其父亲节点的连边在线段树中的位置
int fp[N];//与p数组相反
int pos;//所有链构成的线段树总长度
int col[N<<],a[N];
void addedge(int u,int v)
{
e[tot]=edge(v,head[u]);
head[u]=tot++;
}
void init()
{
tot=;FILL(head,-);
pos=;FILL(son,-);
}
void dfs(int u,int f,int d)
{
dep[u]=d;sz[u]=;fa[u]=f;//printf("%d %d %d\n",u,f,d);
for(int i=head[u];~i;i=e[i].next)
{
int v=e[i].to;//printf("%d\n\n",v);
if(v==f)continue;
dfs(v,u,d+);
sz[u]+=sz[v];
if(son[u]==-||sz[son[u]]<sz[v])son[u]=v;
}
}
void getpos(int u,int sp)
{
top[u]=sp;
p[u]=++pos;
fp[pos]=u;
if(son[u]==-)return;
getpos(son[u],sp);
for(int i=head[u];~i;i=e[i].next)
{
int v=e[i].to;
if(v!=son[u]&&v!=fa[u])
{
getpos(v,v);
}
}
} void Pushdown(int rt)
{
int ls=rt<<,rs=ls|;
if(col[rt])
{
col[rt<<]+=col[rt];
col[rt<<|]+=col[rt];
col[rt]=;
}
}
void build(int l,int r,int rt)
{
if(l==r)
{
col[rt]=a[fp[l]];
return;
}
int m=(l+r)>>;
build(lson);
build(rson);
}
void update(int L,int R,int c,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
col[rt]+=c;
return;
}
Pushdown(rt);
int m=(l+r)>>;
if(L<=m)update(L,R,c,lson);
if(m<R)update(L,R,c,rson);
}
int query(int ps,int l,int r,int rt)
{
if(l==r)
return col[rt];
Pushdown(rt);
int m=(l+r)>>;
if(ps<=m)return query(ps,lson);
if(ps>m)return query(ps,rson);
}
void lca(int u,int v,int c)
{
int fu=top[u],fv=top[v];
while(fu!=fv)
{
if(dep[fu]<dep[fv])
{
swap(fu,fv);
swap(u,v);
}
update(p[fu],p[u],c,,pos,);
u=fa[fu];fu=top[u];
}
if(dep[u]>dep[v])swap(u,v);
update(p[u],p[v],c,,pos,);
}
int main()
{
int n,m,t,u,v,w;
while(scanf("%d%d%d",&n,&m,&t)>)
{
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);
}
dfs(,,);
getpos(,);
FILL(col,);
build(,pos,);
char op[];
while(t--)
{
scanf("%s",op);
if(op[]=='Q')
{
scanf("%d",&u);
printf("%d\n",query(p[u],,pos,));
}
else
{
scanf("%d%d%d",&u,&v,&w);
if(op[]=='D')w=-w;
lca(u,v,w);
}
}
}
}

hdu3966(树链剖分)的更多相关文章

  1. HDU3966(树链剖分)

    题目:Aragorn's Story 题意:给一棵树,并给定各个点权的值,然后有3种操作: I C1 C2 K: 把C1与C2的路径上的所有点权值加上K D C1 C2 K:把C1与C2的路径上的所有 ...

  2. hdu3966 树链剖分+成段更新

    给你n个点,m条边,p次操作.n个点相连后是一棵树.每次操作可以是x 到 y 增加 z,或者减z,或者问当前点的值是多少. 可以将树分成链,每个点在线段树上都有自己的点,然后线段树成段更新一下. #p ...

  3. hdu3966 树链剖分点权模板+线段树区间更新/树状数组区间更新单点查询

    点权树的模板题,另外发现树状数组也是可以区间更新的.. 注意在对链进行操作时方向不要搞错 线段树版本 #include<bits/stdc++.h> using namespace std ...

  4. 树链剖分入门-Hdu3966 Aragorn's Story

    AC通道:http://acm.hdu.edu.cn/showproblem.php?pid=3966 [题目大意] 一棵树上每个点有权值,每次支持三种操作:给[a,b]路径上的所有节点的权值加上k, ...

  5. hdu3966 Aragorn's Story 树链剖分

    题目传送门 题目大意: 有n个兵营形成一棵树,给出q次操作,每一次操作可以使两个兵营之间的所有兵营的人数增加或者减少同一个数目,每次查询输出某一个兵营的人数. 思路: 树链剖分模板题,讲一下树链剖分过 ...

  6. SPOJ375(树链剖分)

    题目:Query on a tree 题意:给定一棵树,告诉了每条边的权值,然后给出两种操作: (1)把第i条边的权值改为val (2)询问a,b路径上权值最大的边 分析:本题与HDU3966差不多, ...

  7. HDU 3966 Aragorn's Story (树链剖分+树状数组)

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

  8. HDU - 3966-Aragorn' Story(树链剖分+线段树)

    链接:https://vjudge.net/problem/HDU-3966 题意: Our protagonist is the handsome human prince Aragorn come ...

  9. BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2050  Solved: 817[Submit][Status ...

随机推荐

  1. Zookeeper从入门到精通(开发详解,案例实战,Web界面监控)

    ZooKeeper是Hadoop的开源子项目(Google Chubby的开源实现),它是一个针对大型分布式系统的可靠协调系统,提供的功能包括:配置维护.命名服务.分布式同步.组服务等. Zookee ...

  2. canvas 多种形状绘图方法

    function canvasUploadImg(image,imageName,imgType,callbackfn){ var img_width = image.width; var img_h ...

  3. 【每日一摩斯】-Troubleshooting: High CPU Utilization (164768.1) - 系列4

    Jobs (CJQ0, Jn, SNPn) Job进程运行用户定义的以及系统定义的类似于batch的任务.检查Job进程占用大量CPU资源的方法,就像检查用户进程一样. 可以根据以下视图检查Job进程 ...

  4. Selenium WebDriver TestNg Maven Eclipse java 简单实例

    环境准备 前提条件Eclipse 已经安装过 TestNg ,Maven 插件 新建一个普通的java项目 点击右键 configure->convert to Maven Project 之后 ...

  5. jquery的ajax提交form表单方式总结

    方法一: function AddHandlingFeeToRefund() { var AjaxURL= "../OrderManagement/AjaxModifyOrderServic ...

  6. 如果用float实现居中

    今天发现自己做的一个项目中有个图片切换的下面的按钮不是固定个数,程序那边根据循环实现放几个切换的按钮,但是按钮相对于整体的要居中,刚开始想着用display:inline-block;实现,但是ie6 ...

  7. protobuf-2.5.0.tar.gz的下载与安装

    1.下载 hadoop使用protocol buffer进行通信,须要下载和安装protobuf-2.5.0.tar.gz.因为如今protobuf-2.5.0.tar.gz已经无法在官网https: ...

  8. Gap 锁

    14.3.1 InnoDB Locking InnoDB 锁 本章节描述InnoDB 使用的锁类型: Shared and Exclusive Locks Intention Locks Record ...

  9. javascript --- 事件托付

    javascript 之 事件托付 长处:1.提高性能(仅仅须要对父级进行操作,子节点相同会拥有其相关属性和方法) 2.对于新加入的事件.也让其拥有父级事件的属性 <!doctype html& ...

  10. 访问项目时,不能自动加载index.php文件

    1.修改配置文件D:\lamp\apache\conf\httpd.conf加上DirectoryIndex index.hmtl index.php <IfModule !mpm_netwar ...