Description
Huihui is keen on cave exploration. One day, he followed the map to a Cave Cluster marked JSZX. After preliminary investigation, Huihui found that this area consists of N caves (numbered 1 to n) and several channels, and each channel connects exactly two caves. If two caves can be connected by one or more channels in a certain order, then the two caves are connected, and the channels connected in a sequence are called a path between the two caves. Caves are very strong and can not be destroyed, but the passageway is not stable, often because of external influences and changes. For example, according to the monitoring results of relevant instruments, there is sometimes a passageway between Cave 123 and Cave 127, and sometimes this passageway will be destroyed for some strange reason. Huihui has a monitoring instrument which can display every change of the channel on the terminal at Huihui's hand in real time. If a channel appears between the cave u and the cave v, an instruction will be displayed on the terminal. If Connect u v monitors that the channel between cave u and cave v is destroyed, a command Destroy u v is displayed on the terminal. After a long and arduous manual calculation, Huihui finds a strange phenomenon: no matter how the channel 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 insists on the terminal day and night, trying to study this essential law through the change of channel. One day, however, Huihui collapsed in a mountain of calculating paper... He smashed the terminal to the ground (it was strong enough not to be destroyed), turned to you and said, "Your brother, write this program." Huihui hopes to send instructions through the terminal at any time. Query u v, ask the monitor if the cave u and V are connected at this time. Now you're going to write a program for him to answer every inquiry. It is known that no channel existed in the JSZX cave group before the first instruction was displayed.
Input
The first two positive integers, N and m, represent the number of caves and the number of instructions on the terminal. The following M lines represent the instructions that appear on the terminal in turn. Each line begins with a string s ("Connect", "Destroy" or "Query", case-sensitive) indicating the type of instruction, followed by two integers u and v (1 < u, v < n and u v) indicating the number of the two caves, respectively.
Output
For each Query instruction, whether output cave u and cave v are interconnected: output "Yes" or output "No". (without double quotation marks)
Sample Input
200 5
Query 123 127
Connect 123 127
Query 123 127
Destroy 127 123
Query 123 127
Sample input 2 cave.in
3 5
Connect 1 2
Connect 3 1
Query 2 3
Destroy 1 3
Query 2 3
Sample Output
No
Yes
No
Sample output 2 cave.out
Yes
No
HINT
Data show that 10% of the data satisfy n < 1000, m < 20000 20% satisfy n < 2000, m < 40000 30% satisfy n < 3000, m < 60000 40% satisfy n < 4000, m < 80000 50% satisfy n < 5000, m < 100000 60% satisfy n < 6000, m < 120000 70% satisfy n < 7000, m < 140000 80% satisfy n < 8000, m < 160000 80% satisfy. 90% of the data satisfy n < 9000, m < 180000 100% of the data satisfy n < 10000, m < 200000 to ensure that all Destroy instructions will destroy an existing channel. The input and output scale of this topic is relatively large. It is suggested that c c++ players use scanf and printf to perform I O operations to avoid timeouts.
Positive solution: link-cut tree.
Board question.
//It is made by wfj_2048~ #include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <vector> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> #define inf (1<<30) #define il inline #define RG register #define ll long long using namespace std; int ch[10010][2],fa[10010],st[10010],lazy[10010],n,m; char s[10]; il int gi(){ RG int x=0,q=1; RG char ch=getchar(); while ((ch<'0' || ch>'9') && ch!='-') ch=getchar(); if (ch=='-') q=-1,ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x; } il void pushdown(RG int x){ lazy[x]=0,lazy[ch[x][0]]^=1,lazy[ch[x][1]]^=1,swap(ch[x][0],ch[x][1]); return; } il int isroot(RG int x){ return ch[fa[x]][0]!=x && ch[fa[x]][1]!=x; } il void rotate(RG int x){ RG int y=fa[x],z=fa[y],k=(ch[y][0]==x); if (!isroot(y)) ch[z][ch[z][1]==y]=x; fa[x]=z,fa[ch[x][k]]=y,ch[y][k^1]=ch[x][k]; fa[y]=x,ch[x][k]=y; return; } il void splay(RG int x){ RG int top=0; st[++top]=x; for (RG int i=x;!isroot(i);i=fa[i]) st[++top]=fa[i]; for (RG int i=top;i;--i) if (lazy[st[i]]) pushdown(st[i]); while (!isroot(x)){ RG int y=fa[x],z=fa[y]; if (!isroot(y)){ if ((ch[y][0]==x)^(ch[z][0]==y)) rotate(x); else rotate(y); } rotate(x); } return; } il void access(RG int x){ RG int t=0; while (x) splay(x),ch[x][1]=t,t=x,x=fa[x]; return; } il void makeroot(RG int x){ access(x),splay(x),lazy[x]^=1; return; } il void link(RG int x,RG int y){ makeroot(x),fa[x]=y; return; } il void cut(RG int x,RG int y){ makeroot(x),access(y),splay(y),ch[y][0]=fa[x]=0; return; } il int find(RG int x){ access(x),splay(x); while (ch[x][0]) x=ch[x][0]; return x; } il void work(){ n=gi(),m=gi(); RG int u,v; for (RG int i=1;i<=m;++i){ scanf("%s",s); u=gi(),v=gi(); if (s[0]=='C') link(u,v); if (s[0]=='D') cut(u,v); if (s[0]=='Q') printf("%s\n",(find(u)==find(v)) ? "Yes" : "No"); } return; } int main(){ work(); return 0; }