第一次写链剖,于是挑了个简单的裸题写。

以下几点要注意:

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的更多相关文章

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

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

  2. BZOJ1036——树的统计count

    1.题目大意:给你一棵树,有三种操作 1>qmax,询问u到v中间点权的最大值 2>qsum,询问u到v中间点权和 3>change,把u这个节点的权值改为v 2.分析:树链剖分的裸 ...

  3. 【BZOJ1036】[ZJOI2008]树的统计Count 树链剖分

    [BZOJ1036][ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. ...

  4. [BZOJ1036][ZJOI2008]树的统计Count 解题报告|树链剖分

    树链剖分 简单来说就是数据结构在树上的应用.常用的为线段树splay等.(可现在splay还不会敲囧) 重链剖分: 将树上的边分成轻链和重链. 重边为每个节点到它子树最大的儿子的边,其余为轻边. 设( ...

  5. bzoj1036 [ZJOI2008]树的统计Count

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 12646  Solved: 5085 [Subm ...

  6. bzoj1036 [ZJOI2008]树的统计Count 树链剖分模板题

    [ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成 一些操作: I. CHANGE u ...

  7. bzoj千题计划124:bzoj1036: [ZJOI2008]树的统计Count

    http://www.lydsy.com/JudgeOnline/problem.php?id=1036 树链剖分板子题 #include<cstdio> #include<iost ...

  8. BZOJ 1036: [ZJOI2008]树的统计Count [树链剖分]【学习笔记】

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

  9. BZOJ 1036: [ZJOI2008]树的统计Count

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 14354  Solved: 5802 [Subm ...

随机推荐

  1. 在struts-config.xml中配置validator-plugin导致404 Servlet action is not available

    就是在struts-config.xml中添加了这么一段 <plug-in className="org.apache.struts.validator.ValidatorPlugIn ...

  2. Github原理

    See image below:

  3. Maven+Spring+MVC结构中,jetty/tomcat是如何启动项目的[转]

    针对maven配置的Spring+MVC项目,我们用Maven自带的jetty和tomcat插件进行调试,这很方便.但是调试时,这些插件所启动的web服务器,是如何来将我们的工程作为一个web项目启动 ...

  4. 运行所有sdk目录下的示例,查看它们的功能,方便以后查寻

    运行所有sdk目录下的示例,查看它们的功能,方便以后查寻

  5. Hibernate 的<generator class="native"></generator>的不同属性含义

    1) assigned主键由外部程序负责生成,无需Hibernate参与. 2) hilo通过hi/lo 算法实现的主键生成机制,需要额外的数据库表保存主键生成历史状态. 3) seqhilo与hil ...

  6. Git基础(一)

    本系列内容主要介绍Git一些基本的也是最常用的命令,相信读完本系列内容后,你也差不多能够上手Git了.读完本系列,你就能初始化一个新的代码仓库,做一些适当配置:开始或停止跟踪某些文件:暂存或提交某些更 ...

  7. CSS处理溢出

    如果内容超过的区块的大小,内容就会溢出,可以使用下面的方法控制溢出 overflow visible 不剪切内容也不添加滚动条 auto 在必需时对象内容才会被裁切或显示滚动条 hidden 不显示超 ...

  8. HDU 2544 最短路【Bellman_Ford 】

    题意:给出n个节点,m条边,问从起点到终点的最短距离 用bellman_ford,注意是无向图 初学bellman_ford= =一点点理解 因为dijkstra是每次用集合里面的点去更新它们所连接的 ...

  9. shockwave flash has crashed(Flash 插件崩溃导致页面中的flash不显示)怎么办

    1.原理: 应该电脑里最近装了chorme或者基于chorme内核的浏览器.越来越多的人开始使用chrome的浏览器,很多用户都遇到过flash崩溃的问题,有时候重启chrome可以解决,有时候会导致 ...

  10. [转] 判断html页是否滚动停止

    原文链接:http://www.phpernote.com/javascript-function/754.html 最近有个项目中遇到这样一个问题: 有一个用于展示数据的带滚动条的DIV块,业务需求 ...