【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id=4034

【题目大意】

  有一棵点数为 N 的树,以点 1 为根,且树点有边权。

  有 M 个 操作,分为三种:

    操作 1 :把某个节点 x 的点权增加 a 。

    操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a 。

    操作 3 :询问某个节点 x 到根的路径中所有点的点权和。

【题解】

  树链剖分之后变成简单的线段树区间和维护。

【代码】

#include <cstdio>
#include <algorithm>
using namespace std;
const int N=200005;
typedef long long LL;
int x,y,d[N],num[N],ed=0,u,w,n,m,i,v[N],vis[N],f[N],g[N];
int nxt[N],size[N],son[N],st[N],en[N],dfn,top[N],t,a[N];
void add(int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}
void dfs(int x){
size[x]=1;
for(int i=g[x];i;i=nxt[i])if(v[i]!=f[x]){
f[v[i]]=x,d[v[i]]=d[x]+1;
dfs(v[i]),size[x]+=size[v[i]];
if(size[v[i]]>size[son[x]])son[x]=v[i];
}
}
void dfs2(int x,int y){
if(x==-1)return;
st[x]=++dfn;top[x]=y;
if(son[x])dfs2(son[x],y);
for(int i=g[x];i;i=nxt[i])if(v[i]!=son[x]&&v[i]!=f[x])dfs2(v[i],v[i]);
en[x]=dfn;
}
struct node{LL l,r,a,b,tag,sum;}T[N*4];
int tot=0;
void addtag(LL x,LL tag){
T[x].tag+=tag;
T[x].sum+=(T[x].b-T[x].a+1)*tag;
}
void pb(LL x){
if(T[x].l){addtag(T[x].l,T[x].tag);addtag(T[x].r,T[x].tag);}
T[x].tag=0;
}
void up(LL x){T[x].sum=T[T[x].l].sum+T[T[x].r].sum;}
void build(int l,int r){
int x=++tot;
T[x].a=l;T[x].b=r;T[x].tag=T[x].l=T[x].r=T[x].sum=0;
if(l==r){return;}
LL mid=(l+r)>>1;
T[x].l=tot+1;build(l,mid);
T[x].r=tot+1;build(mid+1,r);
up(x);
}
void change(LL x,LL a,LL b,LL p){
if(T[x].a>=a&&T[x].b<=b){addtag(x,p);return;}
if(T[x].tag)pb(x); LL mid=(T[x].a+T[x].b)>>1;
if(mid>=a&&T[x].l)change(T[x].l,a,b,p);
if(mid<b&&T[x].r)change(T[x].r,a,b,p);up(x);
}
LL query(LL x,LL a,LL b){
if(T[x].a>=a&&T[x].b<=b)return T[x].sum;
if(T[x].tag)pb(x);LL mid=(T[x].a+T[x].b)>>1,res=0;
if(mid>=a&&T[x].l)res+=query(T[x].l,a,b);
if(mid<b&&T[x].r)res+=query(T[x].r,a,b);
return res;
}
LL chain(int x,int y){
LL res=0;
for(;top[x]!=top[y];x=f[top[x]]){
if(d[top[x]]<d[top[y]]){int z=x;x=y;y=z;}
res+=query(1,st[top[x]],st[x]);
}if(d[x]<d[y]){int z=x;x=y;y=z;}
res+=query(1,st[y],st[x]);
return res;
}
int op;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",a+i);
for(int i=1;i<n;i++){
scanf("%d%d",&x,&y);
add(x,y);add(y,x);
}dfs(1);dfs2(1,1);
build(1,dfn);
for(int i=1;i<=n;i++)change(1,st[i],st[i],a[i]);
for(int i=1;i<=m;i++){
scanf("%d",&op);
if(op==1){
scanf("%d%d",&x,&y);
change(1,st[x],st[x],y);
}else if(op==2){
scanf("%d%d",&x,&y);
change(1,st[x],en[x],y);
}else{
scanf("%d",&x);
printf("%lld\n",chain(1,x));
}
}return 0;
}

  

