spoj 375 AND bzoj 1036 树链剖分
树链剖分的入门题目,自己写了下感觉还是挺好写的,不过真的有点长...
spoj 375 边有权值:
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int INF = -999999999; 7 const int N = 10001; 8 int head[N]; 9 int sz[N]; 10 int depth[N]; 11 int num[N]; 12 int top[N]; 13 int dfn[N]; 14 int hc[N]; 15 int fa[N]; 16 int n, e, dfs_clock; 17 18 void init() 19 { 20 e = dfs_clock = 0; 21 memset( head, -1, sizeof(head) ); 22 } 23 24 struct Edge 25 { 26 int v, w, next; 27 } edge[N << 1]; 28 29 void addEdge( int u, int v, int w ) 30 { 31 edge[e].v = v; 32 edge[e].w = w; 33 edge[e].next = head[u]; 34 head[u] = e++; 35 } 36 37 void dfs1( int u, int pre, int dep ) 38 { 39 sz[u] = 1; 40 fa[u] = pre; 41 depth[u] = dep; 42 hc[u] = -1; 43 for ( int i = head[u]; i != -1; i = edge[i].next ) 44 { 45 int v = edge[i].v; 46 if ( v == pre ) continue; 47 dfs1( v, u, dep + 1 ); 48 sz[u] += sz[v]; 49 if ( hc[u] == -1 || sz[v] > sz[hc[u]] ) 50 { 51 hc[u] = v; 52 } 53 } 54 } 55 56 void dfs2( int u, int tp ) 57 { 58 top[u] = tp; 59 dfn[u] = ++dfs_clock; 60 if ( hc[u] != -1 ) 61 { 62 dfs2( hc[u], tp ); 63 } 64 for ( int i = head[u]; i != -1; i = edge[i].next ) 65 { 66 int v = edge[i].v; 67 if ( v == fa[u] ) continue; 68 if ( v == hc[u] ) 69 { 70 num[dfn[v]] = edge[i].w; 71 } 72 else 73 { 74 dfs2( v, v ); 75 num[dfn[v]] = edge[i].w; 76 } 77 } 78 } 79 80 struct Node 81 { 82 int l, r, maxn; 83 } node[N << 2]; 84 85 void pushup( int i ) 86 { 87 node[i].maxn = max( node[i << 1].maxn, node[i << 1 | 1].maxn ); 88 } 89 90 void build( int i, int l, int r ) 91 { 92 node[i].l = l, node[i].r = r; 93 if ( l == r ) 94 { 95 node[i].maxn = num[l]; 96 return ; 97 } 98 int mid = ( l + r ) >> 1; 99 build( i << 1, l, mid ); 100 build( i << 1 | 1, mid + 1, r ); 101 pushup(i); 102 } 103 104 void update( int i, int pos, int val ) 105 { 106 if ( node[i].l == pos && node[i].r == pos ) 107 { 108 node[i].maxn = val; 109 return ; 110 } 111 int mid = ( node[i].l + node[i].r ) >> 1; 112 if ( pos <= mid ) 113 { 114 update( i << 1, pos, val ); 115 } 116 else 117 { 118 update( i << 1 | 1, pos, val ); 119 } 120 pushup(i); 121 } 122 123 int query( int i, int l, int r ) 124 { 125 if ( node[i].l == l && node[i].r == r ) 126 { 127 return node[i].maxn; 128 } 129 int mid = ( node[i].l + node[i].r ) >> 1; 130 if ( r <= mid ) 131 { 132 return query( i << 1, l, r ); 133 } 134 else if ( l > mid ) 135 { 136 return query( i << 1 | 1, l, r ); 137 } 138 else 139 { 140 return max( query( i << 1, l, mid ), query( i << 1 | 1, mid + 1, r ) ); 141 } 142 } 143 144 struct Data 145 { 146 int u, v; 147 } d[N]; 148 149 int tree_query( int x, int y ) 150 { 151 int ans = INF; 152 while ( top[x] != top[y] ) 153 { 154 if ( depth[top[x]] < depth[top[y]] ) 155 { 156 swap( x, y ); 157 } 158 ans = max( ans, query( 1, dfn[top[x]], dfn[x] ) ); 159 x = fa[top[x]]; 160 } 161 if ( x != y ) 162 { 163 if ( depth[x] > depth[y] ) swap( x, y ); 164 ans = max( ans, query( 1, dfn[x] + 1, dfn[y] ) ); 165 } 166 return ans; 167 } 168 169 void tree_update( int x, int y ) 170 { 171 int u = d[x].u, v = d[x].v; 172 if ( depth[u] < depth[v] ) u = v; 173 update( 1, dfn[u], y ); 174 } 175 176 int main () 177 { 178 int t; 179 scanf("%d", &t); 180 while ( t-- ) 181 { 182 scanf("%d", &n); 183 init(); 184 for ( int i = 1; i < n; i++ ) 185 { 186 int u, v, w; 187 scanf("%d%d%d", &u, &v, &w); 188 addEdge( u, v, w ); 189 addEdge( v, u, w ); 190 d[i].u = u, d[i].v = v; 191 } 192 dfs1( 1, -1, 1 ); 193 dfs2( 1, 1 ); 194 build( 1, 2, n ); 195 char op[11]; 196 int x, y; 197 while ( 1 ) 198 { 199 scanf("%s", op); 200 if ( op[0] == 'D' ) break; 201 scanf("%d%d", &x, &y); 202 if ( op[0] == 'Q' ) 203 { 204 printf("%d\n", tree_query( x, y )); 205 } 206 else 207 { 208 tree_update( x, y ); 209 } 210 } 211 } 212 return 0; 213 }
bzoj 1036 点有权值:
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int INF = -9999999; 7 const int N = 30001; 8 int c[N]; 9 int head[N]; 10 int sz[N]; 11 int depth[N]; 12 int num[N]; 13 int top[N]; 14 int dfn[N]; 15 int hc[N]; 16 int fa[N]; 17 int n, e, dfs_clock; 18 19 void init() 20 { 21 e = dfs_clock = 0; 22 memset( head, -1, sizeof(head) ); 23 } 24 25 struct Edge 26 { 27 int v, next; 28 } edge[N << 1]; 29 30 void addEdge( int u, int v ) 31 { 32 edge[e].v = v; 33 edge[e].next = head[u]; 34 head[u] = e++; 35 } 36 37 void dfs1( int u, int pre, int dep ) 38 { 39 sz[u] = 1; 40 fa[u] = pre; 41 depth[u] = dep; 42 hc[u] = -1; 43 for ( int i = head[u]; i != -1; i = edge[i].next ) 44 { 45 int v = edge[i].v; 46 if ( v == pre ) continue; 47 dfs1( v, u, dep + 1 ); 48 sz[u] += sz[v]; 49 if ( hc[u] == -1 || sz[v] > sz[hc[u]] ) 50 { 51 hc[u] = v; 52 } 53 } 54 } 55 56 void dfs2( int u, int tp ) 57 { 58 top[u] = tp; 59 dfn[u] = ++dfs_clock; 60 num[dfn[u]] = c[u]; 61 if ( hc[u] != -1 ) 62 { 63 dfs2( hc[u], tp ); 64 } 65 for ( int i = head[u]; i != -1; i = edge[i].next ) 66 { 67 int v = edge[i].v; 68 if ( v == fa[u] || v == hc[u] ) continue; 69 dfs2( v, v ); 70 } 71 } 72 73 struct Node 74 { 75 int l, r; 76 int maxn, sum; 77 } node[N << 2]; 78 79 void pushup( int i ) 80 { 81 node[i].maxn = max( node[i << 1].maxn, node[i << 1 | 1].maxn ); 82 node[i].sum = node[i << 1].sum + node[i << 1 | 1].sum; 83 } 84 85 void build( int i, int l, int r ) 86 { 87 node[i].l = l, node[i].r = r; 88 if ( l == r ) 89 { 90 node[i].maxn = node[i].sum = num[l]; 91 return ; 92 } 93 int mid = ( l + r ) >> 1; 94 build( i << 1, l, mid ); 95 build( i << 1 | 1, mid + 1, r ); 96 pushup(i); 97 } 98 99 void update( int i, int pos, int val ) 100 { 101 if ( node[i].l == pos && node[i].r == pos ) 102 { 103 node[i].maxn = node[i].sum = val; 104 return ; 105 } 106 int mid = ( node[i].l + node[i].r ) >> 1; 107 if ( pos <= mid ) 108 { 109 update( i << 1, pos, val ); 110 } 111 else 112 { 113 update( i << 1 | 1, pos, val ); 114 } 115 pushup(i); 116 } 117 118 int query_max( int i, int l, int r ) 119 { 120 if ( node[i].l == l && node[i].r == r ) 121 { 122 return node[i].maxn; 123 } 124 int mid = ( node[i].l + node[i].r ) >> 1; 125 if ( r <= mid ) 126 { 127 return query_max( i << 1, l, r ); 128 } 129 else if ( l > mid ) 130 { 131 return query_max( i << 1 | 1, l, r ); 132 } 133 else 134 { 135 return max( query_max( i << 1, l, mid ), query_max( i << 1 | 1, mid + 1, r ) ); 136 } 137 } 138 139 int query_sum( int i, int l, int r ) 140 { 141 if ( node[i].l == l && node[i].r == r ) 142 { 143 return node[i].sum; 144 } 145 int mid = ( node[i].l + node[i].r ) >> 1; 146 if ( r <= mid ) 147 { 148 return query_sum( i << 1, l, r ); 149 } 150 else if ( l > mid ) 151 { 152 return query_sum( i << 1 | 1, l, r ); 153 } 154 else 155 { 156 return query_sum( i << 1, l, mid ) + query_sum( i << 1 | 1, mid + 1, r ); 157 } 158 } 159 160 int tree_query_max( int x, int y ) 161 { 162 int ans = INF; 163 while ( top[x] != top[y] ) 164 { 165 if ( depth[top[x]] < depth[top[y]] ) 166 { 167 swap( x, y ); 168 } 169 ans = max( ans, query_max( 1, dfn[top[x]], dfn[x] ) ); 170 x = fa[top[x]]; 171 } 172 if ( depth[x] > depth[y] ) swap( x, y ); 173 ans = max( ans, query_max( 1, dfn[x], dfn[y] ) ); 174 return ans; 175 } 176 177 int tree_query_sum( int x, int y ) 178 { 179 int ans = 0; 180 while ( top[x] != top[y] ) 181 { 182 if ( depth[top[x]] < depth[top[y]] ) 183 { 184 swap( x, y ); 185 } 186 ans += query_sum( 1, dfn[top[x]], dfn[x] ); 187 x = fa[top[x]]; 188 } 189 if ( depth[x] > depth[y] ) swap( x, y ); 190 ans += query_sum( 1, dfn[x], dfn[y] ); 191 return ans; 192 } 193 194 int main () 195 { 196 while ( scanf("%d", &n) != EOF ) 197 { 198 init(); 199 for ( int i = 1; i < n; i++ ) 200 { 201 int u, v; 202 scanf("%d%d", &u, &v); 203 addEdge( u, v ); 204 addEdge( v, u ); 205 } 206 for ( int i = 1; i <= n; i++ ) 207 { 208 scanf("%d", c + i); 209 } 210 dfs1( 1, -1, 1 ); 211 dfs2( 1, 1 ); 212 build( 1, 1, n ); 213 char op[11]; 214 int m, x, y; 215 scanf("%d", &m); 216 while ( m-- ) 217 { 218 scanf("%s%d%d", op, &x, &y); 219 if ( op[1] == 'M' ) 220 { 221 printf("%d\n", tree_query_max( x, y )); 222 } 223 else if ( op[1] == 'S' ) 224 { 225 printf("%d\n", tree_query_sum( x, y )); 226 } 227 else 228 { 229 update( 1, dfn[x], y ); 230 } 231 } 232 } 233 return 0; 234 }