#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
using namespace std;
#define REP(i, a, b) for (int i = (a), _end_ = (b); i <= _end_; ++i)
#define DREP(i, a, b) for (int i = (a), _begin_ = (b); i >= _begin_; --i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define x first
#define y second
#define pb push_back
#define SZ(x) (int((x).size()))
#define ALL(x) (x).begin(), (x).end()
template<typename T> inline bool chkmin(T &a, const T &b){ return a > b ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a, const T &b){ return a < b ? a = b, 1 : 0; }
typedef long long LL;
const int dmax = 300100, oo = 0x3f3f3f3f;
int N, M;
struct node
{
node *f, *ch[2];
int size, rev;
}c[dmax], *cur, *Null;
#define L ch[0]
#define R ch[1]
inline node *new_node()
{
cur->size = 1;
cur->rev = 0;
cur->f = cur->L = cur->R = Null;
return cur++;
}
inline void init()
{
cur = c + 1;
Null = c;
Null->f = Null->L = Null->R = Null;
Null->size = Null->rev = 0;
}
struct lct
{
inline bool is_root(node *t){ return t == Null || t->f->L != t && t->f->R != t; }
inline void push_up(node *t){ t->size = t->L->size + t->R->size + 1; }
inline void push_down(node *x)
{
if (x->rev)
{
if (x->L != Null) x->L->rev ^= 1;
if (x->R != Null) x->R->rev ^= 1;
x->rev = 0;
swap(x->L, x->R);
}
}
inline void rotate(node *x)
{
if (is_root(x)) return;
node *y = x->f;
if (!is_root(y))
{
if (y == y->f->L)
y->f->L = x;
else y->f->R = x;
}
x->f = y->f;
int T = x == y->R;
y->ch[T] = x->ch[!T];
if (x->ch[!T] != Null) x->ch[!T]->f = y;
x->ch[!T] = y;
y->f = x;
push_up(x);
}
void splay(node *x)
{
static node *S[dmax];
S[0] = x;
int top = 1;
for (node *y = x; !is_root(y); y = y->f)
S[top++] = y->f;
while (top) push_down(S[--top]);
while (!is_root(x))
{
node *y = x->f;
if (is_root(y))
rotate(x);
else{
if (x == y->f->L->L || x == y->f->R->R)
rotate(y);
else rotate(x);
rotate(x);
}
}
}
node *access(node *x)
{
node *y = Null;
while (x != Null)
{
splay(x);
x->R = y;
y->f = x;
push_up(x);
y = x;
x = x->f;
}
return y;
}
inline void change_root(node *x)
{
access(x);
splay(x);
x->rev ^= 1;
}
inline void link(node *x, node *y)
{
change_root(x);
x->f = y;
access(x);
}
inline void cut(node *x)
{
access(x);
splay(x);
x->L = x->L->f = Null;
push_up(x);
}
node *get_root(node *x)
{
access(x);
splay(x);
while (x->L != Null) x = x->L;
splay(x);
return x;
}
bool p(node *x, node *y)
{
while (x->f != Null) x = x->f;
while (y->f != Null) y = y->f;
return x == y;
}
}t;
char s[dmax];
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
init();
scanf("%d%d", &N, &M);
REP(i, 1, N)
new_node();
while (M--)
{
int x, y;
scanf("%s%d%d", s, &x, &y);
if (!strcmp(s, "Query"))
{
if (t.p(c + x, c + y))
puts("Yes");
else puts("No");
} else if (!strcmp(s, "Connect"))
t.link(c + x, c + y);
else {
t.change_root(c + x);
t.cut(c + y);
}
}
return 0;
}
BZOJ2049 洞穴勘测 LCT
最新推荐文章于 2019-04-13 16:38:00 发布