BZOJ 4034 [HAOI2015]T2(树链剖分)的更多相关文章

  1. Bzoj 4034: [HAOI2015]T2 树链剖分,子树问题,dfs序

    4034: [HAOI2015]T2 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1841  Solved: 598[Submit][Status] ...

  2. BZOJ 4034: [HAOI2015]T2( 树链剖分 )

    树链剖分...子树的树链剖分序必定是一段区间 , 先记录一下就好了 ------------------------------------------------------------------ ...

  3. [BZOJ4034] [HAOI2015] T2 (树链剖分)

    Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所 ...

  4. JZYZOJ1539[haoi2015]T2 树链剖分

    http://172.20.6.3/Problem_Show.asp?id=1539 在学校的OJ又写了一次,RE了好多次,原来haoi的时候这道题需要开栈+快读,裸数据结构30分,加上快读50分.o ...

  5. bzoj 4034 [HAOI2015] T2(树链剖分,线段树)

    4034: [HAOI2015]T2 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1536  Solved: 508[Submit][Status] ...

  6. bzoj 4034: [HAOI2015]T2

    4034: [HAOI2015]T2 Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操 ...

  7. BZOJ 2243: [SDOI2011]染色 [树链剖分]

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6651  Solved: 2432[Submit][Status ...

  8. [BZOJ - 2819] Nim 【树链剖分 / DFS序】

    题目链接: BZOJ - 2819 题目分析 我们知道,单纯的 Nim 的必胜状态是,各堆石子的数量异或和不为 0 .那么这道题其实就是要求求出树上的两点之间的路径的异或和.要求支持单点修改. 方法一 ...

  9. BZOJ.4515.[SDOI2016]游戏(树链剖分 李超线段树)

    BZOJ 洛谷 每次在路径上加的数是个一次函数,容易看出是树剖+李超线段树维护函数最小值.所以其实依旧是模板题. 横坐标自然是取个确定的距离标准.取每个点到根节点的距离\(dis[i]\)作为\(i\ ...

随机推荐

  1. JVM学习之类的卸载机制

    类的生命周期 当Sample类被加载.连接和初始化后,它的生命周期就开始了,当代表Sample类的Class对象不再被引用,即不可触及时,Class对象就会结束生命周期,Sample类在方法区内的数据 ...

  2. 独立版Jexus

    一:下载资源包 把 jexus压缩包下载到linux临时文件夹中. cd /tmp wget linuxdot.net/down/jexus--x64.tar.gz 二,解压: tar -zxvf j ...

  3. Java中的String,StringBuffer,StringBuilder详解与区别

    1.String Java中string类是不可变的,其中在声明的源代码中用的final,所以只能声明一次.所以每次在明面上的改变其实是重新生成一个String对象,指针指向新的String对象.同时 ...

  4. view里文书删除时报错的解决案

  5. [问题解决] ubuntu server12.04 按ctrl+alt+F1没用

    错误: ubuntu server12.04 想从图形化界面变成命令行界面时候,按ctrl+alt+F1没用 发生场景: 虚拟机下的ubuntu server12.04 解决方案: 因为ctrl+al ...

  6. 要不要用STL的问题——真理是越辩越明的~

    QtWidgets的维护者 Marc Mutz 有一篇博客比较详尽的介绍了 Qt自己的容器.介绍了何时用什么比较好https://marcmutz.wordpress.com/effective-qt ...

  7. HDU 5972 Regular Number(ShiftAnd+读入优化)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5972 [题目大意] 给出一个字符串,找出其中所有的符合特定模式的子串位置,符合特定模式是指,该子串 ...

  8. Linux-VPN安装配置方法

    VNP服务器IP地址为:192.168.6.6 一.编译安装:   注意:可能需要ppp.libcap.libcap-devel ncurses-devel RPM 包支持,如果没有请安装 libca ...

  9. 面向对象程序设计-C++_课时14对象组合_课时15继承

    对象组合,就是一个类的对象作为另外一个类的成员,涉及类的对象,对象是实体,玩实 继承,涉及类,类是概念,玩虚 public: 所有人都可以接触 private: 数据放private protecte ...

  10. location的用法

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...