【SDOI2008】Cave Survey-LCT

Topic description

Huihui is keen on cave surveying.

One day, he followed the map to a cave group area marked as JSZX. After preliminary investigation, Huihui found that this area consists of n caves (numbered 1 to n respectively) and several passages, and each passage connects exactly two caves. If two caves can be connected in a certain order through one or more passages, then the two caves are connected, and these passages connected in sequence are called a path between the two caves. The caves are all very solid and cannot be destroyed, but the passage is not stable and often changes due to external influences. For example, according to the monitoring results of relevant instruments, there is sometimes a passage between Cave 123 and Cave 127, and sometimes this passage is different. will be destroyed for some bizarre reason.

Huihui has a monitoring instrument that can display every change of the channel in real time on the terminal at Huihui's hand:

If a passage between cave u and cave v is detected, a command will be displayed on the terminal Connect u v

If the passage between cave u and cave v is detected to be destroyed, a command will be displayed on the terminal Destroy u v

After a long period of painstaking manual calculation, Huihui discovered a strange phenomenon: no matter how the passage changes, there is at most one path between any two caves at any time.

Therefore, Huihui firmly believes that this is due to the domination of some essential law. Therefore, Huihui stayed in front of the terminal day and night, trying to study this essential law through the change of the channel. However, finally one day, Huihui collapsed in the pile of calculation paper... He slammed the terminal on the ground (the terminal was also strong enough to be broken), turned to you and said, "You dude put this Write the program."

Huihui hopes to send an instruction through the terminal at any time  Query u vto ask the monitor whether the cave u and the cave v are connected at this time. Now you have to program him to answer every query. It is known that no passages exist in the JSZX cave complex until the first command is displayed.

Input and output format

Input format: 

The first line contains two positive integers n and m, which respectively represent the number of caves and the number of commands that have appeared on the terminal. The following m lines represent each command appearing on the terminal in turn. Each line begins with a string s ("Connect", "Destroy" or "Query", case sensitive) indicating the type of command, followed by two integers u and v (1≤u, v≤n and u≠v ) represent the numbers of the two caves, respectively.

Output format:

For each Query command, output whether the cave u and the cave v are connected to each other: yes, output "Yes", otherwise output "No". (without double quotes)

 

ideas

LCT board, there are many introductions on the Internet

#include <bits/stdc++.h>
using namespace std;
const int maxn = 10000 + 10;
struct Link_Cut_Tree {
    struct Splay { int ch[2],f,mark,sum,w; }t[maxn];
    inline bool getfa(int x) { return t[t[x].f].ch[1] == x; }
    inline bool isroot(int x) { return t[t[x].f].ch[0] != x && t[t[x].f].ch[1] != x; }
    inline void pushup(int x) { t[x].sum = t[t[x].ch[0]].sum^t[t[x].ch[1]].sum^t[x].w; }
    inline void rev(int x) { t[x].mark ^= 1; swap(t[x].ch[0],t[x].ch[1]); }
    inline void pushdown(int x) {
        if (t[x].mark) {
            if (t[x].ch[0]) rev(t[x].ch[0]);
            if (t[x].ch[1]) rev(t[x].ch[1]);
            t[x].mark = 0;
        }
    }
    inline void rotate(int x) {
        int f = t[x].f,g = t[f].f,c = getfa(x);
        if (!isroot(f)) t[g].ch[getfa(f)]=x; t[x].f = g;
        t[f].ch[c] = t[x].ch[c^1]; t[t[f].ch[c]].f = f;
        t[x].ch[c^1] = f; t[f].f = x;
        pushup(f); pushup(x);
    }
    inline void check(int x) { if (!isroot(x)) check(t[x].f); pushdown(x); }
    inline void splay(int x) {
        check(x);
        for (;!isroot(x);rotate(x))
            if (!isroot(t[x].f)) rotate(getfa(t[x].f) == getfa(x) ? t[x].f : x);
    }
    inline void access(int x) { for (int y = 0;x;y = x,x = t[x].f) splay(x),t[x].ch[1] = y,pushup(x); }
    inline void makeroot(int x) { access(x); splay(x); rev(x); }
    inline int findroot(int x) {
        access(x); splay(x);
        while (t[x].ch[0]) pushdown(x),x = t[x].ch[0];
        return x;
    }
    inline void link(int x,int y) { makeroot(x),t[x].f = y; }
    inline void cut(int x,int y) { makeroot(x); access(y); splay(y); if (t[y].ch[0] == x && t[x].ch[1] == 0) t[x].f = t[y].ch[0] = 0; }
    inline void split(int x,int y) { makeroot(x); access(y); splay(y); }
}lct;
int n,q;
int main() {
    scanf("%d%d",&n,&q);
    while (q--) {
        string op;
        int x,y;
        cin >> op >> x >> y;
        if (op == "Connect") lct.link(x,y);
        if (op == "Destroy") lct.cut(x,y);
        if (op == "Query") printf("%s\n",lct.findroot(x) == lct.findroot(y) ? "Yes" : "No");
    }
    return 0;
}

---End of recovery content---

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325113975&siteId=291194637