【bzoj1036】[ZJOI2008]树的统计Count
题目描述
一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成一些操作:
I. CHANGE u t : 把结点u的权值改为t
II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值
III. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身
输入
输入的第一行为一个整数n,表示节点的个数。接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有一条边相连。接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。接下来1行,为一个整数q,表示操作的总数。接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。 对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。
输出
对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。
样例输入
4
1 2
2 3
4 1
4 2 1 3
12
QMAX 3 4
QMAX 3 3
QMAX 3 2
QMAX 2 3
QSUM 3 4
QSUM 2 1
CHANGE 1 5
QMAX 3 4
CHANGE 3 6
QMAX 3 4
QMAX 2 4
QSUM 3 4
样例输出
4
1
2
2
10
6
5
6
5
16
题解
树链剖分模板题,第一次码。。。
树链剖分就是把一棵树拆为一些链来处理,并用数据结构来维护。
通常的剖分方法是按照轻重链剖分,每次选取节点最多的子树继承重链,其余视作轻链,重新处理。
通常用线段树维护权值。
查询时,如果x和y在同一条链上,那么直接查询,否则一边将x和y往同一条链上靠,一边记录路径上的权值,然后查询。
代码应该不难理解。
#include <cstdio>
#include <algorithm>
using namespace std;
#define inf 0x3fffffff
#define lson l , mid , x << 1
#define rson mid + 1 , r , x << 1 | 1
int val[30005] , deep[30005] , si[30005] , fa[30005] , bl[30005] , pos[30005] , tot;
int head[30005] , to[60005] , next[60005] , cnt;
int maxn[120005] , sum[120005] , n;
char str[10];
void add(int x , int y)
{
to[++cnt] =y;
next[cnt] = head[x];
head[x] = cnt;
}
void dfs1(int x)
{
si[x] = 1;
int i , y;
for(i = head[x] ; i ; i = next[i])
{
y = to[i];
if(y != fa[x])
{
deep[y] = deep[x] + 1;
fa[y] = x;
dfs1(y);
si[x] += si[y];
}
}
}
void dfs2(int x , int c)
{
int k = 0 , i , y;
pos[x] = ++tot;
bl[x] = c;
for(i = head[x] ; i ; i = next[i])
{
y = to[i];
if(deep[y] > deep[x] && si[y] > si[k])
k = y;
}
if(k != 0)
{
dfs2(k , c);
for(i = head[x] ; i ; i = next[i])
{
y = to[i];
if(deep[y] > deep[x] && y != k)
dfs2(y , y);
}
}
}
void pushup(int x)
{
sum[x] = sum[x << 1] + sum[x << 1 | 1];
maxn[x] = max(maxn[x << 1] , maxn[x << 1 | 1]);
}
void update(int p , int c , int l , int r , int x)
{
if(l == r)
{
sum[x] = maxn[x] = c;
return;
}
int mid = (l + r) >> 1;
if(p <= mid)
update(p , c , lson);
else
update(p , c , rson);
pushup(x);
}
int querysum(int b , int e , int l , int r , int x)
{
if(b <= l && r <= e)
return sum[x];
int mid = (l + r) >> 1 , ans = 0;
if(b <= mid)
ans += querysum(b , e , lson);
if(e > mid)
ans += querysum(b , e , rson);
return ans;
}
int querymaxn(int b , int e , int l , int r , int x)
{
if(b <= l && r <= e)
return maxn[x];
int mid = (l + r) >> 1 , ans = -inf;
if(b <= mid)
ans = max(ans , querymaxn(b , e , lson));
if(e > mid)
ans = max(ans , querymaxn(b , e , rson));
return ans;
}
int solvesum(int x , int y)
{
int ans = 0;
while(bl[x] != bl[y])
{
if(deep[bl[x]] < deep[bl[y]])
swap(x , y);
ans += querysum(pos[bl[x]] , pos[x] , 1 , n , 1);
x = fa[bl[x]];
}
if(pos[x] > pos[y])
swap(x , y);
ans += querysum(pos[x] , pos[y] , 1 , n , 1);
return ans;
}
int solvemaxn(int x , int y)
{
int ans = -inf;
while(bl[x] != bl[y])
{
if(deep[bl[x]] < deep[bl[y]])
swap(x , y);
ans = max(ans , querymaxn(pos[bl[x]] , pos[x] , 1 , n , 1));
x = fa[bl[x]];
}
if(pos[x] > pos[y])
swap(x , y);
ans = max(ans , querymaxn(pos[x] , pos[y] , 1 , n , 1));
return ans;
}
int main()
{
int i , x , y , q;
scanf("%d" , &n);
for(i = 1 ; i < n ; i ++ )
{
scanf("%d%d" , &x , &y);
add(x , y);
add(y , x);
}
for(i = 1 ; i <= n ; i ++ )
scanf("%d" , &val[i]);
dfs1(1);
dfs2(1 , 1);
for(i = 1 ; i <= n ; i ++ )
update(pos[i] , val[i] , 1 , n , 1);
scanf("%d" , &q);
while(q -- )
{
scanf("%s%d%d" , str , &x , &y);
switch(str[1])
{
case 'H': val[x] = y; update(pos[x] , y , 1 , n , 1); break;
case 'S': printf("%d\n" , solvesum(x , y)); break;
default: printf("%d\n" , solvemaxn(x , y));
}
}
return 0;
}
【bzoj1036】[ZJOI2008]树的统计Count的更多相关文章
- [BZOJ1036][ZJOI2008]树的统计Count 解题报告|树链剖分
树链剖分 简单来说就是数据结构在树上的应用.常用的为线段树splay等.(可现在splay还不会敲囧) 重链剖分: 将树上的边分成轻链和重链. 重边为每个节点到它子树最大的儿子的边,其余为轻边. 设( ...
- bzoj1036 [ZJOI2008]树的统计Count
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MB Submit: 12646 Solved: 5085 [Subm ...
- bzoj1036 [ZJOI2008]树的统计Count 树链剖分模板题
[ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成 一些操作: I. CHANGE u ...
- bzoj千题计划124:bzoj1036: [ZJOI2008]树的统计Count
http://www.lydsy.com/JudgeOnline/problem.php?id=1036 树链剖分板子题 #include<cstdio> #include<iost ...
- BZOJ1036 [ZJOI2008]树的统计Count 树链剖分
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1036 题意概括 一个树,每个节点有一个权值.3种操作. 1:修改某一个节点的权值. 2:询问某两个 ...
- 【lct】bzoj1036 [ZJOI2008]树的统计Count
题意:给你一棵树,点带权,支持三种操作:单点修改:询问链上和:询问链上max. 这里的Query操作用了与上一题不太一样的做法(上一题用那种做法,因为在边带权的情况下换根太困难啦): 先ChangeR ...
- BZOJ1036[ZJOI2008]树的统计Count 题解
题目大意: 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.有一些操作:1.把结点u的权值改为t:2.询问从点u到点v的路径上的节点的最大权值 3.询问从点u到点v的路径上的节点的权值和 ...
- bzoj1036 zjoi2008 树的统计 count
填坑= =第一道裸树剖 #include<cstdio> #include<algorithm> #include<cstring> #include<cst ...
- [BZOJ1036] [ZJOI2008] 树的统计Count (LCT)
Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. Q ...
- bzoj1036 [ZJOI2008]树的统计Count(树链剖分)
Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. Q ...
随机推荐
- HDU #5733 tetrahedron
tetrahedron 传送门 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) P ...
- rpm包安装过程中依赖问题“libc.so.6 is needed by XXX”解决方法
rpm包安装过程中依赖问题"libc.so.6 is needed by XXX"解决方法 折腾了几天,终于搞定了CentOS上的Canon LBP2900打印机驱动.中间遇到了一 ...
- POJMatrix(二维树状数组)
Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 22058 Accepted: 8219 Descripti ...
- JAVA Socket超时浅析
JAVA Socket超时浅析 套接字或插座(socket)是一种软件形式的抽象,用于表达两台机器间一个连接的"终端".针对一个特定的连接,每台机器上都有一个"套接字&q ...
- WinForm------分页控件dll下载地址
转载: http://files.cnblogs.com/wuhuacong/TestPager_SqlLite.rar
- electron package can not find module xml2json
问题 electron 打包好的应用找不到xml2json 但是开发环境npm start 运行正常 定位 node_modules没有包含在打的包中, 解决办法 --no-prune Be care ...
- 写Action的三种方法
Action类似于servlet,在用户对浏览器输入url访问的时候充当控制器的角色.它在访问时产生,执行execute()之后就销毁了. 写Action是代理事务,它实现的三种方式是: (1)POJ ...
- 对Java垃圾回收最大的误解是什么
当 我还是小孩的时候,父母常说如果你不好好学习,就只能去扫大街了.但他们不知道的是,清理垃圾实际上是很棒的一件事.可能这也是即使在Java的世界中, 同样有很多开发者对GC算法产生误解的原因--包括它 ...
- 9月9日HTML上午表单元素2(框架、样式表)
五.框架 1.frameset是双标签框架集,如果使用框架集,当前页面不能有body. frameset属性:①cols代表左右拆分.cols=“300,*”表示左边框架宽300,右边宽剩余的宽度.* ...
- Java数据结构——有序链表
//================================================= // File Name : SortedList_demo //--------------- ...