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. 第3节 mapreduce高级:12、mapreduce相关的参数调整

    5.1 多job串联 一个稍复杂点的处理逻辑往往需要多个mapreduce程序串联处理,多job的串联可以借助mapreduce框架的JobControl实现 示例代码: ControlledJob ...

  2. Java中Arrays作用

    Arrays类是提供对数组进行排序.查询和修改等操作方法的工具类.(Arrays:尽可进行数组升序排序) 格式:Arrays.sort(数组名); Package Java; import java. ...

  3. mysql jdbc驱动与java 版本对应关系

    当使用某些密码套件时,Connector/J5.1需要JRE 1.8.x才能使用SSL/TLS连接到MySQL 5.6,5.7和8.0.

  4. 自动下载相对应的jar包

    一.去到需要的 maven下载地址 http://mvnrepository.com/artifact/org.apache.struts/struts2-core/2.5.13 二.然后去到 pom ...

  5. tomcat无法正确解析请求参数

    24-Mar-2018 14:11:20.564 INFO [http-nio-8080-exec-3] org.apache.coyote.http11.Http11Processor.servic ...

  6. 用bootstrap_table实现html 表格翻页

    资料网址 百度经验:HTML表格分页,table分页怎么做? 官网(下载链接和官方教程) (右上角可选语言) 文档 以下内容基本摘自官网 用法 1.下载资料 官网下载: 下下来长这样: 其中src里面 ...

  7. JavaScript学习---简易图片轮播

    效果如下: 图片定时轮播 点击左右控制显示下一张或上一张图片 index.html文件 <html> <head> <title> js编写实现幻灯片效果 < ...

  8. mongodb shell 无法删除问题

    1.MongoDB Shell中退格键使用的问题. 利用SecureCRT工具访问linux的时候,在使用MongoDB的交互式shell的时候,退格键(Backspace)无法使用,导致无 法修改输 ...

  9. mysql proxy讀寫分流(二)-加入RW splitting

    上一篇中提到 安裝LUA及MySQL Proxy後,接下來就是RW splitting(讀寫分流)的部份了 整體的概念圖跟上一篇MySQL Proxy安裝方式相同,丫忠再補上一個對應port的圖表: ...

  10. [COJ0968]WZJ的数据结构(负三十二)

    [COJ0968]WZJ的数据结构(负三十二) 试题描述 给你一棵N个点的无根树,边上均有权值,每个点上有一盏灯,初始均亮着.请你设计一个数据结构,回答M次操作. 1 x:将节点x上的灯拉一次,即亮变 ...