BZOJ2843——极地旅行社

来源:互联网 发布:mac mini装win7 编辑:程序博客网 时间:2024/04/27 16:31
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;}


0 0
原创粉丝点击