http://www.lydsy.com/JudgeOnline/problem.php?id=4034

https://www.luogu.org/problemnew/show/P3178

有一棵点数为 N 的树,以点 1 为根,且树点有边权。然后有 M 个
操作,分为三种:
操作 1 :把某个节点 x 的点权增加 a 。
操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a 。
操作 3 :询问某个节点 x 到根的路径中所有点的点权和。

树剖板子。不会写树链剖分的请看:http://www.cnblogs.com/luyouqi233/p/7886709.html

试图默写结果被1和l搞反然后gg。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int N=1e5+;
inline int read(){
int X=,w=;char ch=;
while(ch<''||ch>''){w|=ch=='-';ch=getchar();}
while(ch>=''&&ch<='')X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
struct node{
int to,nxt;
}edge[*N];
int head[N],cnt,tot,n,q;
inline void add(int u,int v){
edge[++cnt].to=v;edge[cnt].nxt=head[u];head[u]=cnt;
}
int fa[N],son[N],size[N],val[N],dep[N],idx[N],pos[N],top[N];
ll sum[*N],lazy[*N];
void dfs1(int u){
size[u]=;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(v==fa[u])continue;
fa[v]=u;dep[v]=dep[u]+;
dfs1(v);
size[u]+=size[v];
if(!son[u]||size[son[u]]<size[v])son[u]=v;
}
}
void dfs2(int u,int anc){
pos[u]=++tot;
idx[tot]=u;
top[u]=anc;
if(!son[u])return;
dfs2(son[u],anc);
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(v==fa[u]||v==son[u])continue;
dfs2(v,v);
}
}
void init(){
dep[]=;
dfs1();
dfs2(,);
}
void push(int a,int l,int r){
int mid=(l+r)>>;
if(lazy[a]){
lazy[a*]+=lazy[a];
lazy[a*+]+=lazy[a];
sum[a*]+=(mid-l+)*lazy[a];
sum[a*+]+=(r-mid)*lazy[a];
lazy[a]=;
}
}
void build(int a,int l,int r){
if(l==r){
sum[a]=val[idx[l]];
return;
}
int mid=(l+r)>>;
build(a*,l,mid);
build(a*+,mid+,r);
sum[a]=sum[a*]+sum[a*+];
}
ll query(int a,int l,int r,int l1,int r1){
if(r1<l||r<l1)return ;
if(l1<=l&&r<=r1)return sum[a];
int mid=(l+r)>>;
push(a,l,r);
return query(a*,l,mid,l1,r1)+query(a*+,mid+,r,l1,r1);
}
ll pathquery(int x,int y){
ll res=;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
res+=query(,,n,pos[top[x]],pos[x]);
x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
res+=query(,,n,pos[x],pos[y]);
return res;
}
void modify(int a,int l,int r,int l1,int r1,ll p){
if(r1<l||r<l1)return;
if(l1<=l&&r<=r1){
sum[a]+=(r-l+)*p;
lazy[a]+=p;
return;
}
int mid=(l+r)>>;
push(a,l,r);
modify(a*,l,mid,l1,r1,p);
modify(a*+,mid+,r,l1,r1,p);
sum[a]=sum[a*]+sum[a*+];
}
int main(){
n=read(),q=read();
for(int i=;i<=n;i++)val[i]=read();
for(int i=;i<n;i++){
int u=read(),v=read();
add(u,v);add(v,u);
}
init();
build(,,n);
while(q--){
int op=read();
if(op==){
int x=read(),a=read();
modify(,,n,pos[x],pos[x],a);
}
if(op==){
int x=read(),a=read();
modify(,,n,pos[x],pos[x]+size[x]-,a);
}
if(op==){
int x=read();
printf("%lld\n",pathquery(x,));
}
}
return ;
}

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

