【HDU】4836 The Query on the Tree dfs+线段树
来源:互联网 发布:windows 不激活会怎样 编辑:程序博客网 时间:2024/05/16 07:05
传送门:【HDU】4836 The Query on the Tree
题目分析:首先如果不换根的话,就可以用dfs求时间戳+树状数组维护即可。
现在多了换根操作,我们该怎么处理?
首先因为换根并不会改变树的结构,所以我们依旧dfs出一棵树来。
对于修改,我们改变该点在树状数组上对应位置的值即可。
对于换根,我们直接将root置为要换的节点。
对于查询,如果root就等于x,直接返回所有节点的和tot_val即可;
如果root和查询的节点x的lca不为x,即root不是x的子树,显然我们直接对【in[x] , ou[x]】求区间和sum即可;
如果root和x的lca为x,那么我们找到x的子节点y使得y在root到x路径上,答案即tot_val - sum。
代码如下:
#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std ;typedef long long LL ;#pragma comment(linker, "/STACK:16777216")#define Log( i , a , b ) for ( int i = a ; ( 1 << i ) <= b ; ++ i )#define rep( i , a , b ) for ( int i = a ; i < b ; ++ i )#define For( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define rev( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i )#define travel( e , H , u ) for ( Edge* e = H[u] ; e ; e = e -> next )#define clr( a , x ) memset ( a , x , sizeof a )#define cpy( a , x ) memcpy ( a , x , sizeof a )const int LOGN = 15 ;const int MAXN = 10005 ;const int MAXE = 20005 ;struct Edge {int v ;Edge* next ;} E[MAXE] , *H[MAXN] , *edge ;int T[MAXN] ;int in[MAXN] , ou[MAXN] , dfs_clock ;int inc[MAXN][LOGN] ;int dep[MAXN] ;int val[MAXN] ;int tot_val ;int root ;int n , q ;void clear () {edge = E ;root = 1 ;tot_val = 0 ;dfs_clock = 0 ;clr ( H , 0 ) ;clr ( T , 0 ) ;}void addedge ( int u , int v ) {edge -> v = v ;edge -> next = H[u] ;H[u] = edge ++ ;}void dfs ( int u ) {in[u] = ++ dfs_clock ;travel ( e , H , u ) {int v = e -> v ;if ( v != inc[u][0] ) {inc[v][0] = u ;dep[v] = dep[u] + 1 ;dfs ( v ) ;}}ou[u] = dfs_clock ;}void preProcess () {dfs ( 1 ) ;For ( i , 1 , n ) Log ( j , 1 , n ) inc[i][j] = 0 ;Log ( j , 1 , n ) For ( i , 1 , n ) if ( inc[i][j - 1] ) inc[i][j] = inc[inc[i][j - 1]][j - 1] ;}int lca1 ( int x , int y ) {if ( dep[x] < dep[y] ) swap ( x , y ) ;int log = 0 ;Log ( i , 1 , dep[x] ) ++ log ;rev ( i , log , 0 ) if ( dep[x] - ( 1 << i ) >= dep[y] ) x = inc[x][i] ;if ( x == y ) return y ;rev ( i , log , 0 ) if ( inc[x][i] && inc[x][i] != inc[y][i] ) {x = inc[x][i] ;y = inc[y][i] ;}return inc[x][0] ;}int lca2 ( int x , int depth ) {int log = 0 ;Log ( i , 1 , dep[x] ) ++ log ;rev ( i , log , 0 ) if ( dep[x] - ( 1 << i ) >= depth ) x = inc[x][i] ;return x ;}void add ( int x , int v ) {for ( ; x <= n ; x += x & -x ) T[x] += v ;}int sum ( int x , int ans = 0 ) {for ( ; x ; x -= x & -x ) ans += T[x] ;return ans ;}void scanf ( int& x , char c = 0 ) {while ( ( c = getchar () ) < '0' || c > '9' ) ;x = c - '0' ;while ( ( c = getchar () ) >= '0' && c <= '9' ) x = x * 10 + c - '0' ;}void solve () {int x , y ;char op ;clear () ;scanf ( n ) ;rep ( i , 1 , n ) {scanf ( x ) , scanf ( y ) ;addedge ( x , y ) ;addedge ( y , x ) ;}preProcess () ;For ( i , 1 , n ) {scanf ( val[i] ) ;add ( in[i] , val[i] ) ;tot_val += val[i] ;}scanf ( q ) ;while ( q -- ) {op = getchar () ;scanf ( x ) ;if ( op == 'C' ) {scanf ( y ) ;tot_val += y - val[x] ;add ( in[x] , -val[x] ) ;add ( in[x] , val[x] = y ) ;} else if ( op == 'Q' ) {if ( root == x ) printf ( "%d\n" , tot_val ) ;else {int a = lca1 ( root , x ) ;if ( a != x ) printf ( "%d\n" , sum ( ou[x] ) - sum ( in[x] - 1 ) ) ;else {int b = lca2 ( root , dep[x] + 1 ) ;printf ( "%d\n" , tot_val - sum ( ou[b] ) + sum ( in[b] - 1 ) ) ;}}} else root = x ;}}int main () {int T , cas = 0 ;scanf ( "%d" , &T ) ;while ( T -- ) {printf ( "Case #%d:\n" , ++ cas ) ;solve () ;}return 0 ;}
0 0
- 【HDU】4836 The Query on the Tree dfs+线段树
- HDU 4836 The Query on the Tree (欧拉序列,线段树,动态树)
- HDU 4836 —— The Query on the Tree(线段树+LCA)
- hdu 4836 The Query on the Tree(线段树or树状数组)
- Hdu 4836 The Query on the Tree
- 【HDU】3804 Query on a tree dfs+线段树
- HDU 4836 The Query on the Tree lca || 欧拉序列 || 动态树
- [HDU 3848]CC On The Tree[dfs]
- HDU 4010 Query on the tree 动态树(link-cut-tree)入门
- Hdu 4010 Query on The Trees lct link-cut tree
- HDU 4010 Query on the tree LCT模板题
- HDU 4718 The LCIS on the Tree(树链剖分+线段树)
- HDU 4718 The LCIS on the Tree (树链剖分 + 线段树区间合并)
- 【HDU 4718】 The LCIS on the Tree 【树链剖分+线段树合并】
- hdu 4918 Query on the subtree (动态点分治+动态开点+线段树)
- Hdu 3804 Query on a tree 树链剖分+线段树
- 【HDU】4010 Query on The Trees 动态树之Link Cut Tree(LCT)
- spoj 375 Query on the tree [树链剖分]
- webserver服务器+matrixssl搭建+openssl产生自签名证书
- 930
- 架构小思
- 黑马程序员——C语言指针
- 程序员技术练级攻略
- 【HDU】4836 The Query on the Tree dfs+线段树
- 'git merge' 和 'git rebase'的区别?
- cache -yii2
- How to use Oracle Instant Client in Mac OS X Lion
- MapReduce单元测试(MRUnit测试)
- delete [] 时如何知道数组长度
- Android平台使用gstreamer 分发视频
- UVaOJ-11992-Fast Matrix Operations 解题报告
- 中国电子商务的新篇章