记录编号 156950 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [POJ 3237] 树的维护 最终得分 100
用户昵称 Gravatarztx 是否通过 通过
代码语言 C++ 运行时间 1.331 s
提交时间 2015-04-06 21:24:57 内存使用 0.75 MiB
显示代码纯文本
/****************************************\
* Author : ztx
* Title  : [cogs] 1583. [POJ3237]树的维护
* ALG    : LCT复习
* CMT    :
链上边权最大值
* Time   :
\****************************************/

#include <cstdio>
#define Rep(i,l,r) for(i=(l);i<=(r);i++)
#define Rev(i,r,l) for(i=(r);i>=(l);i--)
typedef long long ll ;
int CH , NEG ;
template <typename TP>inline void read(TP& 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 ;
}
template <typename TP>inline void reads(TP& ret) {
	while (ret=getchar() , ret<'!') ;
	while (CH=getchar() , CH>'!') ;
}

#define  maxn  10010LL

int fa[maxn] , ch[maxn][2] ;
int val[maxn] , maxv[maxn] , minv[maxn] ;
bool rev[maxn] ;

#define  null     0LL
#define  left(u)  ch[u][0]
#define  right(u) ch[u][1]
#define  max(x,y) ((x)>(y)?(x):(y))
#define  min(x,y) ((x)<(y)?(x):(y))
#define  infi     0x7f7f7f7fLL

inline void Exchange(int&a,int&b) {int c=a;a=b;b=c;}
inline bool Isrt(int u) { return !fa[u]||(left(fa[u])!=u&&right(fa[u])!=u) ; }
inline void Reverse(int u) {
	if (!u) return ;
	rev[u]^=true , val[u]=-val[u] ;
	Exchange(maxv[u],minv[u]) , maxv[u]=-maxv[u] , minv[u]=-minv[u] ;
}
inline void Clear(int u) {
	if (!u || !rev[u]) return ;
	rev[u] = false , Reverse(left(u)) , Reverse(right(u)) ;
}
inline void Maintain(int u) {
	maxv[u] = minv[u] = val[u] ;
	if (left(u)) {
		maxv[u] = max(maxv[u],maxv[left(u)]) ;
		minv[u] = min(minv[u],minv[left(u)]) ;
	}
	if (right(u)) {
		maxv[u] = max(maxv[u],maxv[right(u)]) ;
		minv[u] = min(minv[u],minv[right(u)]) ;
	}
}
inline void Rot(int x , int d) {
	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[y]=x,fa[ch[x][d]]=y;
	ch[y][!d]=ch[x][d],ch[x][d]=y;
	Maintain(y) ;
}
inline void Splay(int x) {
int y , z ;
	Clear(x) ;
	while (!Isrt(x)) {
		y=fa[x] , z=fa[y] ;
		Clear(z) , Clear(y) , Clear(x) ;
		if (Isrt(y)) Rot(x,left(y)==x) ;
		else if (left(z)==y) {
			if (left(y)==x) Rot(y,1) ;
			else Rot(x,0) ; Rot(x,1) ;
		} else {
			if (right(y)==x) Rot(y,0) ;
			else Rot(x,1) ; Rot(x,0) ;
		}
	}
	Maintain(x) ;
}
inline void Access(int u) {
	for (int v=null;u;v=u,u=fa[u]) Splay(u),right(u)=v,Maintain(u) ;
}
inline void NodeChange(int u , int w) {
	Splay(u) , val[u] = w ; Maintain(u) ;
}
inline void ChainRev(int u , int v) {
	for (Access(v),v=null;u;v=u,u=fa[u]) {
		Splay(u) ;
		if (!fa[u])
			Reverse(v) , Reverse(right(u)) ;
		right(u)=v , Maintain(u) ;
	}
}
inline void ChainMax(int u , int v) {
	for (Access(v),v=null;u;v=u,u=fa[u]) {
		Splay(u) ;
		if (!fa[u])
			printf("%d\n", max(maxv[v],maxv[right(u)])) ;
		right(u)=v , Maintain(u) ;
	}
}

#define  maxm  10010LL
int belong[maxm] = {0} ;
struct FST { int to , next , len ; } e[maxm<<1] ;
int star[maxn] = {0} , tote = 1 ;
inline void AddEdge(int u , int v , int w) { e[++tote].to = v ; e[tote].len = w ; e[tote].next = star[u] ; star[u] = tote ; }
inline void GetPar(int u) {
	for (int p=star[u] ; p ; p=e[p].next)
		if (e[p].to != fa[u]) {
			belong[p>>1] = e[p].to ;
			maxv[e[p].to] = minv[e[p].to] = val[e[p].to] = e[p].len ;
			fa[e[p].to] = u ;
			GetPar(e[p].to) ;
		}
}

int main() {
int n , m , i , u , v , w , cmd ;
	#define READ
	#ifdef  READ
		freopen("maintaintree.in" ,"r",stdin ) ;
		freopen("maintaintree.out","w",stdout) ;
	#endif
	read(n) ;
	Rep (i,2,n) {
		read(u) , read(v) , read(w) ;
		AddEdge(u,v,w) ;
		AddEdge(v,u,w) ;
	}
	maxv[null] = -infi ;
	minv[null] = infi ;
	/*   QAQ我特么又犯了一遍这个错   */
	GetPar(1) ;
	while (true) {
		reads(cmd) ;
		if (cmd == 'D') break ;
		read(u) , read(v) ;
		if (cmd == 'C') NodeChange(belong[u],v) ;
		if (cmd == 'Q') ChainMax(u,v) ;
		if (cmd == 'N') ChainRev(u,v) ;
	}
	#ifdef  READ
		fclose(stdin) ; fclose(stdout) ;
	#else
		getchar() ; getchar() ;
	#endif
	return 0 ;
}