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
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define rep(i,s,t) for(int i=s;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]]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[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;
}