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 v | Change the weight of the ith edge to v |
NEGATE a b | Negate the weight of every edge on the path from a to b |
QUERY a b | Find 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 a, b 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; }