bzoj1036 树的统计Count
第一次写链剖,于是挑了个简单的裸题写。
以下几点要注意:
1.链剖中的height是从根到该店经过的轻边个数
2.分清num与sum。。。。。
#include<cstdio>
#include<algorithm>
using namespace std ; const int MAXN = * + ;
const int MAX_SIZE = * + ;
int N , Q ; int max_equal ( int & a , const int b ) { if ( a < b ) a = b ; return a ; } namespace Seg { int maxv [ MAX_SIZE * ] ;
int sumv [ MAX_SIZE * ] ;
int value [ MAXN ] ;
int l , r , v ; void maintain ( const int o ) {
const register int o1 = o << , o2 = o << | ;
maxv [ o ] = max ( maxv [ o1 ] , maxv [ o2 ] ) ;
sumv [ o ] = sumv [ o1 ] + sumv [ o2 ] ;
} void __build ( const int o , const int L , const int R ) {
if ( R - L == ) maxv [ o ] = sumv [ o ] = value [ L ] ;
else {
const int M = ( L + R ) / ;
__build ( o << , L , M ) ;
__build ( o << | , M , R ) ;
maintain ( o ) ;
}
}
void build () {
__build ( , , N ) ;
} void _modify ( const int o , const int L , const int R ) {
if ( R - L == ) maxv [ o ] = sumv [ o ] = v ;
else {
const int M = ( L + R ) / ;
if ( l < M ) _modify ( o << , L , M ) ;
else _modify ( o << | , M , R ) ;
maintain ( o ) ;
}
}
void modify ( const int p , const int V ) {
l = p ; v = V ; _modify ( , , N ) ;
} void _Qmax ( const int o , const int L , const int R ) {
if ( l <= L && R <= r ) max_equal ( v , maxv [ o ] ) ;
else {
const int M = ( L + R ) / ;
if ( l < M ) _Qmax ( o << , L , M ) ;
if ( M < r ) _Qmax ( o << | , M , R ) ;
}
}
int Qmax ( int L , int R ) {
if ( L > R ) swap ( L , R ) ;
l = L ; r = R + ; v = - ( << ) /* -INF */ ;
_Qmax ( , , N ) ;
return v ;
} void _Qsum ( const int o , const int L , const int R ) {
if ( l <= L && R <= r ) v += sumv [ o ] ;
else {
const int M = ( L + R ) / ;
if ( l < M ) _Qsum ( o << , L , M ) ;
if ( M < r ) _Qsum ( o << | , M , R ) ;
}
}
int Qsum ( int L , int R ) {
if ( L > R ) swap ( L , R ) ;
l = L ; r = R + ; v = ;
_Qsum ( , , N ) ;
return v ;
} } struct edge {
int p ;
edge * nxt ;
} ;
edge * V [ MAXN ] ;
int value [ MAXN ] ;
edge E [ MAXN * ] ; void ___add_edge ( const int a , const int b ) {
static edge * t = E ;
t -> p = b ; t -> nxt = V [ a ] ; V [ a ] = t ++ ;
}
void add_edge ( const int a , const int b ) {
___add_edge ( a , b ) ;
___add_edge ( b , a ) ;
} namespace Link_cut { int top [ MAXN ] ;
int num [ MAXN ] ;
int size [ MAXN ] ;
int height [ MAXN ] ;
int father [ MAXN ] ; namespace GET_SIZE {
int dfs ( const int o ) {
size [ o ] = ;
for ( edge * i = V [ o ] ; i != ; i = i -> nxt )
if ( i -> p != father [ o ] ) {
father [ i -> p ] = o ;
size [ o ] += dfs ( i -> p ) ;
}
return size [ o ] ;
}
}
void Get_size () { father [ ] = ; GET_SIZE :: dfs ( ) ; } namespace LINK_CUT {
void dfs ( const int o , const int t , const int h ) {
if ( o < ) return ;
else {
static int dfs_clock = ;
top [ o ] = t ;
num [ o ] = dfs_clock ++ ;
height [ o ] = h ;
int max_size_value = - , max_size_node = - ;
for ( edge * i = V [ o ] ; i != ; i = i -> nxt )
if ( i -> p != father [ o ] && max_size_value < size [ i -> p ] ) {
max_size_value = size [ i -> p ] ;
max_size_node = i -> p ;
}
dfs ( max_size_node , t , h ) ;
for ( edge * i = V [ o ] ; i != ; i = i -> nxt )
if ( i -> p != father [ o ] && i -> p != max_size_node ) dfs ( i -> p , i -> p , h + ) ;
}
}
} void cut_link ( ) {
LINK_CUT :: dfs ( , , ) ;
for ( int i = ; i < N ; ++ i ) Seg :: value [ num [ i ] ] = :: value [ i ] ;
Seg :: build () ;
} void modify ( const int p , const int v ) {
Seg :: modify ( num [ p ] , v ) ;
} int Qsum ( int a , int b ) {
int v = ;
while ( top [ a ] != top [ b ] ) {
if ( height [ a ] < height [ b ] ) swap ( a , b ) ;
v += Seg :: Qsum ( num [ a ] , num [ top [ a ] ] ) ;
a = father [ top [ a ] ] ;
}
v += Seg :: Qsum ( num [ a ] , num [ b ] ) ;
return v ;
} int Qmax ( int a , int b ) {
int v = -( << ) ;
while ( top [ a ] != top [ b ] ) {
if ( height [ a ] < height [ b ] ) swap ( a , b ) ;
max_equal ( v , Seg :: Qmax ( num [ a ] , num [ top [ a ] ] ) ) ;
a = father [ top [ a ] ] ;
}
max_equal ( v , Seg :: Qmax ( num [ a ] , num [ b ] ) ) ;
return v ;
} } char c [ ] ;
int main () {
scanf ( "%d" , & N ) ;
for ( int i = ; i < N ; ++ i ) {
int a , b ;
scanf ( "%d%d" , & a , & b ) ;
add_edge ( a - , b - ) ;
}
for ( int i = ; i < N ; ++ i ) scanf ( "%d" , & value [ i ] ) ;
Link_cut :: Get_size () ;
Link_cut :: cut_link () ; scanf ( "%d" , & Q ) ;
for ( int i = ; i < Q ; ++ i ) {
int a , b ;
scanf ( "%s%d%d" , c , & a , & b ) ;
switch ( c [ ] ) {
case 'H' :
Link_cut :: modify ( a - , b ) ;
break ;
case 'M' :
printf ( "%d\n" , Link_cut :: Qmax ( a - , b - ) ) ;
break ;
case 'S' :
printf ( "%d\n" , Link_cut :: Qsum ( a - , b - ) ) ;
break ;
}
} return ;
}
本博客禁止转载,转载请先联系作者,谢谢。
原地址:http://www.cnblogs.com/Christopher-Cao/p/5186126.html
如发现与文章与地址不同,请通过博客联系作者
bzoj1036 树的统计Count的更多相关文章
- BZOJ-1036 树的统计Count 链剖线段树(模板)=(树链剖分+线段树)
潇爷昨天刚刚讲完...感觉得还可以...对着模板打了个模板...还是不喜欢用指针.... 1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Lim ...
- BZOJ1036——树的统计count
1.题目大意:给你一棵树,有三种操作 1>qmax,询问u到v中间点权的最大值 2>qsum,询问u到v中间点权和 3>change,把u这个节点的权值改为v 2.分析:树链剖分的裸 ...
- 【BZOJ1036】[ZJOI2008]树的统计Count 树链剖分
[BZOJ1036][ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. ...
- [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 ...
- BZOJ 1036: [ZJOI2008]树的统计Count [树链剖分]【学习笔记】
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 14302 Solved: 5779[Submit ...
- BZOJ 1036: [ZJOI2008]树的统计Count
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MB Submit: 14354 Solved: 5802 [Subm ...
随机推荐
- Spring Boot MyBatis 通用Mapper插件集成
Mybatis在使用过程中需要三个东西,每张表对应一个XXMapper.java接口文件,每张表对应一个XXMapper.xml文件,每张表对应一个Entity的Java文件. 其中XXMappe ...
- CMake入门指南-编译教程
CMake是一个比make更高级的编译配置工具,它可以根据不同平台.不同的编译器,生成相应的Makefile或者vcproj项目.通过编写CMakeLists.txt,可以控制生成的Makefile, ...
- mysql 字符串函数
对于针对字符串位置的操作,第一个位置被标记为1. ASCII(str) 返回字符串str的 最左面字符的ASCII代码值.如果str是空字符串, 返回0.如果str是NULL,返回NULL. mysq ...
- linux学习之centos(一):在VMware虚拟机中安装centos6.5
---安装环境如下--- 虚拟机版本:VMware Workstation_10.0.3(版本信息介绍:VMware-workstation-full-10.0.3-1895310,下载地址:http ...
- CodeForces 378C Maze (DFS)
题目链接 题意:给一个由“.”组成的联通区域,求再添加k个‘#'以后还是联通区域的方案. 分析:做题的时候犯二了,用DFS,一直搜到边缘,然后从边缘依次往回 回溯,回溯的过程中填充’#‘ 一直填充k个 ...
- 适用于Firemonkey的Json解析对象XsuperObject使用方法介绍
XSuperObject是适用于FileMonkey平台的JSON解析组件,能够在Android,IOS,MACOS,WINDOWS等多个平台使用 点击下载 Sample JSON { "n ...
- 【第八篇】mvc razor视图配置404 500页面
记住是最外层的这个Web.config 在 <system.web> </system.web>节点里面配置 <customErrors defaultRedirect ...
- Warning: Using innodb_additional_mem_pool_size is DEPRECATED
Warning: Using innodb_additional_mem_pool_size is DEPRECATED. This option may be removed in future r ...
- 【转】很有用但鲜有人知的 Linux 命令
Linux命令行吸引了大多数Linux爱好者.一个正常的Linux用户一般掌握大约50-60个命令来处理每日的任务.Linux命令和它们的转换对于Linux用户.Shell脚本程序员和管理员来说是最有 ...
- unity3d 破解安装
1.下载破解程序,执行生成unity_v4.x.ulf文件 2.断网 3.执行unity客户端,load该lisence文件即可 注意:安装unity客户端完成后,未破解,切记别打开unity客户端