siz[v]表示以v为根的子树的节点数

top[v]表示v所在的重链的顶端节点

fa[v]表示v的父亲

pos[v]表示v的父边标号

mx[v]表示v的子树中边的标号最大的那条边

参考:http://blog.sina.com.cn/s/blog_6974c8b20100zc61.html

题意:

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

操作,分为三种:
操作 1 :把某个节点 x 的点权增加 a 。
操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a 。
操作 3 :询问某个节点 x 到根的路径中所有点的点权和。

第一次写树链剖分。。

 #include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std; typedef long long LL; #define N 100010 int id;
int fa[N],siz[N],top[N];
int head[N],pos[N],mx[N],v[N];
LL sum[N<<],add[N<<]; struct Node
{
int to,next;
}e[N<<];
int cnt; int n,m;
int uu,vv; int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
} void link(int x,int y)
{
e[++cnt]=(Node){y,head[x]};
head[x]=cnt;
} void dfs(int x)
{
siz[x]=;
for (int i=head[x];i;i=e[i].next)
if (e[i].to!=fa[x])
{
fa[e[i].to]=x;
dfs(e[i].to);
siz[x]+=siz[e[i].to];
mx[x]=max(mx[x],mx[e[i].to]);
}
} void dfs2(int x,int cha)
{
top[x]=cha;pos[x]=mx[x]=++id;
int k=;
for(int i=head[x];i;i=e[i].next)
if(e[i].to!=fa[x]&&siz[e[i].to]>siz[k])
k=e[i].to;
if(k)
{
dfs2(k,cha);mx[x]=max(mx[x],mx[k]);
}
for(int i=head[x];i;i=e[i].next)
if(e[i].to!=fa[x]&&e[i].to!=k)
{
dfs2(e[i].to,e[i].to);
mx[x]=max(mx[x],mx[e[i].to]);
}
} void pushup(int now)
{
sum[now]=sum[now<<]+sum[now<<|];
} void pushdown(int nowl,int nowr,int now)
{
if (nowl==nowr)
return;
int mid=(nowl+nowr)>>;
LL t=add[now];
add[now]=;
add[now<<]+=t;
add[now<<|]+=t;
sum[now<<]+=t*(mid-nowl+);
sum[now<<|]+=t*(nowr-mid);
} void update(int nowl,int nowr,int now,int l,int r,LL d)
{
if (add[now])
pushdown(nowl,nowr,now);
if (nowl==l && nowr==r)
{
add[now]+=d;
sum[now]+=(nowr-nowl+)*d;
return ;
}
int mid=(nowl+nowr)>>;
if (l<=mid)
update(nowl,mid,now<<,l,min(r,mid),d);
if (r>mid)
update(mid+,nowr,now<<|,max(l,mid+),r,d);
pushup(now);
} LL query(int nowl,int nowr,int now,int l,int r)
{
if (add[now])
pushdown(nowl,nowr,now);
if (nowl==l && nowr==r)
return sum[now];
int mid=(nowl+nowr)>>;
LL ans=;
if (l<=mid)
ans+=query(nowl,mid,now<<,l,min(mid,r));
if (r>mid)
ans+=query(mid+,nowr,now<<|,max(mid+,l),r);
return ans;
} LL query(int x)
{
LL ans=;
while (top[x]!=)
{
ans+=query(,n,,pos[top[x]],pos[x]);
x=fa[top[x]];
}
ans+=query(,n,,,pos[x]);
return ans;
} int main()
{
n=read(),m=read();
for (int i=;i<=n;i++)
v[i]=read();
for (int i=;i<n;i++)
{
uu=read(),vv=read();
link(uu,vv);
link(vv,uu);
}
dfs();
dfs2(,);
for (int i=;i<=n;i++)
update(,n,,pos[i],pos[i],v[i]);
int askd,x,a;
while (m--)
{
askd=read(),x=read();
if (askd==)
{
a=read();
update(,n,,pos[x],pos[x],a);
}
if (askd==)
{
a=read();
update(,n,,pos[x],mx[x],a);
}
if (askd==)
printf("%lld\n",query(x));
}
return ;
}

