POJ 3237 Tree 树链剖分
2014-08-18 15:55
344 查看
#include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; #define mxn 10020 #define mxe 20020 #define md ( ( ll + rr ) >> 1 ) #define ls ( i << 1 ) #define rs ( ls | 1 ) int is[mxn]; struct tree { int fst[mxn], nxt[mxe], to[mxe], cost[mxe], e, val[mxn], w[mxn]; int fa[mxn], dep[mxn], sz[mxn], son[mxn]; int tid[mxn], top[mxn]; bool vis[mxn]; int label, n; void init( int n ) { this -> n = n; memset( fst, -1, sizeof( fst ) ); e = 0; } void add( int u, int v, int c ) { to[e] = v, nxt[e] = fst[u], cost[e] = c; fst[u] = e++; } void dfs( int u, int p ) { fa[u] = p; sz[u] = 1; for( int i = fst[u]; ~i; i = nxt[i] ) { int v = to[i], c = cost[i]; if( v == p ) continue; dep[v] = dep[u] + 1; is[i>>1] = v; val[v] = c; dfs( v, u ); sz[u] += sz[v]; if( sz[v] > sz[son[u]] ) son[u] = v; } } void dfs2( int u, int t ) { vis[u] = 1; top[u] = t; tid[u] = ++label; w[label] = val[u]; if( son[u] ) dfs2( son[u], t ); for( int i = fst[u]; ~i; i = nxt[i] ) { int v = to[i]; if( !vis[v] ) dfs2( v, v ); } } void cut() { dep[1] = sz[0] = 0; memset( son, 0, sizeof( son ) ); dfs( 1, -1 ); memset( vis, 0, sizeof( vis ) ); label = 0; dfs2( 1, 1 ); } int mx[mxn<<2], mi[mxn<<2]; bool flip[mxn<<2]; void pushdown( int i ) { if( flip[i] ) { swap( mx[ls], mi[ls] ); swap( mi[rs], mx[rs] ); mx[ls] = - mx[ls], mi[ls] = -mi[ls]; mx[rs] = - mx[rs], mi[rs] = -mi[rs]; flip[ls] ^= 1; flip[rs] ^= 1; flip[i] = 0; } } void build( int ll, int rr, int i ) { flip[i] = 0; if( ll == rr ) { mx[i] = w[ll]; mi[i] = w[ll]; return; } build( ll, md, ls ), build( md + 1, rr, rs ); mx[i] = max( mx[ls], mx[rs] ); mi[i] = min( mi[ls], mi[rs] ); } void update( int x, int v, int ll, int rr, int i ) { if( ll == rr ) { mx[i] = v; mi[i] = v; return; } pushdown( i ); if( x <= md ) update( x, v, ll, md, ls ); else update( x, v, md + 1, rr, rs ); mx[i] = max( mx[ls], mx[rs] ); mi[i] = min( mi[ls], mi[rs] ); } void ng( int l, int r, int ll, int rr, int i ) { if( ll == l && rr == r ) { swap( mx[i], mi[i] ); mx[i] = - mx[i], mi[i] = -mi[i]; flip[i] ^= 1; return; } pushdown( i ); if( r <= md ) ng( l, r, ll, md, ls ); else if( l > md ) ng( l, r, md + 1, rr, rs ); else ng( l, md, ll, md, ls ), ng( md + 1, r, md + 1, rr, rs ); mx[i] = max( mx[ls], mx[rs] ); mi[i] = min( mi[ls], mi[rs] ); } int query( int l, int r, int ll, int rr, int i ) { if( ll == l && rr == r ) return mx[i]; pushdown( i ); if( r <= md ) return query( l, r, ll, md, ls ); if( l > md ) return query( l, r, md + 1, rr, rs ); return max( query( l, md, ll, md, ls ), query( md + 1, r, md + 1, rr, rs ) ); } int calc( int x, int y ) { int ret = - 0x3f3f3f3f; while( top[x] != top[y] ) { if( dep[top[x]] > dep[top[y]] ) swap( x, y ); ret = max( ret, query( tid[top[y]], tid[y], 1, n, 1 ) ); y = fa[top[y]]; } if( x != y ) { if( dep[x] > dep[y] ) swap( x, y ); ret = max( ret, query( tid[x] + 1, tid[y], 1, n, 1 ) ); } return ret; } void NG( int x, int y ) { while( top[x] != top[y] ) { if( dep[top[x]] > dep[top[y]] ) swap( x, y ); ng( tid[top[y]], tid[y], 1, n, 1 ); y = fa[top[y]]; } if( x != y ) { if( dep[x] > dep[y] ) swap( x, y ); ng( tid[x] + 1, tid[y], 1, n, 1 ); } } }go; int main() { //freopen( "tt.txt", "r", stdin ); int n, cas; scanf( "%d", &cas ); while( cas-- ) { scanf( "%d", &n ); go.init( n ); for( int i = 1; i < n; ++i ) { int u, v, c; scanf( "%d%d%d", &u, &v, &c ); go.add( u, v, c ); go.add( v, u, c ); } go.cut(); go.build( 1, n, 1 ); char s[10]; while( scanf( "%s", s ) && strcmp( s, "DONE" ) ) { if( s[0] == 'C' ) { int x, val; scanf( "%d%d", &x, &val ); go.update( go.tid[is[x-1]], val, 1, n, 1 ); } else { int a, b; scanf( "%d%d", &a, &b ); if( s[0] == 'N' ) go.NG( a, b ); else printf( "%d\n", go.calc( a, b ) ); } } } return 0; }
相关文章推荐
- poj 3237 Tree(树链剖分)
- poj 3237 Tree [LCA] (树链剖分)
- 【SPOJ 375】 【POJ 3237】 375. Query on a 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 (树链剖分 路径剖分 线段树的lazy标记)
- poj 3237 Tree 树链剖分 动态树 LCT
- POJ 3237 Tree (树链剖分)
- POJ 3237 Tree 树链剖分
- poj 3237 Tree 树链剖分
- poj 3237 Tree 树链剖分