Time Limit: 5000MS | Memory Limit: 131072K | |
Total Submissions: 6171 | Accepted: 1687 |
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 a and 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
Source
用LCT维护链,记录链中的最大值和最小值,用flag标记是否取反
如果取反的话最大值=-的最小值,最小值=-最大值,更新一下即可
lCT参见我的其他博客
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<vector> using namespace std; #define maxn 500007 #define inf 1000000000 #define ll int struct Node{ Node *fa,*ch[2]; bool rev,root,flag,ty; int val; ll minv,mav; }; Node pool[maxn]; Node *nil,*tree[maxn],*road[maxn]; int cnt = 0; void init(){ cnt = 1; nil = tree[0] = pool; nil->ch[0] = nil->ch[1] = nil; nil->val = 0; nil->minv = -inf; nil->ty = 0; nil->flag = 0; } Node *newnode(int val,Node *f){ pool[cnt].fa = f; pool[cnt].ch[0]=pool[cnt].ch[1]=nil; pool[cnt].rev = false; pool[cnt].root = true; pool[cnt].val = val; pool[cnt].minv = pool[cnt].mav = val; pool[cnt].flag = 0; return &pool[cnt++]; } //左右子树反转******真正把结点变为根 void update_rev(Node *x){ if(x == nil) return ; x->rev = !x->rev; swap(x->ch[0],x->ch[1]); } void set_negate(Node *x){ if(x == nil) return ; x->flag = !x->flag; swap(x->minv,x->mav); x->minv = -x->minv; x->mav = -x->mav; } //splay向上更新信息****** void update(Node *x){ if(x == nil) return ; if(x->ty == 0) x->minv = inf,x->mav = -inf; else x->minv = x->val,x->mav = x->val; if(x->ch[0] != nil){ x->minv = min(x->minv,x->ch[0]->minv); x->mav = max(x->mav,x->ch[0]->mav); } if(x->ch[1] != nil){ x->minv = min(x->minv,x->ch[1]->minv); x->mav = max(x->mav,x->ch[1]->mav); } } //splay下推信息****** void pushdown(Node *x){ if(x == nil) return ; if(x->rev != false){ update_rev(x->ch[0]); update_rev(x->ch[1]); x->rev = false; } if(x->flag != false){ x->val = -x->val; set_negate(x->ch[0]); set_negate(x->ch[1]); x->flag = false; } } //splay在root-->x的路径下推信息****** void push(Node *x){ if(!x->root) push(x->fa); pushdown(x); } //将结点x旋转至splay中父亲的位置****** void rotate(Node *x){ Node *f = x->fa, *ff = f->fa; int t = (f->ch[1] == x); if(f->root) x->root = true, f->root = false; else ff->ch[ff->ch[1] == f] = x; x->fa = ff; f->ch[t] = x->ch[t^1]; x->ch[t^1]->fa = f; x->ch[t^1] = f; f->fa = x; update(f); } //将结点x旋转至x所在splay的根位置****** void splay(Node *x){ push(x); Node *f, *ff; while(!x->root){ f = x->fa,ff = f->fa; if(!f->root) if((ff->ch[1]==f)&&(f->ch[1] == x)) rotate(f); else rotate(x); rotate(x); } update(x); } //将x到树根的路径并成一条path****** Node *access(Node *x){ Node *y = nil,*z; while(x != nil){ splay(x); x->ch[1]->root = true; (x->ch[1] = y)->root = false; update(x); y = x; x = x->fa; } return y; } //将结点x变成树根****** void be_root(Node *x){ access(x); splay(x); update_rev(x); } //将x连接到结点f上****** void link(Node *x, Node *f){ be_root(x); x->fa = f; } char word[30]; int main(){ int n,q,s,t; Node*x,*y,*z; scanf("%d",&t); while(t--){ scanf("%d",&n); init(); int u,v,t; for(int i = 1;i <= n; i++){ tree[i] = newnode(0,nil); tree[i]->ty = 0; update(tree[i]); } for(int i = 1;i < n ;i++){ scanf("%d%d%d",&u,&v,&t); road[i] = newnode(t,nil); road[i]->ty = 1; update(road[i]); link(tree[u],road[i]); link(tree[v],road[i]); } while(1){ scanf("%s",word); if(word[0] == 'D') break; scanf("%d%d",&u,&v); if(word[0] == 'Q'){ be_root(tree[u]); x = access(tree[v]); printf("%d\n",x->mav); } else if(word[0] == 'C'){ be_root(road[u]); road[u]->val = v; update(road[u]); } else if(word[0] == 'N'){ be_root(tree[u]); x = access(tree[v]); set_negate(x); } } } return 0; } /* 1 3 1 2 1 2 3 2 QUERY 1 2 CHANGE 1 3 QUERY 1 2 N 1 3 Q 1 2 */