zjoi 2008 树的统计——树链剖分
比较基础的一道树链剖分的题 大概还是得说说思路
树链剖分是将树剖成很多条链,比较常见的剖法是按儿子的size来剖分,剖分完后对于这课树的询问用线段树维护——比如求路径和的话——随着他们各自的链向上走,直至他们在同一条链上为止。比较像lca的方法,只不过这里是按链为单位,而且隔壁的SymenYang说可以用树链剖分做lca。。吓哭
然后说说惨痛的调题经历:边表一定要开够啊! 不是n-1 而是2*(n-1)啊! 然后写变量时原始值和映射值要搞清楚啊! 不要搞错了! 还有就是下次求最小值一定看清下界是多少! 树的统计是-30000 ~ 30000 ,我果断naive 的写了一个初值为0!!! wa 0 就是这么痛苦! 还是too Young too Simple !
code :
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = ; struct edge{
int t; edge* next;
}e[maxn*], *head[maxn];int ne = ; void addedge(int f, int t){
e[ne].t = t; e[ne].next = head[f]; head[f] = e + ne ++;
} int n;
int size[maxn],fa[maxn],dep[maxn],w[maxn],un[maxn],map[maxn]; struct node{
int smax, sum;
node *l, *r;
}tr[maxn * ], *root; int trne = ; node* build(int l, int r){
node* x = tr + trne ++;
if(l != r) {
int mid = (l + r) >> ;
x-> l = build(l, mid);
x-> r = build(mid + , r);
}
return x;
} void update(node* x){
if(x-> l) {
x-> sum = x-> l-> sum + x-> r->sum;
x-> smax = max(x-> l-> smax, x-> r-> smax);
}
} void insert(node* x, int l, int r, int pos, int v) {
if(l == r) { x-> sum = v, x-> smax = v;}
else{
int mid = (l + r) >> ;
if(pos <= mid) insert(x-> l, l, mid, pos, v);
else insert(x-> r, mid + , r, pos, v);
update(x);
}
} int ask(node* x, int l, int r, int ls, int rs, int flag) {
if(l == ls && r == rs) {
if(flag == ) return x-> smax;
else return x-> sum;
}
else {
int mid = (l + r) >> ;
if(rs <= mid) return ask(x-> l, l, mid, ls, rs, flag);
else if(ls >= mid + ) return ask(x-> r, mid + , r, ls, rs, flag);
else {
if(flag == )
return max(ask(x->l, l, mid, ls, mid, flag), ask(x-> r, mid + , r, mid + , rs, flag));
else
return ask(x-> l, l, mid, ls, mid, flag) + ask(x-> r, mid + , r, mid + , rs, flag);
}
}
} int cnt = ; void size_cal(int x, int pre) {
if(pre == -) dep[x] = , fa[x] = x;
else dep[x] = dep[pre] + , fa[x] = pre; size[x] = ;
for(edge* p = head[x]; p; p = p-> next)
if(dep[p-> t] == -)size_cal(p-> t, x), size[x] += size[p-> t];
} void divide(int x, int pre){
if(pre == -) un[x] = x;
else un[x] = un[pre];
map[x] = ++ cnt; insert(root, , n, map[x], w[x]);
int tmax = -, ts = -;
for(edge* p = head[x]; p; p = p-> next) {
if(dep[p-> t] > dep[x] && size[p-> t] > tmax) tmax = size[p-> t], ts = p-> t;
}
if(ts != -) {
divide(ts, x);
for(edge* p = head[x]; p; p = p-> next) {
if(dep[p-> t] > dep[x] && p-> t != ts) divide(p-> t, -);
}
}
} void read() {
memset(dep,-,sizeof(dep));
scanf("%d", &n);
root = build(, n);
for(int i = ; i <= n - ; i++) {
int f, t;
scanf("%d%d", &f, &t);
addedge(f, t), addedge(t, f);
}
for(int i = ; i <= n; ++ i) {
scanf("%d", &w[i]);
}
size_cal(, -);divide(, -);
} int sovmax(int a, int b) {
int ans = -; int ls, rs;
while(un[a] != un[b]) {
if(dep[un[a]] > dep[un[b]]) {
ls = map[a]; rs = map[un[a]];
if(ls > rs) swap(ls, rs);
ans = max(ans, ask(root, , n, ls, rs, ));
a = fa[un[a]];
}
else {
ls = map[b]; rs = map[un[b]];
if(ls > rs) swap(ls, rs);
ans = max(ans, ask(root, , n, ls, rs, ));
b = fa[un[b]];
}
}
ls = map[a], rs = map[b];
if(ls > rs) swap(ls,rs);
ans = max(ans, ask(root, , n, ls, rs, ));
return ans;
} int sovsum(int a,int b) {
int ans = ; int ls, rs;
while(un[a] != un[b]) {
if(dep[un[a]] > dep[un[b]]) {
ls = map[a], rs = map[un[a]];
if(ls > rs) swap(ls, rs);
ans += ask(root, , n, ls, rs, );
a = fa[un[a]];
}
else {
ls = map[b]; rs = map[un[b]];
if(ls > rs) swap(ls, rs);
ans += ask(root, , n, ls, rs, );
b = fa[un[b]];
}
}
ls = map[a], rs = map[b];
if(ls > rs) swap(ls, rs);
ans += ask(root, , n, ls, rs, );
return ans;
} void sov() {
int m;
scanf("%d", &m);
while(m --) {
char s[]; int ls, rs;
scanf("%s %d%d", s + , &ls, &rs);
if(s[] == 'M') printf("%d\n", sovmax(ls, rs));
if(s[] == 'S') printf("%d\n", sovsum(ls, rs));
if(s[] == 'H') insert(root, , n, map[ls], rs);
}
} int main(){
read();sov();
return ;
}
zjoi 2008 树的统计——树链剖分的更多相关文章
- BZOJ 1036: [ZJOI2008]树的统计Count-树链剖分(点权)(单点更新、路径节点最值、路径求和)模板,超级认真写了注释啊啊啊
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 23015 Solved: 9336[Submit ...
- 树的统计Count---树链剖分
NEFU专项训练十和十一——树链剖分 Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t ...
- BZOJ 1036 树的统计-树链剖分
[ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 12904 Solved: 5191[Submit][Status ...
- bzoj1036 树的统计 树链剖分模板
题意:给出树上任意两点,求路径上的值的和与最大值,带单点修改操作 树链剖分思路: 1.对树进行dfs求出点的深度和父亲节点,然后求出轻重儿子(重儿子就是点最多的那个子树,其余都是轻儿子),用一个son ...
- BZOJ-1036 树的统计Count 链剖线段树(模板)=(树链剖分+线段树)
潇爷昨天刚刚讲完...感觉得还可以...对着模板打了个模板...还是不喜欢用指针.... 1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Lim ...
- BZOJ1036[ZJOI2008]树的统计——树链剖分+线段树
题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v ...
- [ZJOI2008]树的统计——树链剖分
本题是一个树链剖分裸题,由于比较菜,老是RE,后来发现是因为使用了全局变量. /************************************************************ ...
- [luogu P2590 ZJOI2008] 树的统计 (树链剖分)
题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u ...
- 洛谷P2590 [ZJOI2008] 树的统计 [树链剖分]
题目传送门 树的统计 题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t ...
随机推荐
- 记录我个人对Telegram的了解
对Telegram(电报) 开始的了解是以为提供了Telegram API,就可以基于它进行开发自己的即时通讯(Instant Messaging)程序. 大概使用过: webogram 和 tele ...
- CTSC2019
(upd:随机立方体AC) 太菜了只会部分分.以后慢慢补坑吧…… 随机立方体: 30分: 正常人都能想到的的转移状态(我的确是弱智),从大往小填数,记录有多少个极大值点和三个方向上各占了多少.转移可以 ...
- bzoj1001 [ICPC-Beijing 2006]狼抓兔子
我满心以为本题正解为最短路,结果到处都是最大流…… 几乎所有的都写了什么“对偶图”跑最短路,但我真的不知道什么叫做对偶图---------------------------------------- ...
- mysql|tomcat|nginx|redis在docker中的部署
MySQL部署 拉取MySQL镜像 docker pull mysql 查看镜像 创建MySQL容器 docker run -di --name pinyougou_mysql -p 33306:33 ...
- JS对象的引用,对象的拷贝
目录 一.场景 二.浅拷贝 三.深拷贝 一.场景 除了基本类型跟null,对象之间的赋值,只是将地址指向同一个,而不是真正意义上的拷贝 将一个对象赋值给另外一个对象. var a = [1,2,3]; ...
- 四:RF框架appium工具之xpath定位
XPATH定位方法具体的学会,还是在今年1月份,以前运用的都不熟练. 这个定位神器是一定要掌握的,不然有你抓狂的时候. 第一要掌握它的书写格式,这个好上手. 第二要掌握它的具体用法.这个就要多练习了, ...
- (动态改变数据源遇到的问题)ORACLE11g:No Dialect mapping for JDBC type: -9解决方案
在动态改变数据源时 hibernate配置不能使用Oracle官方的方言(org.hibernate.dialect.Oracle10gDialect) 做法写一个方言扩展类,缺什么类型,添加什么类型 ...
- java.lang.Boolean.compareTo()方法实例
compareTo接口 Comparable<Boolean>指定以下接口 参数 b - 布尔实例进行比较 返回值 方法返回 0 - 如果该对象表示相同的布尔值作为参数 一个正数值 - 如 ...
- jmeter 查看结果树之查看响应的13种方法
查看结果树查看响应有哪几种方法,可通过左侧面板底部的下拉框选择 1 Text 查看结果树中请求的默认格式为Text,显示取样器结果.请求.响应数据3个部分内容. 取样器结果: 默认Raw展示,可以切换 ...
- null == null 或者 [] == [] 或者{} == {} 或者alert(1|| 2) 或者alert(1&& 2) 结果及原理
相信面试的小伙伴们都会遇到此头大的问题,是不是很想骂一句面试官:你白痴啊,鬼都用不着的东西拿来问,你还别说,这些看似用不着的东西却包含着最基础的原理,那我们来理一理. 1.alert(1||2)和 a ...