1、题目大意:动态树问题,点修改,链查询。另外说明双倍经验题=bzoj1180
2、分析:lct模板题,练手的
#include <stack> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> using namespace std; namespace LinkCutTree{ struct Node{ Node *ch[2], *fa; int sum, num; bool rev; inline int which(); inline void reverse(){ if(this) rev ^= 1; } inline void pd(){ if(rev){ swap(ch[0], ch[1]); ch[0] -> reverse(); ch[1] -> reverse(); rev = false; } } inline void maintain(){ sum = num + ch[0] -> sum + ch[1] -> sum; } Node(); } *null = new Node, tree[30010], *pos[30010]; Node::Node(){ num = sum = 0; rev = false; ch[0] = ch[1] = fa = null; } inline int Node::which(){ if(fa == null || (this != fa -> ch[0] && this != fa -> ch[1])) return -1; return this == fa -> ch[1]; } inline void rotate(Node *o){ Node *p = o -> fa; int l = o -> which(), r = l ^ 1; o -> fa = p -> fa; if(p -> which() != -1) p -> fa -> ch[p -> which()] = o; p -> ch[l] = o -> ch[r]; if(o -> ch[r]) o -> ch[r] -> fa = p; o -> ch[r] = p; p -> fa = o; o -> ch[r] -> maintain(); o -> maintain(); } inline void splay(Node *o){ static stack<Node*> st; if(!o) return; Node *p = o; while(1){ st.push(p); if(p -> which() == -1) break; p = p -> fa; } while(!st.empty()){ st.top() -> pd(); st.pop(); } while(o -> which() != -1){ p = o -> fa; if(p -> which() != -1){ if(p -> which() ^ o -> which()) rotate(o); else rotate(p); } rotate(o); } } inline void Access(Node *o){ Node *y = null; while(o != null){ splay(o); o -> ch[1] = y; o -> maintain(); y = o; o = o -> fa; } } inline void MovetoRoot(Node *o){ Access(o); splay(o); o -> reverse(); } inline Node* FindRoot(Node *o){ Access(o); splay(o); while(o -> ch[0] != null) o = o -> ch[0]; return o; } inline void Link(Node *x, Node *y){ MovetoRoot(x); x -> fa = y; } inline void Cut(Node *x, Node *y){ MovetoRoot(x); Access(y); splay(y); y -> ch[0] = x -> fa = null; y -> maintain(); } } int main(){ using namespace LinkCutTree; int n; scanf("%d", &n); for(int i = 1; i <= n; i ++){ int x; scanf("%d", &x); pos[i] = &tree[i]; pos[i] -> sum = pos[i] -> num = x; } int m; scanf("%d", &m); char op[20]; int x, y; for(int i = 1; i <= m; i ++){ scanf("%s%d%d", op, &x, &y); if(op[0] == 'b'){ if(FindRoot(pos[x]) != FindRoot(pos[y])){ puts("yes"); Link(pos[x], pos[y]); } else puts("no"); } else if(op[0] == 'p'){ Access(pos[x]); splay(pos[x]); pos[x] -> num = y; pos[x] -> maintain(); } else{ if(FindRoot(pos[x]) != FindRoot(pos[y])) puts("impossible"); else{ MovetoRoot(pos[x]); Access(pos[y]); splay(pos[y]); printf("%d\n", pos[y] -> sum); } } } return 0; }