アットウィキロゴ

部分永続UnionFind

t回目までのuniteクエリでx,yが同じ連結成分にいるかどうかを求められる
uniteがO(logN)、findがO(logN)
参考ページ

  1. // find:O(logN) unite:O(logN)
  2. class persistentUF {
  3. public:
  4. const static int MAX_N = 100010;
  5. unordered_map<int, int> par[MAX_N];
  6. int rank[MAX_N];
  7. int fin[MAX_N];
  8. int idx;
  9.  
  10. persistentUF() { init(); }
  11. void init() {
  12. idx = 0;
  13. REP(i, MAX_N) par[i][0] = i, rank[i] = 1, fin[i] = 0;
  14. }
  15. persistentUF(int n) { init(n); }
  16. void init(int n) {
  17. idx = 0;
  18. REP(i, n) par[i][0] = i, rank[i] = 1, fin[i] = 0;
  19. }
  20.  
  21. int find(int x, int t) {
  22. if(t >= fin[x] && par[x][fin[x]] != x) return find(par[x][fin[x]], t);
  23. return x;
  24. }
  25.  
  26. void unite(int x, int y) {
  27. x = find(x, idx);
  28. y = find(y, idx);
  29. idx++;
  30. if(x == y) return;
  31. if(rank[x] < rank[y]) par[x][idx] = y, fin[x] = idx;
  32. else {
  33. par[y][idx] = x, fin[y] = idx;
  34. if(rank[x] == rank[y]) rank[x]++;
  35. }
  36. }
  37.  
  38. bool same(int x, int y, int t) { return find(x, t) == find(y, t); }
  39. };
  40. persistentUF uf;
最終更新:2018年02月13日 18:48