【POJ】3237 Tree 树链剖分
2014-09-16 16:14
405 查看
传送门:【POJ】3237 Tree
题目分析:树链剖分水题。线段树每个区间两个变量,minv表示区间最小值,maxv表示区间最大值,区间取反的时候swap( minv , maxv ),然后minv = -minv,maxv = -maxv即可,因为最小值变成了最大值,最大值变成了最小值。
代码如下:
题目分析:树链剖分水题。线段树每个区间两个变量,minv表示区间最小值,maxv表示区间最大值,区间取反的时候swap( minv , maxv ),然后minv = -minv,maxv = -maxv即可,因为最小值变成了最大值,最大值变成了最小值。
代码如下:
#include <cmath> #include <cstdio> #include <cstring> #include <algorithm> using namespace std ; typedef long long LL ; #define travel( e , H , u ) for ( Edge* e = H[u] ; e ; e = e -> next ) #define rep( i , a , b ) for ( int i = ( a ) ; i < ( b ) ; ++ i ) #define rev( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i ) #define FOR( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i ) #define clr( a , x ) memset ( a , x , sizeof a ) #define cpy( a , x ) memcpy ( a , x , sizeof a ) #define ls ( o << 1 ) #define rs ( o << 1 | 1 ) #define lson ls , l , m #define rson rs , m + 1 , r #define root 1 , 2 , n #define mid ( ( l + r ) >> 1 ) const int MAXN = 10005 ; const int MAXE = 20005 ; const int INF = 0x3f3f3f3f ; struct Edge { int v ; Edge* next ; } E[MAXE] , *H[MAXN] , *edge ; struct Line { int x , y , w ; Line () {} Line ( int x , int y , int w ) : x ( x ) , y ( y ) , w ( w ) {} } L[MAXN] ; int maxv[MAXN << 2] ; int minv[MAXN << 2] ; bool set[MAXN << 2] ; int siz[MAXN] ; int pos[MAXN] ; int pre[MAXN] ; int top[MAXN] ; int dep[MAXN] ; int son[MAXN] ; int val[MAXN] ; int tree_idx ; int n ; void clear () { edge = E ; tree_idx = 0 ; clr ( H , 0 ) ; clr ( set , 0 ) ; pre[1] = 0 ; siz[0] = 0 ; dep[0] = 0 ; } void addedge ( int u , int v ) { edge -> v = v ; edge -> next = H[u] ; H[u] = edge ++ ; edge -> v = u ; edge -> next = H[v] ; H[v] = edge ++ ; } void dfs ( int u ) { siz[u] = 1 ; son[u] = 0 ; travel ( e , H , u ) { int v = e -> v ; if ( v != pre[u] ) { pre[v] = u ; dep[v] = dep[u] + 1 ; dfs ( v ) ; siz[u] += siz[v] ; if ( siz[v] > siz[son[u]] ) son[u] = v ; } } } void rewrite ( int u , int top_element ) { top[u] = top_element ; pos[u] = ++ tree_idx ; if ( son[u] ) rewrite ( son[u] , top_element ) ; travel ( e , H , u ) { int v = e -> v ; if ( v != son[u] && v != pre[u] ) rewrite ( v , v ) ; } } inline void pushup ( int o ) { minv[o] = min ( minv[ls] , minv[rs] ) ; maxv[o] = max ( maxv[ls] , maxv[rs] ) ; } inline void fun ( int o ) { set[o] ^= 1 ; swap ( minv[o] , maxv[o] ) ; minv[o] = -minv[o] ; maxv[o] = -maxv[o] ; } inline void pushdown ( int o ) { if ( set[o] ) { fun ( ls ) ; fun ( rs ) ; set[o] = 0 ; } } void build ( int o , int l , int r ) { if ( l == r ) { minv[o] = maxv[o] = val[l] ; return ; } int m = mid ; build ( lson ) , build ( rson ) ; pushup ( o ) ; } void sub_update ( int L , int R , int o , int l , int r ) { if ( L <= l && r <= R ) { fun ( o ) ; return ; } int m = mid ; pushdown ( o ) ; if ( L <= m ) sub_update ( L , R , lson ) ; if ( m < R ) sub_update ( L , R , rson ) ; pushup ( o ) ; } void update ( int x , int y ) { while ( top[x] != top[y] ) { if ( dep[top[x]] < dep[top[y]] ) swap ( x , y ) ; sub_update ( pos[top[x]] , pos[x] , root ) ; x = pre[top[x]] ; } if ( x == y ) return ; if ( dep[x] > dep[y] ) swap ( x , y ) ; sub_update ( pos[x] + 1 , pos[y] , root ) ; } void modify ( int pos , int v , int o , int l , int r ) { while ( l != r ) { int m = mid ; pushdown ( o ) ; if ( pos <= m ) r = m , o = ls ; else l = m + 1 , o = rs ; } minv[o] = maxv[o] = v ; while ( o != 1 ) { o >>= 1 ; pushup ( o ) ; } } int sub_query ( int L , int R , int o , int l , int r ) { if ( L <= l && r <= R ) return maxv[o] ; int m = mid ; pushdown ( o ) ; if ( R <= m ) return sub_query ( L , R , lson ) ; if ( m < L ) return sub_query ( L , R , rson ) ; return max ( sub_query ( L , R , lson ) , sub_query ( L , R , rson ) ) ; } int query ( int x , int y , int res = -INF ) { while ( top[x] != top[y] ) { if ( dep[top[x]] < dep[top[y]] ) swap ( x , y ) ; res = max ( res , sub_query ( pos[top[x]] , pos[x] , root ) ) ; x = pre[top[x]] ; } if ( x == y ) return res ; if ( dep[x] > dep[y] ) swap ( x , y ) ; return max ( res , sub_query ( pos[x] + 1 , pos[y] , root ) ) ; } void solve () { char buf[10] ; int x , y , w ; clear () ; scanf ( "%d" , &n ) ; rep ( i , 1 , n ) { scanf ( "%d%d%d" , &x , &y , &w ) ; L[i] = Line ( x , y , w ) ; addedge ( x , y ) ; } dfs ( 1 ) ; rewrite ( 1 , 1 ) ; rep ( i , 1 , n ) { if ( dep[L[i].x] < dep[L[i].y] ) swap ( L[i].x , L[i].y ) ; val[pos[L[i].x]] = L[i].w ; } build ( root ) ; while ( ~scanf ( "%s" , buf ) && buf[0] != 'D' ) { scanf ( "%d%d" , &x , &y ) ; if ( buf[0] == 'C' ) modify ( pos[L[x].x] , y , root ) ; else if ( buf[0] == 'N' ) update ( x , y ) ; else printf ( "%d\n" , query ( x , y ) ) ; } } int main () { int T ; scanf ( "%d" , &T ) ; while ( T -- ) solve () ; return 0 ; }
相关文章推荐
- POJ 3237 Tree 树链剖分
- POJ 3237 Tree(树链剖分-线段树点更新-区间更新-区间最值查询-入边)
- POJ 3237 Tree (树链剖分)
- POJ-3237:Tree(树链剖分)
- POJ 3237 Tree(树链剖分模板)
- POJ-3237 Tree(树链剖分)
- POJ 3237 - Tree(树链剖分)
- POJ 3237 Tree 树链剖分
- 【树链剖分】 POJ 3237 Tree
- POJ 3237 Tree(树链剖分 + 单点更新 + 区间更新 + 区间查询)
- POJ 3237 Tree(树链剖分)
- poj 3237 Tree 树链剖分
- POJ 3237 Tree 树链剖分
- POJ 3237 Tree(树链剖分——边权)
- poj 3237 Tree(树链剖分,线段树)
- poj 3237 Tree 树链剖分 线段树
- POJ 3237 Tree (树链剖分 路径更新)
- POJ 3237 Tree 树链剖分 线段树
- POJ 3237 Tree 树链剖分
- poj 3237 Tree(树链剖分)