BZOJ 4034: [HAOI2015]树上操作 [欧拉序列 线段树]
题意:
操作 1 :把某个节点 x 的点权增加 a 。
操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a 。
操作 3 :询问某个节点 x 到根的路径中所有点的点权和。
显然树链剖分可做,但我是来练欧拉序列的
和splay维护一样了
其实没大有意义....如果树形态不改变人家树链剖分本来就可以维护子树信息....
唯一的好处就是不会爆栈吧
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define lc x<<1
#define rc x<<1|1
#define mid ((l+r)>>1)
#define lson lc, l, mid
#define rson rc, mid+1, r
#define pii pair<int, int>
#define MP make_pair
#define fir first
#define sec second
typedef long long ll;
const int N=2e5+;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-; c=getchar();}
while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
return x*f;
} int n, Q, op, x, y, a[N];
struct edge{int v, ne;} e[N<<];
int cnt, h[N];
inline void ins(int u, int v) {
e[++cnt]=(edge){v, h[u]}; h[u]=cnt;
e[++cnt]=(edge){u, h[v]}; h[v]=cnt;
}
pii dfn[N]; int dfc, eul[N];
void dfs(int u, int fa) {
dfn[u].fir = ++dfc; eul[dfc] = u;
for(int i=h[u]; i; i=e[i].ne) if(e[i].v != fa) dfs(e[i].v, u);
dfn[u].sec = ++dfc; eul[dfc] = -u;
} struct SegTre {
struct meow{ll sum, tag; int sl, sr;} t[N<<];
inline void merge(int x) {
t[x].sum = t[lc].sum + t[rc].sum;
t[x].sl = t[lc].sl + t[rc].sl;
t[x].sr = t[lc].sr + t[rc].sr;
}
inline void paint(int x, ll v) {
t[x].sum += (t[x].sl - t[x].sr)*v;
t[x].tag += v;
}
inline void pushDown(int x) {
if(t[x].tag) {
paint(lc, t[x].tag);
paint(rc, t[x].tag);
t[x].tag = ;
}
}
void build(int x, int l, int r) {
if(l==r) {
if(eul[l] > ) t[x].sum = a[eul[l]], t[x].sl = ;
else t[x].sum = -a[-eul[l]], t[x].sr = ;
}else {
build(lson);
build(rson);
merge(x);
}
} void Add(int x, int l, int r, int p, int v) {
if(l==r) paint(x, v);
else {
pushDown(x);
if(p<=mid) Add(lson, p, v);
else Add(rson, p, v);
merge(x);
}
}
void Add2(int x, int l, int r, int ql, int qr, ll v) {
if(ql<=l && r<=qr) paint(x, v);
else {
pushDown(x);
if(ql<=mid) Add2(lson, ql, qr, v);
if(mid<qr) Add2(rson, ql, qr, v);
merge(x);
}
}
ll Que(int x, int l, int r, int ql, int qr) {
if(ql<=l && r<=qr) return t[x].sum;
else {
pushDown(x);
ll ans=;
if(ql<=mid) ans += Que(lson, ql, qr);
if(mid<qr) ans += Que(rson, ql, qr);
return ans;
}
}
}seg;
int main() {
freopen("in","r",stdin);
n=read(); Q=read();
for(int i=; i<=n; i++) a[i]=read();
for(int i=; i<n; i++) x=read(), y=read(), ins(x, y);
dfs(, ); seg.build(, , dfc);
for(int i=; i<=Q; i++) {
op=read(); x=read();
if(op==) printf("%lld\n", seg.Que(, , dfc, dfn[].fir, dfn[x].fir));
else{
y=read();
if(op==) seg.Add(, , dfc, dfn[x].fir, y), seg.Add(, , dfc, dfn[x].sec, y);
else seg.Add2(, , dfc, dfn[x].fir, dfn[x].sec, y);
}
}
}
BZOJ 4034: [HAOI2015]树上操作 [欧拉序列 线段树]的更多相关文章
- BZOJ 4034 [HAOI2015]树上操作(欧拉序+线段树)
题意: 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有点的点权都增 ...
- 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 树上操作(树的欧拉序列+线段树)
刷个清新的数据结构题爽一爽? 题意: 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x ...
- [BZOJ]4034: [HAOI2015]树上操作
[HAOI2015]树上操作 传送门 题目大意:三个操作 1:a,b,c b节点权值+c 2:a,b,c 以b为根的子树节点权值全部+c 3:a,b 查询b到根路径的权值和. 题解:树链剖分 操作1 ...
- 洛谷P3178 [HAOI2015]树上操作(dfs序+线段树)
P3178 [HAOI2015]树上操作 题目链接:https://www.luogu.org/problemnew/show/P3178 题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边 ...
- 洛谷 P3178 BZOJ 4034 [HAOI2015]树上操作
题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a .操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 ...
- BZOJ 4034[HAOI2015]树上操作(树链剖分)
Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a .操作 2 :把某个节点 x 为根的子树中所有点 ...
随机推荐
- c语言变量类型联想
int float char *(指针) 已经定义:单个变量 单个相同类型在内存中顺序存放:数组 不同单个类型在内存中顺序存放:结构体 不同类型在内存中自由存放:链表 其中结构体与链表类型需运用时提前 ...
- 010 有顺序的Map的实现类:TreeMap和LinkedHashMap
作者:nnngu GitHub:https://github.com/nnngu 博客园:http://www.cnblogs.com/nnngu 简书:https://www.jianshu.com ...
- [国嵌笔记][011][Linux密码破解]
破解步骤 1.在系统启动时进入grub选项菜单 2.在grub选项菜单中按e进入编辑模式 3.编辑kernel行,添加 /init 1 (表示进入单用户启动模式,在单用户启动模式中不会要求输入密码) ...
- node学习笔记2 —— npm包管理
全局模式安装包 将包安装为全局可用的可执行命令, 并非可以从任意地方require 将 package.json中bin定义的文件软链到统一的目录下, 该目录可以通过如下方式推算出来: path.re ...
- WEBZIP为什么打不开网页
先试三个办法 一.打开IE,点工具,点internet选项,点高级,点恢复默认设置,点保存,退出,重新打开IE 二.打开IE,刷新五次以上 三.打开IE,点工具,点internet选项,点删除文件,点 ...
- ngRx 官方示例分析 - 6 - Effect
@ngrx/effect 前面我们提到,在 Book 的 reducer 中,并没有 Search 这个 Action 的处理,由于它需要发出一个异步的请求,等到请求返回前端,我们需要根据返回的结果来 ...
- Java 获得Class的绝对路径方法
Java获得class文件的绝对路径:1.e.g. Foo.class => Foo.class.getResuorce("").getFile(); 该方法在eclipse ...
- Jquery如何删除table里面checkbox选中的多个行
思路:遍历被选中的checkbox对象→根据选中项筛选出需要删除的行→删除行.实例说明如下: 1.HTML结构 <table id = "test_table"> &l ...
- 策略模式--List排序
需求:根据姓名进行排序,升序或者降序,如果名字一样,就按照id升序排序,用策略模式 步骤一: 定义一个Person对象 public class Person { private Integer id ...
- HX711初步处理记录
参考文档为极客工坊大神记录 http://www.geek-workshop.com/forum.php?mod=viewthread&tid=2315&highlight=hx711 ...