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 ...
随机推荐
- HDU 4617 Weapon 三维计算几何
题意:给你一些无限长的圆柱,知道圆柱轴心直线(根据他给的三个点确定的平面求法向量即可)与半径,判断是否有圆柱相交.如果没有,输出柱面最小距离. 一共只有30个圆柱,直接暴力一下就行. 判相交/相切:空 ...
- Test Tools
1. http://www.dummytextgenerator.com/: Generate dummy text 2. fsutil file createnew D:\New.txt 1024: ...
- QQ2013手工去广告
QQ的广告令人讨厌,虽然网上有很多去广告补丁或者是去广告版,但是总是害怕有被盗号的风险,那除了付费会员还有其他什么方法可以安全的去除qq广告吗?显然有,那就是手动去广告. 很简单,不会比使用去广告补丁 ...
- Hibernate —— ID的各种生成器(转)
Hibernate中,<id>元素下的可选<generator>子元素是一个Java类的名字,用来为该持久化类的实例生成惟一标示,所有的生成器都实现net.sf.hiberna ...
- 10.cadence.自定义焊盘的创建[原创]
一.自定义图形焊盘 1.设置环境(面板大小,格点) --- ------ 圆形 Shape > Circular ---- 两个DRC错误,证明图形重合了, 将图形复合一下: --- 椭圆类焊盘 ...
- java 反编译插件 JD-Eclipse 和 JD-IntelliJ
去官网 : http://jd.benow.ca/ 找到 JD-Eclipse 和 JD-IntelliJ,下载,前者安在eclipse上,后者安在as上.
- VS2013控制台一闪而过问题解决方法
1.修改项目配置,右键点击项目: 2.在右键菜单中选择属性,然后在弹出的对话框左侧列表中中选择 “配置属性”-->“链接器”-->“系统”然后在右侧的列表中,在第一项”子系统“的值中选择” ...
- leetcode:House Robber(动态规划dp1)
You are a professional robber planning to rob houses along a street. Each house has a certain amount ...
- HDu 3449 (有依赖的01背包) Consumer
题意: 有n件物品,对应有不同的价格和价值,这是典型的01背包.但现在有了一个限制,要买物品先买能装这件物品的特定的盒子,盒子的价值为0 代码理解得还不是太好,感觉这是一个“二重”的01背包.首先假设 ...
- 15.Object-C--浅谈Foundation框架OC数组NSArray与NSMutableArray
昨天总结了一下NSString与NSMutableString,今天我在这里总结一下NSArray与NSMutableArray. NSArray数组是:不可变数组. nil 是数组元素结束的标记.O ...