比较基础的一道树链剖分的题 大概还是得说说思路

  树链剖分是将树剖成很多条链,比较常见的剖法是按儿子的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 树的统计——树链剖分的更多相关文章

  1. BZOJ 1036: [ZJOI2008]树的统计Count-树链剖分(点权)(单点更新、路径节点最值、路径求和)模板,超级认真写了注释啊啊啊

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 23015  Solved: 9336[Submit ...

  2. 树的统计Count---树链剖分

    NEFU专项训练十和十一——树链剖分 Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t ...

  3. BZOJ 1036 树的统计-树链剖分

    [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 12904 Solved: 5191[Submit][Status ...

  4. bzoj1036 树的统计 树链剖分模板

    题意:给出树上任意两点,求路径上的值的和与最大值,带单点修改操作 树链剖分思路: 1.对树进行dfs求出点的深度和父亲节点,然后求出轻重儿子(重儿子就是点最多的那个子树,其余都是轻儿子),用一个son ...

  5. BZOJ-1036 树的统计Count 链剖线段树(模板)=(树链剖分+线段树)

    潇爷昨天刚刚讲完...感觉得还可以...对着模板打了个模板...还是不喜欢用指针.... 1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Lim ...

  6. BZOJ1036[ZJOI2008]树的统计——树链剖分+线段树

    题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v ...

  7. [ZJOI2008]树的统计——树链剖分

    本题是一个树链剖分裸题,由于比较菜,老是RE,后来发现是因为使用了全局变量. /************************************************************ ...

  8. [luogu P2590 ZJOI2008] 树的统计 (树链剖分)

    题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u ...

  9. 洛谷P2590 [ZJOI2008] 树的统计 [树链剖分]

    题目传送门 树的统计 题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t ...

随机推荐

  1. Django过滤器之safe

    safe除了将html生成安全的文本外,还有将整型转为字符串: {% for user in user_list %} {% if user.id|safe == uid %} <li clas ...

  2. Python爬虫总结——常见的报错、问题及解决方案

    在爬虫开发时,我们时常会遇到各种BUG各种问题,下面是我初步汇总的一些报错和解决方案. 在以后的学习中,如果遇到其他问题,我也会在这里进行更新. 各位如有什么补充,欢迎评论区留言~~~ 问题: IP被 ...

  3. 2017 ACM/ICPC Asia Regional Shenyang Online 12 card card card

    题目大意: 给出两个长度为n的序列A,B,从1开始依次加Ai,减Bi,分数为第一次为当前和为负数的位置以前的Ai之和(左闭右开区间).同时有一种操作可以把当前的A1,B1移动到序列最后,注意序列A的各 ...

  4. macOS截屏

    Command+Shift+3: 全屏幕截屏,并自动保存在桌面 Command+Shift+4: 手动截屏,并自动保存在桌面 Command+Shift+4, + Space, 之后点击程序的窗口,实 ...

  5. HTML5中的Canvas和SVG

    Canvas 和 SVG 都允许我们在浏览器中创建图形,但是它们在根本上是不同的. 1 SVG SVG 是一种使用 XML 描述 2D 图形的语言. SVG 基于 XML,这意味着 SVG DOM 中 ...

  6. js总结体会

    1.表单元素提交之后(不刷新)数据还是会存在的,想要提交之后清除数据可以在ajax提交数据后,用reset()方法清除数据. 2.js中怎么判断哪个单选控件被选中了呢,即表单控件被选中哪些属性发生了变 ...

  7. yield和生成器, 通过斐波那契数列学习(2.5)

    实现斐波那契数列的集中方法 返回一个数 def fib(max): n, a, b = 0, 0, 1 while n < max: print(b) a, b = b, a+b n += 1 ...

  8. HTML-参考手册: HTTP 方法:GET 对比 POST

    ylbtech-HTML-参考手册: HTTP 方法:GET 对比 POST 1.返回顶部 1. HTTP 方法:GET 对比 POST 两种最常用的 HTTP 方法是:GET 和 POST. 什么是 ...

  9. 戏说 .NET GDI+系列学习教程(三、Graphics类的应用_打印收银小票)

    #region 打印 /// <summary> /// 打印字符串内容 /// </summary> /// <returns></returns> ...

  10. python使用threading获取线程函数返回值的实现方法

    python使用threading获取线程函数返回值的实现方法 这篇文章主要介绍了python使用threading获取线程函数返回值的实现方法,需要的朋友可以参考下 threading用于提供线程相 ...