记录编号 216989 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [POJ 3237] 树的维护 最终得分 100
用户昵称 Gravatar一個人的雨 是否通过 通过
代码语言 C++ 运行时间 1.567 s
提交时间 2016-01-01 19:43:00 内存使用 32.19 MiB
显示代码纯文本
#include<map>
#include<set>
#include<queue>
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=210000+10;
struct seg{
	int l,r,delta;
	seg *lc,*rc;
	int mx,mi;
	seg():mx(0),mi(0),delta(0){}
};
seg *root=new seg;
int Belong[maxn],deep[maxn],size[maxn];
struct edge{
	int to,next,w,f;
}G[maxn*5];
int n,m,q,tot=0,h[maxn];
int fa[maxn][16],pos[maxn];
int ans,ind=0;
bool vis[maxn];
int X[maxn],Y[maxn],Z[maxn];
char ch;
int read(){
	int num=0; ch=getchar();
	while (ch<'!') ch=getchar();
    while (ch>='0'&&ch<='9'){num=num*10+ch-'0';ch=getchar();}
	return num;
}

void add(int x,int y,int z){
	++tot; G[tot].to=y; G[tot].w=z;
	G[tot].next=h[x]; h[x]=tot;
}

void DFS1(int x,int dep){
	deep[x]=dep; size[x]=1; vis[x]=1;
	for (int i=1;i<=15;++i){
		if (deep[x]<(1<<i)) break;
		fa[x][i]=fa[fa[x][i-1]][i-1];
	}
	for (int i=h[x];i;i=G[i].next){
		int v=G[i].to;
		if (vis[v]) continue;
		fa[v][0]=x;
		DFS1(v,dep+1);
		size[x]+=size[v];
	}
}

void DFS2(int x,int L){
	int k=0; ++ind;
	pos[x]=ind;
	Belong[x]=L;
	for (int i=h[x];i;i=G[i].next)
	   if (deep[x]<deep[G[i].to]&&size[G[i].to]>size[k])
	      k=G[i].to;
	if (!k) return ;
	DFS2(k,L);
	for (int i=h[x];i;i=G[i].next)
	   if (deep[x]<deep[G[i].to]&&k!=G[i].to)
	      DFS2(G[i].to,G[i].to);
}

void build(seg *p,int l,int r){
	p->l=l; p->r=r;
	if (l+1==r) return;
	else if (l+1<r){
		int mid=(l+r)>>1;
		p->lc=new seg;
		p->rc=new seg;
		if (l<mid) build(p->lc,l,mid);
		if (mid<r) build(p->rc,mid,r);
	}
}

void updatemax(seg *p){//以后带标记时都要这么些
	if (p->l+1==p->r) return;
	if (p->lc) p->mx=p->lc->mx;
	else{
		if (p->rc) p->mx=p->rc->mx;
		return;
	}
	if (p->rc)
	    p->mx=max(p->mx,p->rc->mx);
}

void updatemin(seg *p){
	if (p->l+1==p->r) return;
	if (p->lc) p->mi=p->lc->mi;
	else{
		if (p->rc) p->mi=p->rc->mi;
		return;
	}
	if (p->rc)
		p->mi=min(p->mi,p->rc->mi);
}

void Swap(seg *p){
	int t=p->mx; p->mx=-p->mi; p->mi=-t;
}

void push_down(seg *p){//注意标记的写法,更新儿子的值
	if (!p->delta) return;
	else{
		p->delta=0;
		if (p->l+1==p->r) return;
		if (p->lc) p->lc->delta^=1;
		if (p->rc) p->rc->delta^=1;
		if (p->lc) Swap(p->lc);
		if (p->rc) Swap(p->rc);
	}
}

void update(seg *p,int pos,int val){
	if (p->l+1==p->r){p->mx=p->mi=val;return ;}
	else{
		int mid=(p->l+p->r)>>1;
		if (p->delta) push_down(p);
		if (pos<mid) update(p->lc,pos,val);
		if (mid<=pos) update(p->rc,pos,val);
		updatemax(p); updatemin(p);
	}
}

