ztx
[SDOI2011]染色
[SDOI2008]Cave 洞穴勘测

[POJ3237]树的维护

ztx posted @ 2015年1月17日 17:25 in 动态树 with tags LCT , 526 阅读
/****************************************\
* Author : ztx
* Title  : [POJ3237]树的维护
* ALG    : LCT
* CMT    :
* 很明显的动态树模型, 首先要把边权转化为点权,
* 并且要在dfs的时候记录每条边的权值在哪个点里面.
* 操作1 和3 是常规操作.
* 对于操作2, 我们对每个节点记录Max和Min, 取反就等价于Max = -Min , Min = -Max
* Time   :
\****************************************/
/****************************************\
* Author : ztx
* Title  : [POJ3237]树的维护
* ALG    : LCT
* CMT    :
* 很明显的动态树模型, 首先要把边权转化为点权,
* 并且要在dfs的时候记录每条边的权值在哪个点里面.
* 操作1 和3 是常规操作.
* 对于操作2, 我们对每个节点记录Max和Min, 取反就等价于Max = -Min , Min = -Max
* Time   :
\****************************************/

#include <cstdio>
#include <cstring>

int CH , NEG ;
inline void read(int& ret) {
    ret = NEG = 0 ; while (CH=getchar() , CH<'!') ;
    if (CH == '-') NEG = true , CH = getchar() ;
    while (ret = ret*10+CH-'0' , CH=getchar() , CH>'!') ;
    if (NEG) ret = -ret ;
}

inline void reads(int& ret) {
	while (ret=getchar() , ret<'!') ;
	while (CH=getchar() , CH>'!') ;
}

#define  maxn     10010LL
#define  maxe     20010LL
#define  infi     0x7f7f7f7fLL
#define  max(a,b) ((a)>(b)?(a):(b))
#define  min(a,b) ((a)<(b)?(a):(b))

struct FST { int to , next , val ; } e[maxe] ;
int star[maxn] = {0} , tote = 1 ;/* ! */
void AddEdge(int u , int v , int w) {
	e[++tote].to = v ; e[tote].val = w ; e[tote].next = star[u] ; star[u] = tote ;
	e[++tote].to = u ; e[tote].val = w ; e[tote].next = star[v] ; star[v] = tote ;
}

int fa[maxn] = {0} , ch[maxn][2] = {0} ;
int val[maxn] = {0} , maxv[maxn] = {0} , minv[maxn] = {0} ;
bool neg[maxn] = {0} ;

int belong[maxn] = {0} ;

#define null     0LL
#define left(u)  ch[u][0]
#define right(u) ch[u][1]

inline void Exchange(int&u,int&v) {int w=u;u=v;v=w;}
inline bool Isrt(int u) {
	return (!fa[u]) || ((left(fa[u])!=u)&&(right(fa[u])!=u)) ;
}

inline void Maintain(int u) {
	maxv[u] = minv[u] = val[u] ;
	if (left(u)) {
		maxv[u] = max(maxv[left(u)] , maxv[u]) ;
		minv[u] = min(minv[left(u)] , minv[u]) ;
	}
	if (right(u)) {
		maxv[u] = max(maxv[right(u)] , maxv[u]) ;
		minv[u] = min(minv[right(u)] , minv[u]) ;
	}
}

inline void Negated(int u) {
	if (u) {
		neg[u] ^= true ;
		val[u] = -val[u] ;
		maxv[u] = -maxv[u] ;
		minv[u] = -minv[u] ;
		Exchange(maxv[u] , minv[u]) ;
	}
}

inline void Clear(int u) {
	if (u && neg[u]) {
		Negated(left(u)) ;
		Negated(right(u)) ;
		neg[u] = false ;
	}
}

inline void zig(int x) {
    /* right rotate */
    int y = fa[x] , z = fa[y] ;
    if (left(z) == y) left(z) = x ; else if(right(z) == y) right(z) = x ; fa[x] = z ;
    fa[right(x)] = y ; left(y) = right(x) ; fa[y] = x ; right(x) = y ;
    Maintain(y) ;
}

inline void zag(int x) {
    /* left rotate */
    int y = fa[x] , z = fa[y] ;
    if (left(z) == y) left(z) = x ; else if(right(z) == y) right(z) = x ; fa[x] = z ;
    fa[left(x)] = y ; right(y) = left(x) ; fa[y] = x ; left(x) = y ;
    Maintain(y) ;
}

inline void Splay(int x) {
	Clear(x) ;
	int y , z ;
	while (!Isrt(x)) {
		y = fa[x] , z = fa[y] ;
		if (Isrt(y)) {
			Clear(y) , Clear(x) ;
			if (left(y) == x) zig(x) ; else zag(x) ;
		} else {
			Clear(z) , Clear(y) , Clear(x) ;
			if (left(z) == y) {
				if (left(y) == x) zig(x) , zig(x) ;
				else zag(x) , zig(x) ;
			} else if (right(z) == y) {
				if (right(y) == x) zag(x) , zag(x) ;
				else zig(x) , zag(x) ;
			}
		}
	}
	Maintain(x) ;
}

inline void Access(int u) {
	for (int v = null ; u ; u = fa[u]) {
		Splay(u) ; Clear(u) ;
		right(u) = v , v = u ; Maintain(u) ;
	}
}

int vis[maxn] = {0} ;
void Build(int u) {
	vis[u] = true ;
	int p , v ;
	for (p=star[u] ; p ; p =e[p].next) {
		v = e[p].to ;
		if (vis[v]) fa[u] = v ;
		else {
			val[v] = e[p].val ;
			belong[p>>1] = v ;
			Build(v) ;
		}
	}
}

void CHANGE(int u , int w) {
	u = belong[u] ; Splay(u) ; val[u] = w ;
}

void NEGATE(int u , int v) {
	Access(v) ;
	for (v = null ; u ; u = fa[u]) {
		Splay(u) ;
		if (!fa[u]) {
			Negated(v) , Negated(right(u)) ;
			return ;
		}
		Clear(u) ;
		right(u) = v , v = u ; Maintain(u) ;
	}
}

void QUERY(int u , int v) {
	Access(v) ;
	for (v = null ; u ; u = fa[u]) {
		Splay(u) ;
		if (!fa[u]) {
			printf("%d\n", max(maxv[v] , maxv[right(u)])) ;
			return ;
		}
		Clear(u) ;
		right(u) = v , v = u ; Maintain(u) ;
	}
}

int n , i , u , v , w ;

int main() {
    #define READ
    #ifdef  READ
        freopen("maintaintree.in" ,"r",stdin ) ;
        freopen("maintaintree.out","w",stdout) ;
    #endif
    read(n) ;
    for (i = 1 ; i < n ; i ++ ) {
    	read(u) , read(v) , read(w) ;
    	AddEdge(u , v , w) ;
	}
	maxv[null] = -infi , minv[null] = infi ;
	Build(1) ;
	while (reads(i) , i!='D') {
		read(u) , read(v) ;
		if (i == 'C') CHANGE(u , v) ;
		if (i == 'Q') QUERY(u , v) ;
		if (i == 'N') NEGATE(u , v) ;
	}
    #ifdef  READ
        fclose(stdin) ; fclose(stdout) ;
    #else
        getchar() ; getchar() ;
    #endif
    return 0 ;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter