poj 3237 Tree

Tree
Time Limit: 5000MS Memory Limit: 131072K
Total Submissions: 3532 Accepted: 989

Description

You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edges are numbered 1 through N − 1. Each edge is associated with a weight. Then you are to execute a series of instructions on the tree. The instructions can be one of the following forms:

CHANGE i vChange the weight of the ith edge to v
NEGATE a bNegate the weight of every edge on the path from a to b
QUERY a bFind the maximum weight of edges on the path from a to b

Input

The input contains multiple test cases. The first line of input contains an integer t (t ≤ 20), the number of test cases. Then follow the test cases.

Each test case is preceded by an empty line. The first nonempty line of its contains N (N ≤ 10,000). The next N − 1 lines each contains three integers ab and c, describing an edge connecting nodes aand b with weight c. The edges are numbered in the order they appear in the input. Below them are the instructions, each sticking to the specification above. A lines with the word “DONE” ends the test case.

Output

For each “QUERY” instruction, output the result on a separate line.

Sample Input

1

3
1 2 1
2 3 2
QUERY 1 2
CHANGE 1 3
QUERY 1 2
DONE

Sample Output

1
3
 
存下区间最大值和最小值,NEGATE后,Max=-Min,Min=-Max.
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <queue>
#include <stack>
#include <vector>
#include <math.h>
#include <algorithm>
using namespace std;

#define rep(i,s,t) for(int i=s;i<t;i++)
#define red(i,s,t) for(int i=s-1;i>=t;i--)
#define ree(i,now) for(int i=head[now];i!=-1;i=edge[i].next)
#define L t<<1
#define R t<<1|1
#define clr(a,v) memset(a,v,sizeof a)
typedef long long ll;

inline int input(){  
	int ret=0;bool isN=0;char c=getchar(); 
	while(c<'0' || c>'9'){  
		if(c=='-') isN=1;  
		c=getchar();  
	}  
	while(c>='0' && c<='9'){
		ret=ret*10+c-'0';c=getchar();  
	}  
	return isN?-ret:ret;  
}  

inline void output(int x){  
	if(x<0){  
		putchar('-');x=-x;  
	}  
	int len=0,data[11];  
	while(x){  
		data[len++]=x%10;x/=10;  
	}  
	if(!len)    data[len++]=0;  
	while(len--) 
		putchar(data[len]+48);  
	putchar('\n');
}


const int MAXN=10005;
struct Edge{
	int v,next;
}edge[MAXN<<1];
int head[MAXN],e;
int t,n,a[MAXN],b[MAXN],c[MAXN];
int cnt,size[MAXN],son[MAXN],fa[MAXN],dep[MAXN],to[MAXN],top[MAXN];
int w[MAXN];
int Max[MAXN<<2],Min[MAXN<<2];
bool lazy[MAXN<<2];
char op[10];
int x,y;

inline void addEdge(int u,int v){
	edge[e].v=v;
	edge[e].next=head[u];
	head[u]=e++;
}

inline void push_up(int t){
	Max[t]=max(Max[L],Max[R]);
	Min[t]=min(Min[L],Min[R]);
}

inline void changeVal(int t){
	int r=Max[t];
	Max[t]=-Min[t];
	Min[t]=-r;
}

inline void push_down(int t){
	if(lazy[t]){
		lazy[t]^=1;
		lazy[L]^=1;changeVal(L);
		lazy[R]^=1;changeVal(R);
	}
}

inline void build(int t,int x,int y){
	if(x==y){
		Max[t]=Min[t]=w[x];
	}
	else{
		int mid=(x+y)>>1;
		build(L,x,mid),build(R,mid+1,y);
		push_up(t);
	}
}