BZOJ4034:[HAOI2015]树上操作——题解的更多相关文章

  1. bzoj4034: [HAOI2015]树上操作(树剖)

    4034: [HAOI2015]树上操作 题目:传送门 题解: 树剖裸题: 麻烦一点的就只有子树修改(其实一点也不),因为子树编号连续啊,直接改段(记录编号最小和最大) 开个long long 水模版 ...

  2. bzoj千题计划242:bzoj4034: [HAOI2015]树上操作

    http://www.lydsy.com/JudgeOnline/problem.php?id=4034 dfs序,树链剖分 #include<cstdio> #include<io ...

  3. bzoj4034[HAOI2015]树上操作 树链剖分+线段树

    4034: [HAOI2015]树上操作 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 6163  Solved: 2025[Submit][Stat ...

  4. BZOJ4034 [HAOI2015]树上操作 树链剖分

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ4034 题意概括 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三 ...

  5. BZOJ4034: [HAOI2015]树上操作

    这题把我写吐了...代码水平还是太弱鸡了啊... 这题就是先给你一些点,以及点权.然后给你一些向边构成一颗树,树的根节点是1. 然后给定三个操作 第一个是把指定节点的权值+W 第二个是把指定节点X为根 ...

  6. BZOJ4034[HAOI2015]树上操作——树链剖分+线段树

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

  7. [luogu3178][bzoj4034][HAOI2015]树上操作

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

  8. [bzoj4034][HAOI2015]树上操作——树状数组+dfs序

    Brief Description 您需要设计一种数据结构支持以下操作: 把某个节点 x 的点权增加 a . 把某个节点 x 为根的子树中所有点的点权都增加 a . 询问某个节点 x 到根的路径中所有 ...

  9. BZOJ4034 [HAOI2015]树上操作+DFS序+线段树

    参考:https://www.cnblogs.com/liyinggang/p/5965981.html 题意:是一个数据结构题,树上的,用dfs序,变成线性的: 思路:对于每一个节点x,记录其DFS ...

随机推荐

  1. 解决Entity Framework查询匿名对象后的跨域访问的一种方式

    在Entity Framework中,可以使用lambda表达式进行对数据的查询,而且可以将查询结果直接映射为对象或者对象列表,这极大的提高的开发速度,并且使数据层的数据更加方便处理和传递.但是很多时 ...

  2. Weka java.lang.reflect.InvocationTargetException

    在用Weka导入数据的时候报 java.lang.reflect.InvocationTargetException 错误,Weka运行包没有给出详细的错误信息,无法查到. 直接调试Weka源码,发现 ...

  3. MySQL☞关联查询

    关联查询:所需要的数据来源于多张表,通过表的连接查询(关联查询)来查询多张表中的数据 格式: select 别名1 . */列名 , 别名2 . */列名 from 表名1  别名1 , 表名2  别 ...

  4. tpo-09 C2 Return a sociology book

    check out 在library里有借书的意思 第 1 段 1.Listen to a conversation between a student and a librarian employe ...

  5. lesson 16 Mary had a little lamb

    lesson 16 Mary had a little lamb a little + 可数 小的;+ 不可数 少量的 对于动物在幼时都有不同的称呼: calf 小牛 lamb 羊羔 piglet 小 ...

  6. 爬虫1.5-ajax数据爬取

    目录 爬虫-ajax数据爬取 1. ajax数据 2. selenium+chromedriver知识准备 3. selenium+chromedriver实战拉勾网爬虫代码 爬虫-ajax数据爬取 ...

  7. CMD Markdown basic & Math Cheatsheet

    CMD Markdown basic & Math Cheatsheet I am using CMD Markdown both at work and for study.You can ...

  8. POJ 2987 Firing(最大流最小割の最大权闭合图)

    Description You’ve finally got mad at “the world’s most stupid” employees of yours and decided to do ...

  9. 《梦断代码Dreaming In Code》阅读笔记(一)

    第0章!干得漂亮! 这是我看到这本书冒出来的第一个想法.身为计算机系的学生,对于从0开始的任何事情,都感到格外亲切. 进入阅读之后,疑惑.惊讶.感叹渐渐取代了之前轻松的心情,原来做软件竟是攀越一座又一 ...

  10. java---Map接口实现类

    Map是一个双列集合接口,如果实现了Map接口,特点是数据以键值对形式存在,键不可重复,值可以重复.java中主要有HashMap.TreeMap.Hashtable.本文主要介绍Map的接口方法: ...