Pagini recente » Cod sursa (job #1810268) | Cod sursa (job #2872394) | Cod sursa (job #2886329) | Cod sursa (job #2900357) | Cod sursa (job #2657783)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
class SplayTree {
public:
struct Node {
Node *parent = nullptr;
Node *son[2] = {nullptr, nullptr};
int flip = 0;
int side() const {
if (parent->son[0] == this)
return 0;
return 1;
}
bool root() const {
return parent == nullptr || (this != parent->son[0] && this != parent->son[1]);
}
};
static Node* push(Node *x) {
if (!x || !x->flip)
return x;
swap(x->son[0], x->son[1]);
for (int i = 0; i < 2; ++i)
if (x->son[i])
x->son[i]->flip^= 1;
x->flip = 0;
return x;
}
static void splay(Node *x) {
while (!x->root()) {
Node *p = x->parent;
Node *g = p->parent;
if (p->root())
g = nullptr;
push(g);
push(p);
push(x);
if (!g) {
rotate(p, x->side());
}
else {
int sx = x->side();
int sp = p->side();
if (sx == sp) {
rotate(g, sp);
rotate(p, sx);
} else {
rotate(p, sx);
rotate(g, sp);
}
}
}
}
static void rotate(Node *p, int side) {
Node *g = p->parent;
Node *x = p->son[side];
Node *y = x->son[side ^ 1];
p->son[side] = y;
x->son[side ^ 1] = p;
if (!p->root()) {
g->son[p->side()] = x;
}
if (y)
y->parent = p;
p->parent = x;
x->parent = g;
}
static Node* first(Node *x) {
while (push(x)->son[0])
x = x->son[0];
splay(x);
return x;
}
};
class LinkCutTree {
public:
LinkCutTree(int size): m_node(size) {}
bool connected(int x, int y) {
Node *xx = SplayTree::first(access(&m_node[x]));
Node *yy = SplayTree::first(access(&m_node[y]));
return xx == yy;
}
void link(int x, int y) {
Node *xx = access(&m_node[x]);
Node *yy = make_root(&m_node[y]);
yy->parent = xx;
}
void delink(int x, int y) {
Node *xx = make_root(&m_node[x]);
Node *yy = access(&m_node[y]);
access(xx);
yy->parent = nullptr;
}
private:
using Node = SplayTree::Node;
void cut(Node *x) {
SplayTree::push(x);
Node *y = x->son[1];
if (!y)
return;
x->son[1] = nullptr;
}
Node* access(Node *x) {
SplayTree::splay(x);
cut(x);
while (x->parent) {
Node *up = x->parent;
SplayTree::splay(up);
cut(up);
up->son[1] = x;
SplayTree::splay(x);
}
return x;
}
Node* make_root(Node *x) {
access(x);
x->flip ^= 1;
cut(x);
return x;
}
vector<SplayTree::Node> m_node;
};
int main() {
ios::sync_with_stdio(false);
ifstream cin("disjoint.in");
ofstream cout("disjoint.out");
int N, M; cin >> N >> M;
LinkCutTree T(N);
for (int i = 0; i < M; ++i) {
int op; int x, y;
cin >> op >> x >> y;
--x; --y;
if (op == 2) {
if (T.connected(x, y))
cout << "DA\n";
else
cout << "NU\n";
} else {
T.link(x, y);
}
}
}