QOJ.ac

QOJ

IDSubmission IDProblemHackerOwnerResultSubmit timeJudge time
#721#127762#6501. Graph Partitioningegypt_ioi2024_12nhuang685Failed.2024-07-04 04:55:302024-07-04 04:55:30

Details

Extra Test:

Accepted
time: 0ms
memory: 3840kb

input:

5
1 2
1 2
1 2
1 2
1 2
1 2
1 2
1 2

output:

0

result:

ok 1 number(s): "0"

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#127762#6501. Graph Partitioningnhuang685AC ✓347ms59424kbC++204.5kb2023-07-20 02:33:252024-07-16 01:40:52

answer

/**
 * @file qoj6501F1.cpp
 * @author n685
 * @brief
 * @date 2023-07-19
 *
 *
 */
#include <bits/stdc++.h>

#ifdef LOCAL
std::ifstream cin;
std::ofstream cout;
using std::cerr;
#else
using std::cin;
using std::cout;
#define cerr                                                                   \
  if (false)                                                                   \
  std::cerr
#endif

std::pair<int64_t, int64_t> exEucl(int64_t a, int64_t b) {
  if (a < b) {
    auto [x, y] = exEucl(b, a);
    return {y, x};
  }
  if (b == 0) {
    assert(a == 1);
    return {1, 0};
  }
  auto [x, y] = exEucl(b, a % b);
  return {y, x - (a / b) * y};
}

template <class Md> class Mod {
private:
  using T = typename std::decay<decltype(Md::value)>::type;
  T val = 0;

public:
  template <class U> static T normalize(U val) {
    if (val <= -Md::value || Md::value <= val)
      val %= Md::value;
    if (val < 0)
      val += Md::value;
    return static_cast<T>(val);
  }

  Mod() : val(0) {}
  template <class U> Mod(U _val) { val = normalize(_val); }

  // addition
  Mod &operator+=(Mod b) {
    val += b.val;
    if (val >= Md::value)
      val -= Md::value;
    return *this;
  }
  friend Mod operator+(Mod a, Mod b) { return (a += b); }
  Mod &operator++() { return (*this += 1); }
  Mod operator++(int) {
    Mod res = *this;
    ++(*this);
    return res;
  }

  // subtraction
  Mod &operator-=(Mod b) {
    val -= b.val;
    if (val < 0)
      val += Md::value;
    return *this;
  }
  friend Mod operator-(Mod a, Mod b) { return (a -= b); }
  Mod &operator--() { return (*this -= 1); }
  Mod operator--(int) {
    Mod res = *this;
    --(*this);
    return res;
  }

  // multiplication
  Mod &operator*=(Mod b) {
    val = static_cast<T>(static_cast<int64_t>(val) * b.val % Md::value);
    return *this;
  }
  friend Mod operator*(Mod a, Mod b) { return (a *= b); }

  // division
  template <class U> Mod binpow(U b) const {
    // assumes Mod(0).binpow(0) == 1
    Mod res = 1, a = *this;
    while (b > 0) {
      if (b % 2 == 1)
        res *= a;
      a *= a;
      b /= 2;
    }
    return res;
  }
  Mod inv() const {
    return Mod(
        exEucl(static_cast<int64_t>(val), static_cast<int64_t>(Md::value))
            .first);
  }
  Mod operator/=(Mod b) { return (*this *= b.inv()); }
  friend Mod operator/(Mod a, Mod b) { return (a /= b); }

  // comparison
  bool operator==(Mod b) const { return (val == b.val); }
  // strong_ordering operator<=>(Mod b) { return (val <=> b.val); }
  bool operator!=(Mod b) const { return (val != b.val); }
  bool operator<(Mod b) const { return (val < b.val); }
  bool operator>(Mod b) const { return (val > b.val); }
  bool operator<=(Mod b) const { return (val <= b.val); }
  bool operator>=(Mod b) const { return (val >= b.val); }

  // io
  friend std::istream &operator>>(std::istream &in, Mod &a) {
    int64_t val;
    cin >> val;
    a = Mod(val);
    return in;
  }
  friend std::ostream &operator<<(std::ostream &out, const Mod &a) {
    out << a.val;
    return out;
  }

  // conversion
  explicit operator T() const { return val; }
  const T &operator()() const { return val; }
  Mod operator-() const { return Mod(-val); }
};

constexpr int MOD = 998244353;
using Mint = Mod<std::integral_constant<std::decay<decltype(MOD)>::type, MOD>>;

int main() {
#ifdef LOCAL
  cin.open("input.txt");
  cout.rdbuf()->pubsetbuf(0, 0);
  cout.open("output.txt");
#else
  cin.tie(nullptr)->sync_with_stdio(false);
#endif

  int n;
  cin >> n;

  std::vector<std::vector<int>> adj(2 * n);
  for (int i = 0; i < 2 * n - 2; ++i) {
    int u, v;
    cin >> u >> v;
    u--, v--;
    if (u == v) {
      cout << "0\n";
      return 0;
    }
    if (u > v)
      std::swap(u, v);

    adj[u].push_back(v + n);
    adj[v + n].push_back(u);
  }

  std::vector<bool> v(2 * n);
  auto dfs = [&](auto &self, int node) -> std::pair<int, int> {
    v[node] = true;
    std::pair<int, int> num{(int)adj[node].size(), 1};
    for (int i : adj[node]) {
      if (v[i])
        continue;
      auto [a, b] = self(self, i);
      num.first += a;
      num.second += b;
    }
    return num;
  };
  Mint ans = 1;
  for (int i = 0; i < 2 * n; ++i) {
    if (!v[i]) {
      auto [e, sz] = dfs(dfs, i);
      e /= 2;
      if (e != sz) {
        if (e != 0) {
          cout << "0\n";
          return 0;
        }
      } else
        ans *= 2;
    }
  }

  cout << ans << '\n';
}