test

UnionFind（バイナリ入力）





Example

Input




Output
#include <algorithm>
#include <cassert>
#include <cstdio>
#include <iostream>
#include <limits>
#include <random>
#include <utility>
#include <vector>

namespace procon {
class UnionFind {
private:
  struct nodeinfo {
    int par;
    int rank;
    nodeinfo(int par) : par(par), rank(0) {}
  };
  std::vector<nodeinfo> node;

public:
  UnionFind(int n) : node() {
    node.reserve(n);
    for (int i = 0; i < n; ++i) {
      node.push_back(nodeinfo(i));
    }
  }
  int root(int x) {
    if (node[x].par == x) {
      return x;
    }
    return node[x].par = root(node[x].par);
  }
  void unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y) {
      return;
    }
    if (node[x].rank < node[y].rank) {
      node[x].par = y;
    } else {
      node[y].par = x;
      if (node[x].rank == node[y].rank) {
        ++node[x].rank;
      }
    }
  }
  bool is_same_set(int x, int y) { return root(x) == root(y); }
};
}
  
int main(void) {
  int size, n_query;
  std::cin.read((char *)&size, sizeof(int));
  std::cin.read((char *)&n_query, sizeof(int));

  std::vector<uint64_t> query(n_query);
  std::cin.read((char *)query.data(), sizeof(uint64_t) * n_query);

  const int mask = (1 << 30) - 1;

  uint64_t res = 123456789;
  procon::UnionFind uf(size);
  for (uint64_t q : query) {
    const int com = q >> 60;
    const int x = (q >> 30) & mask;
    const int y = (q >> 0) & mask;
    assert(0 <= x && x < size);
    assert(0 <= y && y < size);
    if (com) {
      res = res * 17 + (uf.is_same_set(x, y) ? 1 : 0);
    } else {
      uf.unite(x, y);
    }
  }
  std::cout << res << std::endl;
  return 0;
}

