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 ...
随机推荐
- swift:入门知识之枚举和结构体
枚举: swift中的枚举有些类似于类这个概念,它有自己的属性,也可以有自己的方法 枚举中的成员有原始值和实际值之分,原始值用来枚举成员的排序次序,默认从0开始 枚举出来的成员值就是实际值 可以通过t ...
- [转]C:int型指针
开源中国:http://my.oschina.net/lotte1699/blog/142538 网页快照:http://www.piaocafe.com/295977937/139381567037 ...
- 应用scikit-learn做文本分类
文本挖掘的paper没找到统一的benchmark,只好自己跑程序,走过路过的前辈如果知道20newsgroups或者其它好用的公共数据集的分类(最好要所有类分类结果,全部或取部分特征无所谓)麻烦留言 ...
- Backbone seajs demo2
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Eclipse插件安装与使用 —— Properties Editor
一.下载 首先当然是下载插件啦! 下载地址:http://sourceforge.jp/projects/propedit/downloads/40156/jp.gr.java_conf.us ...
- poj - 3723 Conscription(最大权森林)
http://poj.org/problem?id=3723 windy需要挑选N各女孩,和M各男孩作为士兵,但是雇佣每个人都需要支付10000元的费用,如果男孩x和女孩y存在亲密度为d的关系,只要他 ...
- [51NOD]大数加法(模拟)
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1005 要处理符号,还要特别注意0和连续进位等情况.偷懒使用st ...
- JAVA反射技术的使用
前言 在开发html使用jquery提交post的时候,可以使用jquery遍历from元素里面的input元素实现参数组合,这样就不用手动打参数了,特别是在参数很多的时候,费神费时. 我开发Andr ...
- Couchbase 找回登录密码
在项目里,我们使用Couchbase当做缓存层,效果非常好,支持集群与数据监测,可悲的有一次我新建了一个服务器,安装完成Couchbase之后,密码忘了! 怎么也想不起来,Couchbase又没有提供 ...
- networking常用命令
nc -l 3000 将开一个临时的3000端口并且侦听,用于测试