Cod sursa(job #2689488)

Utilizator retrogradLucian Bicsi retrograd Data 21 decembrie 2020 02:43:00
Problema Paduri de multimi disjuncte Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.45 kb
#include <bits/stdc++.h>

using namespace std;

struct SplayTree {
  struct Node {
    int ch[2] = {0, 0}, p = 0;
  };
  vector<Node> T;

  SplayTree(int n) : T(n + 1) {}

  void splay(int x) {
    auto set = [&](int x, int d, int y) {
      T[x].ch[d] = y; T[y].p = x; 
    };
    auto dir = [&](int x) {
      int p = T[x].p; if (!p) return -1;
      return T[p].ch[0] == x ? 0 : T[p].ch[1] == x ? 1 : -1;
    };
    auto rotate = [&](int x) {
      int y = T[x].p, z = T[y].p, dx = dir(x), dy = dir(y);
      set(y, dx, T[x].ch[!dx]); set(x, !dx, y);
      if (~dy) set(z, dy, x); else T[x].p = z;
    };
    while (~dir(x)) {
      int y = T[x].p, z = T[y].p;
      int dx = dir(x), dy = dir(y);
      if (~dy) rotate(dx != dy ? x : y);
      rotate(x);
    }
  }
};

struct LinkCut : SplayTree {
  LinkCut(int n) : SplayTree(n) {}

  int access(int x) {
    int u = x, v = 0;
    for (; u; v = u, u = T[u].p) {
      splay(u); 
      T[u].ch[1] = v;
    }
    return splay(x), v;
  }
  void Link(int u, int v) {
    access(u); access(v); T[u].p = v;
  }
  int LCA(int u, int v) { 
    if (u == v) return u;
    access(u); int ret = access(v); 
    return T[u].p ? ret : 0;
  }
};

int main() {
  ifstream cin("disjoint.in");
  ofstream cout("disjoint.out");
  int n, m; cin >> n >> m;
  LinkCut lc(n);
  for (int i = 0; i < m; ++i) {
    int t, x, y; cin >> t >> x >> y;
    if (t == 1) lc.Link(x, y); 
    if (t == 2) cout << (lc.LCA(x, y) ? "DA\n" : "NU\n");
  }
  return 0;
}