【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 ...
随机推荐
- 大一上学期C语言学习心得总结
经过一个学期的C语言学习,大体算是在这个编程语言上入了门,能够通过一些代码解决特定的问题.当然,每次成功将问题转换成代码都小有激动,虽然只是在黑框上输出了一些数字或是字符串. 编程,虽然还不是很懂,但 ...
- Sublime Text 3 编辑器使用
今天打开别人的python脚本,想找IDE的时候,本来在eclipse中有安装python插件,但是好像是太旧了,很多sys的方法找不着 又上网找了一下python的IDE工具,看好多人在歌颂这个Su ...
- BZOJ1031: [JSOI2007]字符加密Cipher
传送门 后缀数组模板题 //BZOJ 1031 //by Cydiater //2016.9.21 #include <iostream> #include <cstring> ...
- rhino(犀牛) --- color control
create color materials, if "材料赋予方式" is "图层", the color of "材质" is show ...
- 【原】整理的react相关的一些学习地址,包括 react-router、redux、webpack、flux
因为平时经常去网上找react相关的一些地址,找来找去很麻烦,所以自己整理了一下,不过前面部分不是我整理的, 是出自于:http://www.cnblogs.com/aaronjs/p/4333925 ...
- k-nearest-neighbor算法
1. kNN 1.1 基本的kNN模型 kNN(k-nearest neighbor)的思想简单来说就是,要评价一个未知的东西U,只需找k个与U相似的已知的东西,并通过k个已知的,对U进行评价.假如要 ...
- Foundation框架--字典( NSDictionary NSMutableDictionary )
基础知识 1.字典不允许相同的key,但允许有相同的value. 2,字典是无序的,字典不能排序. 3.字典里的内容是成对存在的,不会出现单数. 4.快速创建的方式只适合不可变字典. 不可变字典 #i ...
- IDEA 搭建的SpringMVC Maven项目出现的问题
1.添加jar包时,报添加某个jar包有问题,在pom.xml文件的project节点上有红波浪线 jar引用的maven地址没有问题,就是报错 解决办法:到本地仓库把相关jar包删掉重新下载 2.各 ...
- Mac安装Brew
安装命令如下:curl -LsSf http://github.com/mxcl/homebrew/tarball/master | sudo tar xvz -C/usr/local --strip ...
- SCWS分词扩展在UNIX/LINUX下的安装方法
<?php/** * 中文分词处理方法 *+--------------------------------- * @param stirng $string 要处理的字符串 * @param ...