poj 3237 Tree树剖边权更新模板

来源:互联网 发布:手游天龙部3D百度端口 编辑:程序博客网 时间:2024/06/05 02:56

题意:将树上某条路径的值正负倒换,或者使某条边变成val,或者查询某条路径上的最大的边权

裸边权更新,与点权更新不同的是,边权中记录边的编号是pos[x] + 1,也就是由重建链之后的子节点记录,pos[x]+1同pos[ son[x] ]。

详见代码,另附有数据

#include <map>#include <set>#include <queue>#include <stack>#include <vector>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define lson l, mid, rt << 1#define rson mid + 1, r, rt << 1 | 1#define pi acos(-1.0)#define eps 1e-8typedef long long ll;const int inf = 0x3f3f3f3f;const int N = 10010;struct node{int v, nxt;}e[N << 2];struct pp{int x, y, z;pp(){}pp( int x, int y, int z ): x(x), y(y), z(z){}}p[N];int tot, cnt, n;int head[N];int pos[N];int dep[N];int top[N];int val[N];int son[N];int pre[N];int sz[N];void init(){sz[0] = dep[1] = 0;memset( head, -1, sizeof( head ) );cnt = tot = 0;}void add( int u, int v ){e[cnt].v = v;e[cnt].nxt = head[u];head[u] = cnt++;e[cnt].v = u;e[cnt].nxt = head[v];head[v] = cnt++;}void dfs( int u ){sz[u] = 1;son[u] = 0;for( int i = head[u]; ~i; i = e[i].nxt ){int v = e[i].v;if( v == pre[u] )continue;dep[v] = dep[u] + 1;pre[v] = u;dfs( v );sz[u] += sz[v];if( sz[v] > sz[ son[u] ] )son[u] = v;}}void rebuild( int u, int anc ){pos[u] = ++tot;top[u] = anc;if( son[u] )rebuild( son[u], anc );for( int i = head[u]; ~i; i = e[i].nxt ){int v = e[i].v;if( v != pre[u] && v != son[u] )rebuild( v, v );}}struct seg{int l, r;int mx, mn;int add;}tr[N << 2];void pushup( int rt ){tr[rt].mx = max( tr[rt<<1].mx, tr[rt<<1|1].mx );tr[rt].mn = min( tr[rt<<1].mn, tr[rt<<1|1].mn );}void f( int rt ){tr[rt].add ^= 1;int minn = tr[rt].mn, maxx = tr[rt].mx;tr[rt].mx = -minn;tr[rt].mn = -maxx;}void down( int rt ){if( tr[rt].add ){//tr[rt<<1].add = tr[rt<<1|1].add = tr[rt].add;f( rt << 1 );f( rt << 1 | 1 );tr[rt].add = 0;}}void build( int l, int r, int rt ){tr[rt].l = l;tr[rt].r = r;tr[rt].add = 0;if( l == r ){tr[rt].mx = tr[rt].mn = val[l];return;}int mid = (l + r) >> 1;build( lson );build( rson );pushup( rt );}void update_point( int pos, int v, int rt ){if( tr[rt].l == tr[rt].r && tr[rt].l == pos ){tr[rt].mn = tr[rt].mx = v;return;}down(rt);int mid = ( tr[rt].l + tr[rt].r ) >> 1;if( pos <= mid )update_point( pos, v, rt << 1 );elseupdate_point( pos, v, rt << 1 | 1 );pushup( rt );}void update( int l, int r, int rt ){if( l <= tr[rt].l && tr[rt].r <= r ){f( rt );return;}down( rt );int mid = ( tr[rt].l + tr[rt].r ) >> 1;if( r <= mid )update( l, r, rt << 1 );else if( l > mid )update( l, r, rt << 1 | 1 );else{update( lson );update( rson );}pushup( rt );}int query( int l, int r, int rt ){if( l <= tr[rt].l && tr[rt].r <= r ){return tr[rt].mx;}down( rt );int mid = ( tr[rt].l + tr[rt].r ) >> 1;if( r <= mid )return query( l, r, rt << 1 );else if( l > mid )return query( l, r, rt << 1 | 1 );elsereturn max( query( lson ), query( rson ) );}void update1( int x, int y ){while( top[x] != top[y] ){int f1 = top[x], f2 = top[y];if( dep[f1] > dep[f2] ){update( pos[f1], pos[x], 1 );x = pre[f1];}else{update( pos[f2], pos[y], 1 );y = pre[f2];}}if( x == y )return;if( dep[x] > dep[y] )swap( x, y );update( pos[x]+1, pos[y], 1 );}int query1( int x, int y ){int res = -inf;while( top[x] != top[y] ){int f1 = top[x], f2 = top[y];if( dep[f1] > dep[f2] ){res = max( res, query( pos[f1], pos[x], 1) );x = pre[f1];}else{res = max( res, query( pos[f2], pos[y], 1) );y = pre[f2];}}if( x == y )return res;if( dep[x] > dep[y] )swap( x, y );return max( res, query( pos[x]+1, pos[y], 1 ) );//pos[x] + 1 是因为比如有边1->2 = 3,那么val存这条边的时候,val[2] = 3(这里假设pos[x] = x),//所以update的时候点的编号要+1,也就是说pos[x]记录的是x与其父亲的边,即pos[son] = pos[fa] + 1,// 故还可写成query(pos[son[x]], pos[y], 1)//在while中没+1,是因为从top[x]到x就是一条完整的链(top【x】是根x是最下子节点)}int main(){int tt;scanf("%d", &tt);while( tt-- ){scanf("%d", &n );init();int u, v, w;for( int i = 1; i < n; ++i ){scanf("%d%d%d", &u, &v, &w);add( u, v );p[i] = pp( u, v, w );}dfs( 1 );rebuild( 1, 1 );for( int i = 1; i < n; i++ ){if( dep[p[i].x] < dep[p[i].y] )swap( p[i].x, p[i].y );val[ pos[p[i].x] ] = p[i].z;//printf("old: %d new: %d val: %d\n", p[i].x, pos[p[i].x], val[pos[p[i].x]]);}build( 2, n, 1 );char op[10];while( ~scanf("%s", op)){if( op[0] == 'D' )break;scanf("%d%d", &u, &v);if( op[0] == 'C' )update_point( pos[p[u].x], v, 1 );else if( op[0] == 'N' )update1( u, v );else{int ans = query1(u, v);printf("%d\n", ans);}}}return 0;}/*3101 2 12 3 73 4 84 5 65 6 96 7 17 8 18 9 79 10 6NEGATE 4 7CHANGE 2 3QUERY 2 9CHANGE 2 3QUERY 6 8NEGATE 1 8CHANGE 2 7QUERY 1 3NEGATE 1 5CHANGE 4 7QUERY 3 5DONE61 2 12 3 23 4 44 5 1005 6 -1000QUERY 1 2CHANGE 1 3QUERY 1 2NEGATE 1 2QUERY 1 3QUERY 1 2CHANGE 1 10QUERY 1 3NEGATE 1 2QUERY 1 3CHANGE 1 10CHANGE 2 20QUERY 1 3NEGATE 1 2QUERY 1 3NEGATE 2 3QUERY 1 3CHANGE 1 -100CHANGE 2 -1000QUERY 1 4NEGATE 1 6QUERY 1 6DONE1001 2 2652 3 1333 4 5084 5 1975 6 4376 7 8497 8 5778 9 5039 10 47810 11 43411 12 87712 13 69113 14 5414 15 29515 16 42116 17 16617 18 55018 19 41019 20 86820 21 47621 22 28322 23 41023 24 91524 25 30825 26 30126 27 55327 28 60928 29 73329 30 77030 31 63531 32 58132 33 75333 34 70734 35 44835 36 73836 37 84137 38 38938 39 53239 40 21040 41 45841 42 59542 43 98943 44 67844 45 21445 46 74646 47 54847 48 11748 49 75849 50 43750 51 84051 52 55552 53 72653 54 49054 55 71955 56 40356 57 32957 58 9258 59 31159 60 66460 61 20761 62 17062 63 54863 64 71364 65 55665 66 70566 67 8267 68 50868 69 5969 70 4570 71 67071 72 54072 73 82673 74 26274 75 50475 76 98976 77 40877 78 89678 79 38879 80 1580 81 48581 82 21982 83 97783 84 64184 85 98585 86 18986 87 6487 88 64188 89 32089 90 78890 91 44191 92 78592 93 16393 94 15394 95 85295 96 3696 97 1097 98 14598 99 95699 100 641QUERY 32 69NEGATE 1 22CHANGE 40 53QUERY 17 38NEGATE 17 65CHANGE 49 68QUERY 44 52NEGATE 11 53CHANGE 9 68QUERY 2 49NEGATE 25 45CHANGE 23 67QUERY 89 90NEGATE 5 37CHANGE 27 53QUERY 22 86NEGATE 6 7CHANGE 17 23QUERY 78 93NEGATE 30 63CHANGE 56 99QUERY 3 29NEGATE 24 38CHANGE 9 95QUERY 63 66NEGATE 69 92CHANGE 9 91QUERY 7 27NEGATE 32 60CHANGE 48 77QUERY 47 94NEGATE 14 27CHANGE 50 99QUERY 38 97NEGATE 11 67CHANGE 74 83QUERY 28 81NEGATE 13 53CHANGE 55 88QUERY 2 66NEGATE 71 95CHANGE 32 74QUERY 14 50NEGATE 1 28CHANGE 16 80QUERY 36 75NEGATE 20 49CHANGE 22 54QUERY 5 46NEGATE 12 37CHANGE 61 94QUERY 18 92NEGATE 19 26CHANGE 6 94QUERY 33 60NEGATE 79 87CHANGE 30 75QUERY 55 94NEGATE 28 79CHANGE 23 31QUERY 91 95NEGATE 28 76CHANGE 8 41QUERY 6 25NEGATE 19 70CHANGE 17 54QUERY 52 66NEGATE 4 95CHANGE 19 52QUERY 73 87DONEans:8178132-31022020-104100098991568989788989985868705868840852989877746826989989989989785868705985*/


0 0
原创粉丝点击