inline void modefiy(int t,int l,int r,int x,int y){
	if(l>=x && r<=y){
		lazy[t]^=1;
		changeVal(t);
	}
	else{
		push_down(t);
		int mid=(l+r)>>1;
		if(y<=mid) modefiy(L,l,mid,x,y);
		else if(x>mid) modefiy(R,mid+1,r,x,y);
		else modefiy(L,l,mid,x,mid),modefiy(R,mid+1,r,mid+1,y);
		push_up(t);
	}
}

inline void change(int t,int l,int r,int x,int v){
	if(l==r) Max[t]=Min[t]=v;
	else{
		push_down(t);
		int mid=(l+r)>>1;
		if(x<=mid) change(L,l,mid,x,v);
		else change(R,mid+1,r,x,v);
		push_up(t); 
	}
}

inline int query(int t,int l,int r,int x,int y){
	if(l>=x && r<=y) return Max[t];
	push_down(t);
	int mid=(l+r)>>1;
	if(y<=mid) return query(L,l,mid,x,y);
	else if(x>mid) return query(R,mid+1,r,x,y);
	else return max(query(L,l,mid,x,mid),query(R,mid+1,r,mid+1,y));
}

inline void dfs(int now,int pre,int d){
	size[now]=1;son[now]=0;
	fa[now]=pre,dep[now]=d;
	ree(i,now){
		int nxt=edge[i].v;
		if(nxt!=pre){
			dfs(nxt,now,d+1);
			size[now]+=size[nxt];
			if(size[son[now]]<size[nxt]){
				son[now]=nxt;
			}
		}
	}
}

inline void dfs2(int now,int tp){  
    to[now]=(++cnt);  
    top[now]=tp;  
    if(son[now]) dfs2(son[now],tp);  
    ree(i,now){  
        int nxt=edge[i].v;  
        if(nxt!=son[now] && nxt!=fa[now]){  
            dfs2(nxt,nxt);  
        }  
    }  
}  

inline void Solve(int a,int b){
	int f1=top[a],f2=top[b];
	while(f1!=f2){
		if(dep[f1]<dep[f2]){
			swap(a,b),swap(f1,f2);
		}
		modefiy(1,1,cnt,to[f1],to[a]);
		a=fa[f1];
		f1=top[a];
	}
	if(a==b) return;
	if(dep[a]>dep[b]) swap(a,b);
	modefiy(1,1,cnt,to[son[a]],to[b]);
}

inline int getAns(int a,int b){
	int ans=(-1000000000),f1=top[a],f2=top[b];
	while(f1!=f2){  
        if(dep[f1]<dep[f2]){  
        	swap(a,b),swap(f1,f2);  
        }  
        ans=max(ans,query(1,1,cnt,to[f1],to[a]));  
        a=fa[f1];  
        f1=top[a];  
    }  
    if(a==b) return ans;  
    if(dep[a]>dep[b]) swap(a,b);  
    return max(ans,query(1,1,cnt,to[son[a]],to[b]));  
}

int main(){
	t=input();
	rep(ca,0,t){
		n=input();
		clr(head,-1),e=0;
		clr(son,0),cnt=0;
		rep(i,1,n){
			a[i]=input(),b[i]=input(),c[i]=input();
			addEdge(a[i],b[i]);
			addEdge(b[i],a[i]);
		}
		clr(lazy,0);
		son[0]=size[0]=top[0]=0;
		dfs(1,1,0);w[1]=-1000000000;
		dfs2(1,1);
		rep(i,1,n){
			if(dep[a[i]]>dep[b[i]]) swap(a[i],b[i]);
			b[i]=to[b[i]];
			w[b[i]]=c[i];
		}
		build(1,1,cnt);
		while(scanf("%s",op),op[0]!='D'){
			if(op[0]=='C'){
				x=input(),y=input();
				change(1,1,cnt,b[x],y);
			}
			else if(op[0]=='N'){
				x=input(),y=input();
				Solve(x,y);
			}
			else{
				x=input(),y=input();
				if(x==y) output(0);
				else	output(getAns(x,y));
			}
		}
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值