【HDU】5296 Annoying problem【树链剖分+分类讨论】
来源:互联网 发布:手机看最新电影软件 编辑:程序博客网 时间:2024/06/06 08:34
传送门:【HDU】5296 Annoying problem
这题我是分类讨论做的,没想到多校题解的方法
#include <stdio.h>#include <string.h>#include <algorithm>using namespace std ;typedef long long LL ;#define clr(a,x) memset ( 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 , 1 , n#define mid ( ( l + r ) >> 1 )const int MAXN = 100005 ;const int MAXE = 200005 ;struct Edge { int v , n ; Edge () {} Edge ( int v , int n ) : v ( v ) , n ( n ) {}} ;struct Node { int u , v , c ;} ;Node node[MAXN] ;Edge E[MAXE] ;int H[MAXN] , cntE ;int dep[MAXN] ;int top[MAXN] ;int siz[MAXN] ;int son[MAXN] ;int pre[MAXN] ;int idx[MAXN] ;int pos[MAXN] ;int in[MAXN] , ou[MAXN] , dfs_clock ;int tree_idx ;int sum[MAXN] ;int f[MAXN][18] ;int vis[MAXN] ;int lca[MAXN << 2] ;int cnt[MAXN << 2] ;int n , q ;void init () { cntE = 0 ; tree_idx = 0 ; dfs_clock = 0 ; clr ( H , -1 ) ; clr ( f , 0 ) ;}void addedge ( int u , int v ) { E[cntE] = Edge ( v , H[u] ) ; H[u] = cntE ++ ;}void dfs ( int u ) { in[u] = ++ dfs_clock ; siz[u] = 1 ; son[u] = 0 ; for ( int i = H[u] ; ~i ; i = E[i].n ) { int v = E[i].v ; if ( v == pre[u] ) continue ; pre[v] = u ; dep[v] = dep[u] + 1 ; f[v][0] = u ; for ( int j = 1 ; j < 18 ; ++ j ) {//这里比赛的时候和dfs(v)写反了,一直调不出来,不然比赛的时候就AC了……太弱 f[v][j] = f[f[v][j - 1]][j - 1] ; } dfs ( v ) ; siz[u] += siz[v] ; if ( siz[son[u]] < siz[v] ) son[u] = v ; } ou[u] = dfs_clock ;}void rebuild ( int u , int top_element ) { top[u] = top_element ; pos[u] = ++ tree_idx ; if ( son[u] ) rebuild ( son[u] , top_element ) ; for ( int i = H[u] ; ~i ; i = E[i].n ) { int v = E[i].v ; if ( v != pre[u] && v != son[u] ) rebuild ( v , v ) ; }}int LCA ( int x , int y ) { if ( !x && !y ) return 0 ; if ( !x ) return y ; if ( !y ) return x ; if ( dep[x] < dep[y] ) swap ( x , y ) ; for ( int i = 17 ; i >= 0 ; -- i ) { if ( dep[x] - ( 1 << i ) >= dep[y] ) x = f[x][i] ; } if ( x == y ) return x ; for ( int i = 17 ; i >= 0 ; -- i ) { if ( f[x][i] != f[y][i] ) { x = f[x][i] ; y = f[y][i] ; } } return f[x][0] ;}void update ( int x , int v , int o , int l , int r ) { if ( l == r ) { lca[o] = v ; cnt[o] = v ? 1 : 0 ; return ; } int m = mid ; if ( x <= m ) update ( x , v , lson ) ; else update ( x , v , rson ) ; lca[o] = LCA ( lca[ls] , lca[rs] ) ; cnt[o] = cnt[ls] + cnt[rs] ;}int query ( int L , int R , int o , int l , int r ) { if ( L <= l && r <= R ) return lca[o] ; int m = mid ; if ( R <= m ) return query ( L , R , lson ) ; if ( m < L ) return query ( L , R , rson ) ; return LCA ( query ( L , R , lson ) , query ( L , R , rson ) ) ;}int query_cnt ( int L , int R , int o , int l , int r ) { if ( L <= l && r <= R ) return cnt[o] ; int m = mid ; if ( R <= m ) return query_cnt ( L , R , lson ) ; if ( m < L ) return query_cnt ( L , R , rson ) ; return query_cnt ( L , R , lson ) + query_cnt ( L , R , rson ) ;}int Query ( int x , int y ) { int res = 0 ; while ( top[x] != top[y] ) { if ( dep[top[x]] < dep[top[y]] ) swap ( x , y ) ; res += sum[pos[x]] - sum[pos[top[x]] - 1] ; x = pre[top[x]] ; } if ( x == y ) return res ; if ( dep[x] > dep[y] ) swap ( x , y ) ; res += sum[pos[y]] - sum[pos[x]] ; return res ;}int jump ( int x ) { for ( int i = 17 ; i >= 0 ; -- i ) { if ( f[x][i] ) { if ( !query_cnt ( in[f[x][i]] , ou[f[x][i]] , root ) ) x = f[x][i] ; } } return f[x][0] ;}void solve () { int op , x ; init () ; scanf ( "%d%d" , &n , &q ) ; for ( int i = 1 ; i < n ; ++ i ) { scanf ( "%d%d%d" , &node[i].u , &node[i].v , &node[i].c ) ; addedge ( node[i].u , node[i].v ) ; addedge ( node[i].v , node[i].u ) ; } dfs ( 1 ) ; rebuild ( 1 , 1 ) ; for ( int i = 1 ; i < n ; ++ i ) { int u = node[i].u ; int v = node[i].v ; if ( dep[u] > dep[v] ) sum[pos[u]] = node[i].c ; else sum[pos[v]] = node[i].c ; } for ( int i = 1 ; i <= n ; ++ i ) { sum[i] += sum[i - 1] ; } clr ( lca , 0 ) ; clr ( cnt , 0 ) ; clr ( vis , 0 ) ; int ans = 0 ; while ( q -- ) { scanf ( "%d%d" , &op , &x ) ; if ( op == 1 ) { if ( !vis[x] ) { vis[x] = 1 ; int lcatot = query ( 1 , n , root ) ; // printf ( "-----%d %d\n" , lcatot , LCA ( x , lcatot ) ) ; if ( LCA ( x , lcatot ) == x ) { int num = query_cnt ( in[x] , ou[x] , root ) ; if ( num ) ans += Query ( x , lcatot ) ; } else { if ( !query_cnt ( in[x] , ou[x] , root ) ) { int y = jump ( x ) ; // printf ( "%d\n" , y ) ; // printf ( "cnt = %d\n" , query_cnt ( in[2] , ou[2] , root ) ) ; ans += Query ( x , y ) ; int z = query ( in[y] , ou[y] , root ) ; if ( dep[lcatot] >= dep[y] ) ans += Query ( z , y ) ; } } update ( in[x] , x , root ) ; // printf ( "cnt[5] = %d\n" , query_cnt ( in[5] , in[5] , root ) ) ; cnt[0] ++ ; //printf ( "%d %d\n" , in[4] , ou[4] ) ; //printf ( "in[%d] = %d\n" , 8 , in[8] ) ; // printf ( "------------%d\n" , LCA ( 4 , 8 ) ) ; } } else { if ( vis[x] ) { vis[x] = 0 ; update ( in[x] , 0 , root ) ; cnt[0] -- ; int lcatot = query ( 1 , n , root ) ; if ( LCA ( x , lcatot ) == x ) { int num = query_cnt ( in[x] , ou[x] , root ) ; if ( num ) ans -= Query ( x , lcatot ) ; } else { // printf ( "%d\n" , query_cnt ( in[x] + 1 , ou[x] , root ) ) ; if ( !query_cnt ( in[x] , ou[x] , root ) ) { //printf ( "ok\n" ) ; int y = jump ( x ) ; ans -= Query ( x , y ) ; int z = query ( in[y] , ou[y] , root ) ; // printf ( "%d %d\n" , y , z ) ; if ( dep[lcatot] >= dep[y] ) ans -= Query ( z , y ) ; } } } } printf ( "%d\n" , ans ) ; }}int main () { int T ; scanf ( "%d" , &T ) ; for ( int i = 1 ; i <= T ; ++ i ) { printf ( "Case #%d:\n" , i ) ; solve () ; } return 0 ;}
0 0
- 【HDU】5296 Annoying problem【树链剖分+分类讨论】
- HDU 5296 Annoying problem
- HDU 5296 Annoying problem
- HDU 5296 Annoying problem
- hdu 5296 Annoying problem
- hdu 5296 Annoying problem(LCA)
- 【LCA】HDU 5296 Annoying problem
- hdu 5296 Annoying problem (LCA)
- HDU 5296 Annoying Problem 树链剖分 LCA 倍增法
- HDU 5296 Annoying problem LCA+树状数组
- HDU 5296 Annoying problem dfs序+lca
- dfs序(HDU 5296,Annoying problem)
- HDOJ 5296 Annoying problem
- HDU 5296 Annoying problem(点到树链的距离+LCA)
- HDU 5296 Annoying problem (树状数组+dfs序+倍增)
- [HDU 5296] Annoying problem (DFS序性质+LCA)
- hdu5105Math Problem(分类讨论)
- hdu 5296 Annoying problem(15多校第一场1009)(在线lca+dfs序)
- java中包的作用以及权限问题
- Delete Node in a Linked List
- Android4.0以上HttpURLConnection出FileNotFoundException异常解决
- iCloudManager部署---iCloudManager的安装及设置(三)
- hdoj5308
- 【HDU】5296 Annoying problem【树链剖分+分类讨论】
- Android New Relic 4.244 Agent 安装问题
- Oracle中的延迟块的清除方法
- Arraylist.addall(c) 方法
- JSVC启动Tomcat
- 转 -- MySQL UNDERSTANDING MAX_CONNECT_ERRORS
- ReccylerView添加header和footer
- listview复用导致内容错乱的问题
- 查看硬件信息