【bzoj4034】[HAOI2015]T2的更多相关文章

  1. 【BZOJ4034】[HAOI2015]树上操作 树链剖分+线段树

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

  2. 【bzoj4034】[HAOI2015]树上操作

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

  3. 【BZOJ4036】[HAOI2015]按位或 FWT

    [BZOJ4036][HAOI2015]按位或 Description 刚开始你有一个数字0,每一秒钟你会随机选择一个[0,2^n-1]的数字,与你手上的数字进行或(c++,c的|,pascal的or ...

  4. 【BZOJ4033】[HAOI2015]树上染色 树形DP

    [BZOJ4033][HAOI2015]树上染色 Description 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并将其他的N-K个点染 ...

  5. 【NOIP2016】DAY1 T2 天天爱跑步

    [NOIP2016]DAY1 T2 天天爱跑步 Description 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.?天天爱跑步?是一个养成类游戏,需要玩家每天按时 ...

  6. 【BZOJ4034】T2(树链剖分)

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

  7. 【BZOJ4034】【HAOI2015】树上操作

    题目请自行查阅传送门. 典型的树剖题,线段树维护操作,记一下子树在线段树内范围即可. 时间复杂度:\( O(m \log^{2} n) \) #include <stdio.h> #def ...

  8. 【SRM】649 t2

    题意 一个数列\(A\),数的范围均在\([0, 2^N-1]\)内,求一个\(B\),使得新生成的数列\(C\)中逆序对最多(\(C_i = A_i xor B\)),输出最多的逆序对.(\(|A| ...

  9. 【nowcoder】 4th T2 区间

    题目链接:https://www.nowcoder.com/acm/contest/175/B 当你为时间复杂度挠头的时候 别人已经33行拿满分了 #include<cstdio> #in ...

随机推荐

  1. React开发实时聊天招聘工具 -第四章 Redux

    复杂以后 setState 就不太方便了 所以使用Redux来管理 React只负责View. Store.State.Dispatch.Reducer reducer(state,action) { ...

  2. 空循环导致CPU使用率很高

    业务背景 业务背景就是需要将多张业务表中的数据增量同步到一张大宽表中,后台系统基于这张大宽表开展业务,所以就开发了一个数据同步工具,由中间件采集binlog消息到kafka里,然后我去消费,实现增量同 ...

  3. PS一些技巧

    色阶的解决办法 我们做效果图的时候经常会使用大面积渐变,时常会出现比较严重的色阶问题,通常出现这些明显色阶的时候,可以通过使用高斯模糊对色阶进行模糊化处理. 在使用PS CC的过程中,笔者经常遇到假死 ...

  4. C51 使用端口 个人笔记

    使用整个端口的8个引脚: 八个引脚,需要8位2进制,2位十六进制 #define P0 led led = 0x3f; //led = ~0x3f; 使用某个端口的某一个引脚 sbit led = P ...

  5. 使用IDEA部署Myeclipse项目----亲测有效

    使用IDEA部署Myeclipse项目-----https://blog.csdn.net/u010570551/article/details/51510447

  6. JavaEE JDBC 怎么加载驱动

    JDBC怎么加载驱动 @author ixenos 分析 1.JDBC是一套连接数据库的接口(放在java.util.sql.Driver类中),不同的数据库依此接口各自实现Java连接到数据库的操作 ...

  7. 【转】Selenium专题—JQuery选择器

    juqery选择器是jquery库中非常重要的功能.jquery选择器是基于CSS1-3选择器,加上一些额外的选择器.这些选择器和CSS选择器的使用方法很相似,允许开发人员简单快速的识别页面上的元素. ...

  8. noip模拟赛 Nephren Ruq Insania

    题目背景 大样例下发链接: https://pan.baidu.com/s/1nuVpRS1 密码: sfxg 注意:本题大样例4的输出文件修改为 https://pan.baidu.com/s/1b ...

  9. [K/3Cloud] 分录行复制和新增行的冲突如何处理

    新增行:执行AfterCreateNewEntryRow,这个函数里面对一些数据进行处理(比如字段给上默认值): 复制行:复制行过程中希望这些字段能够得到我修改行信息后的数据,如果不处理,执行到Aft ...

  10. [NOIP2004] 提高组 洛谷P1091 合唱队形

    题目描述 N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形. 合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2, ...