bzoj 4034 [HAOI2015]树上操作 入栈出栈序+线段树 / 树剖 维护到根距离和
题目大意
有一棵点数为 N 的树,以点 1 为根,且树点有边权。然后有 M 个
操作,分为三种:
操作 1 :把某个节点 x 的点权增加 a 。
操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a 。
操作 3 :询问某个节点 x 到根的路径中所有点的点权和。
分析
真就是一见到这类题就得先写一次,发现错,再写一次
想清楚再写行不 -.-
方法1:树剖
方法2:入栈出栈序
入栈+,出栈 -
一个点x到根路径和,就是sum[1,in[x]]
如何区间修改呢
线段树上记录区间中 +的个数减去 -的个数
就是一次修改中权值总体要增加多少个delta
具体见代码
solution
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long LL;
const int M=100007;
inline int rd(){
int x=0;bool f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
for(;isdigit(c);c=getchar()) x=x*10+c-48;
return f?x:-x;
}
LL val[M];
int n,m;
int g[M],te;
struct edge{
int y,nxt;
}e[M<<1];
void addedge(int x,int y){
e[++te].y=y;e[te].nxt=g[x];g[x]=te;
}
int st[M],ed[M],ty[M<<1],dd[M<<1],tdfn=0;
void dfs(int x,int fa){
st[x]=++tdfn;
ty[tdfn]=1;
dd[tdfn]=val[x];
int p,y;
for(p=g[x];p;p=e[p].nxt)
if((y=e[p].y)!=fa) dfs(y,x);
ed[x]=++tdfn;
ty[tdfn]=-1;
dd[tdfn]=-val[x];
}
struct seg{
LL sum,tag,sz;
}a[M<<3];
void pushup(int x){
a[x].sum=a[x<<1].sum+a[x<<1|1].sum;
}
void totag(int x,LL d){
a[x].sum+=d*a[x].sz;
a[x].tag+=d;
}
void pushdown(int x){
if(a[x].tag){
totag(x<<1,a[x].tag);
totag(x<<1|1,a[x].tag);
a[x].tag=0;
}
}
void build(int x,int l,int r){
if(l==r){
a[x].sum=dd[l];
a[x].sz=ty[l];
a[x].tag=0;
return;
}
int mid=l+r>>1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
pushup(x);
a[x].sz=a[x<<1].sz+a[x<<1|1].sz;
}
void add(int x,int l,int r,int tl,int tr,LL d){
if(tl<=l&&r<=tr){
totag(x,d);
return;
}
int mid=l+r>>1;
pushdown(x);
if(tl<=mid) add(x<<1,l,mid,tl,tr,d);
if(mid<tr) add(x<<1|1,mid+1,r,tl,tr,d);
pushup(x);
}
LL get(int x,int l,int r,int tl,int tr){
if(tl<=l&&r<=tr) return a[x].sum;
int mid=l+r>>1;
pushdown(x);
LL res=0;
if(tl<=mid) res+=get(x<<1,l,mid,tl,tr);
if(mid<tr) res+=get(x<<1|1,mid+1,r,tl,tr);
return res;
}
int main(){
int i,kd,x,y;
n=rd(); m=rd();
for(i=1;i<=n;i++) val[i]=rd();
for(i=1;i<n;i++){
x=rd(),y=rd();
addedge(x,y);
addedge(y,x);
}
dfs(1,0);
build(1,1,2*n);
while(m--){
kd=rd();
if(kd==1){
x=rd(); y=rd();
add(1,1,2*n,st[x],st[x],y);
add(1,1,2*n,ed[x],ed[x],y);
}
else if(kd==2){
x=rd(); y=rd();
add(1,1,2*n,st[x],ed[x],y);
}
else{
x=rd();
printf("%lld\n",get(1,1,2*n,1,st[x]));
}
}
return 0;
}
bzoj 4034 [HAOI2015]树上操作 入栈出栈序+线段树 / 树剖 维护到根距离和的更多相关文章
- BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )
BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 ...
- bzoj 4034: [HAOI2015]树上操作 树链剖分+线段树
4034: [HAOI2015]树上操作 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 4352 Solved: 1387[Submit][Stat ...
- bzoj 4034: [HAOI2015]树上操作 (树剖+线段树 子树操作)
4034: [HAOI2015]树上操作 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 6779 Solved: 2275[Submit][Stat ...
- [BZOJ]4034: [HAOI2015]树上操作
[HAOI2015]树上操作 传送门 题目大意:三个操作 1:a,b,c b节点权值+c 2:a,b,c 以b为根的子树节点权值全部+c 3:a,b 查询b到根路径的权值和. 题解:树链剖分 操作1 ...
- BZOJ 4034 [HAOI2015]树上操作(欧拉序+线段树)
题意: 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有点的点权都增 ...
- BZOJ 4034: [HAOI2015]树上操作 [欧拉序列 线段树]
题意: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a . 操作 3 :询问某个节点 x 到根的路径中所有点的点权和. 显然树链剖分可做 ...
- 洛谷 P3178 BZOJ 4034 [HAOI2015]树上操作
题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a .操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 ...
- BZOJ 4034 [HAOI2015]树上操作 线段树+树剖或dfs
题意 直接照搬原题面 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所 ...
- bzoj 4034: [HAOI2015]树上操作——树链剖分
Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中 ...
随机推荐
- 字符编码:BSTR
typedef wchar_t WCHAR; typedef WCHAR OLECHAR; typedef OLECHAR __RPC_FAR *BSTR;;
- wine卸载
Wine手动卸载,出现殘留,导致安装其他软件也不成功. 错误如下: 正在读取软件包列表... 完成正在分析软件包的依赖关系树 正在读取状态信息... 完成 您也许需要运行“ap ...
- C++容器类-list
C++ 表(List容器类) 一.概念 头文件:#include <list> 又叫链表,是一种双线性链表,只能顺序访问(从前往后或从后往前) 他不支持随机访问. 二.方法 #includ ...
- DB2中创建表
CONNECT TO TEST; CREATE TABLE DB2ADMIN.PERSON ( ID BIGINT NOT NULL , NAME BIGINT , FLAG BIGINT , ADD ...
- iOS中的数据存储方式_Plist
plist文件只能存储OC常用数据类型(NSString.NSDictionary.NSArray.NSData.NSNumber等类型)而不能直接存储自定义模型对象; 我们拿NSData举例: /* ...
- 35. Search Insert Position@python
Given a sorted array and a target value, return the index if the target is found. If not, return the ...
- JAVA实现webSocket网页聊天室
一.什么是webSocket WebSocket 是一种网络通信协议,是持久化协议.RFC6455 定义了它的通信标准. WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全 ...
- 洛谷 P1228 【地毯填补问题】
事实上感觉四个的形状分别是这样: spj报错: 1:c 越界 2:x,y 越界 3:mp[x][y] 已被占用 4:mp[x][y] 从未被使用 题解: 初看这个问题,似乎无从下手,于是我们可以先考虑 ...
- knn算法之预测数字
训练算法并对算法的准确值准确率进行估计 #导入相应模块 import numpy as npimport pandas as pdimport matplotlib.pyplot as plt%mat ...
- Angular - Can't bind to 'ngModel' since it isn't a known property of 'input'.
用[(ngModel)]="xxx"双向绑定,如:控制台报错:Can't bind to 'ngModel' since it isn't a known property of ...