[BZOJ]4034: [HAOI2015]树上操作
[HAOI2015]树上操作
题目大意:三个操作 1:a,b,c b节点权值+c 2:a,b,c 以b为根的子树节点权值全部+c 3:a,b 查询b到根路径的权值和。
题解:树链剖分
操作1 ,2是区间修改,3是区间和。
看题解都提示开long long 了,我也开了,可是整形相乘赋值给Long long时爆了。
简直要哭晕了。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 500005
#define LL long long
using namespace std; int sumedge,cnt,n,m;
int head[maxn],size[maxn],dad[maxn],deep[maxn],top[maxn];
int tpos[maxn],re[maxn],w[maxn]; struct Tree{
int l,r;LL sum,s;
}tr[maxn<<]; struct Edge{
int x,y,nxt;
Edge(int x=,int y=,int nxt=):
x(x),y(y),nxt(nxt){}
}edge[maxn<<]; void read(int &x){
char ch=getchar();x=;int f=;
for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';
x=x*f;
} void add(int x,int y){
edge[++sumedge]=Edge(x,y,head[x]);
head[x]=sumedge;
} void dfs(int x){
size[x]=;deep[x]=deep[dad[x]]+;
for(int i=head[x];i;i=edge[i].nxt){
int v=edge[i].y;
if(v==dad[x])continue;
dad[v]=x;dfs(v);
size[x]+=size[v];
}
} void dfs_(int x){
int s=;tpos[x]=++cnt;re[cnt]=x;
if(!top[x])top[x]=x;
for(int i=head[x];i;i=edge[i].nxt){
int v=edge[i].y;
if(v!=dad[x]&&size[v]>size[s])s=v;
}
if(s){
top[s]=top[x];
dfs_(s);
}
for(int i=head[x];i;i=edge[i].nxt){
int v=edge[i].y;
if(v!=dad[x]&&v!=s)dfs_(v);
}
} void pushup(int rt){
tr[rt].sum=tr[rt<<].sum+tr[rt<<|].sum;
return;
} void pushdown(int rt){
if(!tr[rt].s)return;
tr[rt<<].s+=tr[rt].s;tr[rt<<|].s+=tr[rt].s;
tr[rt<<].sum+=(LL)(tr[rt<<].r-tr[rt<<].l+)*tr[rt].s;
tr[rt<<|].sum+=(LL)(tr[rt<<|].r-tr[rt<<|].l+)*tr[rt].s;
tr[rt].s=;return;
} void build(int rt,int l,int r){
tr[rt].l=l;tr[rt].r=r;
if(l==r){
tr[rt].sum=w[re[l]];
return;
}
int mid=(l+r)>>;
build(rt<<,l,mid);build(rt<<|,mid+,r);
pushup(rt);
} void change(int rt,int l,int r,int ql,int qr,int p){
if(l>=ql&&r<=qr){
tr[rt].sum+=(LL)(r-l+)*p;
tr[rt].s+=p;
return;
}
pushdown(rt);
int mid=(l+r)>>;
if(ql<=mid)change(rt<<,l,mid,ql,qr,p);
if(qr>mid)change(rt<<|,mid+,r,ql,qr,p);
pushup(rt);
} LL query_sum(int rt,int l,int r,int ql,int qr){
if(l>=ql&&r<=qr){
return tr[rt].sum;
}
pushdown(rt);
int mid=(l+r)>>;LL ans=;
if(ql<=mid)ans+=query_sum(rt<<,l,mid,ql,qr);
if(qr>mid)ans+=query_sum(rt<<|,mid+,r,ql,qr);
return ans;
} LL query(int x){
LL ret=;
for(;top[x]!=;){
ret+=query_sum(,,n,tpos[top[x]],tpos[x]);
x=dad[top[x]];
}
ret+=query_sum(,,n,,tpos[x]);
return ret;
} int main(){
read(n);read(m);
for(int i=;i<=n;i++)read(w[i]);
for(int i=;i<n;i++){
int x,y;
read(x);read(y);
add(x,y);add(y,x);
}
dfs();dfs_();build(,,n);
for(int i=;i<=m;i++){
int od,x,a;
read(od);read(x);
if(od==){
read(a);
change(,,n,tpos[x],tpos[x],a);
}else if(od==){
read(a);
change(,,n,tpos[x],tpos[x]+size[x]-,a);
}else if(od==){
printf("%lld\n",query(x));
}
}
return ;
}
AC
[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]树上操作 入栈出栈序+线段树 / 树剖 维护到根距离和
题目大意 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有点的点权都 ...
- BZOJ 4034 [HAOI2015]树上操作(欧拉序+线段树)
题意: 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有点的点权都增 ...
- BZOJ 4034: [HAOI2015]树上操作 [欧拉序列 线段树]
题意: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a . 操作 3 :询问某个节点 x 到根的路径中所有点的点权和. 显然树链剖分可做 ...
- bzoj 4034: [HAOI2015]树上操作——树链剖分
Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中 ...
- BZOJ 4034[HAOI2015]树上操作(树链剖分)
Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a .操作 2 :把某个节点 x 为根的子树中所有点 ...
- 洛谷 P3178 BZOJ 4034 [HAOI2015]树上操作
题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a .操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 ...
随机推荐
- securecrt重建
CRT重建步骤: 重装系统或者重装CRT后,面临找回以前的session记录信息.记住下面的步骤,再也不担心丢session了! 1.备份关键文件(config文件夹) (1)配置文件默认文件路径 ...
- Unable to handle kernel NULL pointer dereference at virtual address 00000000【转】
本文转载自:https://blog.csdn.net/hpu11/article/details/72628052 这说明是非法指针的使用,才导致系统出错. [ 1023.510000] Unabl ...
- Linux系统中使用netcat命令的奇技淫巧
netcat是网络工具中的瑞士军刀,它能通过TCP和UDP在网络中读写数据.通过与其他工具结合和重定向,你可以在脚本中以多种方式使用它.使用netcat命令所能完成的事情令人惊讶. netcat所做的 ...
- [BZOJ2730]矿场搭建
Description 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤点设立救援出口,使得无论哪一 ...
- java中Vector类的常用方法
Vector类是实现List接口,所以继承的方法就不在这里讲了 https://www.cnblogs.com/xiaostudy/p/9503199.html public void add(int ...
- ssh整合学习(1)
Hibernate框架 1 hibernate核心配置文件 (0)orm思想 -对象关系映射 (1)数据库信息 (2)hibernate信息 (3)映射配置 (4)hibernate核心配置文件 -如 ...
- Go语言 进程、线程、轻量级进程、协程和go中的Goroutine 那些事儿
原文:http://www.cnblogs.com/shenguanpu/archive/2013/05/05/3060616.html 电话面试被问到go的协程,曾经的军伟也问到过我协程.虽然用py ...
- shell read
#!/bin/bash read -p "Enter your account:" acct #提示用户输入用户名read -s -p "Enter your passw ...
- javascript 对象简单介绍(二)
JavaScript Array(数组) 对象数组对象的作用是:使用单独的变量名来存储一系列的值. 什么是数组?数组对象是使用单独的变量名来存储一系列的值.如果你有一组数据(例如:车名字),存在单独变 ...
- eclipse indigo 安装 Eclipse Marketplace Client
打开 eclipse,help--Eclipse Marketplace Client就能找到 有的eclipse中没有这个功能就需手动添加Eclipse Marketplace Client. he ...