void Qmax(seg *p,int l,int r){//对于这道题要改就改到底,否则会影响程序正确性
	if (l<=p->l&&p->r<=r){
		push_down(p);
		if (p->l+1==p->r){
			ans=max(ans,p->mx);
			return;
		}
		if (p->lc) Qmax(p->lc,l,r);
		if (p->rc) Qmax(p->rc,l,r);
		updatemax(p); updatemin(p);
        ans=max(ans,p->mx);
	}else{
		push_down(p);
		if (p->l+1==p->r) return;
		int mid=(p->l+p->r)>>1;
		if (l<mid) Qmax(p->lc,l,r);
		if (mid<r) Qmax(p->rc,l,r);
		updatemax(p); updatemin(p);
	}
}

void change(seg *p,int l,int r){
	if (l<=p->l&&p->r<=r){
		p->delta^=1;
		if (p->l+1==p->r){Swap(p);}
		return;}
	else{
		if (p->delta) push_down(p);
		int mid=(p->l+p->r)>>1;
		if (l<mid) change(p->lc,l,r);
		if (mid<r) change(p->rc,l,r);
		updatemax(p); updatemin(p);
	}
}

int solve(int u,int v){
	int sum=-100000000;
	bool flag=0;
	if (u==9) flag=1;
	while (Belong[u]!=Belong[v]){
		ans=-100000000;
		Qmax(root,pos[Belong[u]],pos[u]+1);
		sum=max(sum,ans); u=fa[Belong[u]][0];
	}
	ans=-100000000; Qmax(root,pos[v]+1,pos[u]+1);//注意这里的pos[v]+1
	sum=max(sum,ans); return sum;
}

int LCA(int a,int b){
	if (deep[a]<deep[b]) swap(a,b);
	int t=deep[a]-deep[b];
	for (int i=0;i<=15;++i)
	   if (t&(1<<i)) a=fa[a][i];
	for (int i=15;~i;i--)
	   if (fa[a][i]!=fa[b][i]){
	   	   a=fa[a][i];b=fa[b][i];}
	if (a==b) return a;
	else return fa[a][0];
}

void Fchange(int u,int v){
	while (Belong[u]!=Belong[v]){
		change(root,pos[Belong[u]],pos[u]+1);
		u=fa[Belong[u]][0];
		if (u==0) return;
	}
	change(root,pos[v]+1,pos[u]+1);
}

int main(){
	freopen("maintaintree.in","r",stdin);
	freopen("maintaintree.out","w",stdout);
	n=read();
	for (int i=1;i<n;++i){
		int x,y,z;
		x=read(); y=read(); z=read();
		add(x,y,z); add(y,x,z);
		X[i]=x; Y[i]=y; Z[i]=z;
	}
	DFS1(1,1);
	DFS2(1,1);
	build(root,1,ind+1);
	update(root,pos[1],-100000000);
	for (int i=1;i<n;++i){
		int u=X[i],v=Y[i],w=Z[i];
		if (deep[u]<deep[v]) swap(u,v);
		update(root,pos[u],w);
 	}
	char ch[10]; int x,y;
	while (scanf("%s",ch)==1){
		if (ch[0]=='D') break;
		x=read(); y=read();
		if (ch[0]=='C'){
			int a=X[x],b=Y[x],Aim;
			if(deep[a]>deep[b])Aim=a;else Aim=b;
			Z[Aim]=y; update(root,pos[Aim],y);
		}else if (ch[0]=='N'){
			int zx=LCA(x,y);
		    Fchange(x,zx); Fchange(y,zx);
		}else{
			int zx=LCA(x,y);
			printf("%d\n",max(solve(x,zx),solve(y,zx)));
		}
	}
	//system("pause");
	//碉堡啦!
}