Problem p00967 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>
using namespace std;

#define int long long

#define rep(i, n) for (int i = 0; i < (n); i++)
#define pb push_back
#define all(v) (v).begin(), (v).end()
#define fi first
#define se second
typedef vector<int> vint;
typedef pair<int, int> pint;
typedef vector<pint> vpint;

template <typename A, typename B> inline void chmin(A &a, B b) {
  if (a > b)
    a = b;
}
template <typename A, typename B> inline void chmax(A &a, B b) {
  if (a < b)
    a = b;
}

struct UnionFindTree {
  vector<int> par, sz;

  void init() { rep(i, par.size()) par[i] = i, sz[i] = 1; }
  UnionFindTree(int n) {
    par.resize(n);
    sz.resize(n);
    for (int i = 0; i < n; i++) {
      par[i] = i;
      sz[i] = 1;
    }
  }
  int find(int x) { return x == par[x] ? x : par[x] = find(par[x]); }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    if (sz[x] < sz[y])
      swap(x, y);
    sz[x] += sz[y];
    par[y] = x;
  }
  bool areSame(int x, int y) { return find(x) == find(y); }
  int size(int x) { return sz[find(x)]; }
};

int N, M;

int A[111111], B[111111];
vint G[111111];
bool mark[111111];
bool dfs(int v, int p) {
  int cnt = 0;
  for (auto u : G[v]) {
    if (u == p)
      continue;
    cnt += dfs(u, v);
  }

  if (cnt >= 2)
    mark[v] = true;
  return mark[v] || cnt;
}

int n, m;
int id[111111];
int par[111111];
int parEdgeId[111111];
int aa[111111], bb[111111];
int dfs2(int v, int p, int a) {
  if (mark[v]) {
    id[v] = n++;
    par[id[v]] = a;
    if (a != -1) {
      aa[m] = a;
      bb[m] = id[v];
      parEdgeId[id[v]] = m++;
    }
    a = id[v];
  }

  for (auto u : G[v]) {
    if (u == p)
      continue;
    dfs2(u, v, a);
  }
}

typedef bitset<100> mask;

signed main() {
  cin >> N >> M;
  UnionFindTree uf(N);
  vpint es;
  rep(i, M) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;

    A[i] = a;
    B[i] = b;
    if (uf.areSame(a, b)) {
      es.pb({a, b});
      mark[A[i]] = true;
      mark[B[i]] = true;
    } else {
      uf.unite(a, b);
      G[a].pb(b);
      G[b].pb(a);
    }
  }

  dfs(0, -1);
  dfs2(0, -1, -1);

  rep(i, es.size()) {
    es[i].fi = id[es[i].fi];
    es[i].se = id[es[i].se];

    aa[m] = es[i].fi;
    bb[m] = es[i].se;
    m++;
  }

  mask st[20];
  rep(i, es.size()) {
    int a = es[i].fi;
    int b = es[i].se;
    st[i][m - (int)es.size() + i] = 1;

    rep(latte, 2) {
      int v = a;
      while (par[v] != -1) {
        st[i][parEdgeId[v]] = 1 - st[i][parEdgeId[v]];
        v = par[v];
      }
      swap(a, b);
    }
  }

  rep(i, m) if (!(0 <= aa[i] && aa[i] < n) || !(0 <= bb[i] && bb[i] < n)) {
    for (;;)
      ;
  }

  int ans = 0;
  for (int i = 1; i < 1 << es.size(); i++) {
    UnionFindTree uf(n);

    mask x;
    rep(j, es.size()) if (i >> j & 1) x ^= st[j];
    int latte;
    rep(j, m) if (x[j]) uf.unite(aa[j], bb[j]), latte = aa[j];
    if (uf.size(latte) == x.count())
      ans++;
  }
  cout << ans << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

#define int long long

#define rep(i, n) for (int i = 0; i < (n); i++)
#define pb push_back
#define all(v) (v).begin(), (v).end()
#define fi first
#define se second
typedef vector<int> vint;
typedef pair<int, int> pint;
typedef vector<pint> vpint;

template <typename A, typename B> inline void chmin(A &a, B b) {
  if (a > b)
    a = b;
}
template <typename A, typename B> inline void chmax(A &a, B b) {
  if (a < b)
    a = b;
}

struct UnionFindTree {
  vector<int> par, sz;

  void init() { rep(i, par.size()) par[i] = i, sz[i] = 1; }
  UnionFindTree(int n) {
    par.resize(n);
    sz.resize(n);
    for (int i = 0; i < n; i++) {
      par[i] = i;
      sz[i] = 1;
    }
  }
  int find(int x) { return x == par[x] ? x : par[x] = find(par[x]); }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    if (sz[x] < sz[y])
      swap(x, y);
    sz[x] += sz[y];
    par[y] = x;
  }
  bool areSame(int x, int y) { return find(x) == find(y); }
  int size(int x) { return sz[find(x)]; }
};

int N, M;

int A[111111], B[111111];
vint G[111111];
bool mark[111111];
bool dfs(int v, int p) {
  int cnt = 0;
  for (auto u : G[v]) {
    if (u == p)
      continue;
    cnt += dfs(u, v);
  }

  if (cnt >= 2)
    mark[v] = true;
  return mark[v] || cnt;
}

int n, m;
int id[111111];
int par[111111];
int parEdgeId[111111];
int aa[111111], bb[111111];
int dfs2(int v, int p, int a) {
  if (mark[v]) {
    id[v] = n++;
    par[id[v]] = a;
    if (a != -1) {
      aa[m] = a;
      bb[m] = id[v];
      parEdgeId[id[v]] = m++;
    }
    a = v;
  }

  for (auto u : G[v]) {
    if (u == p)
      continue;
    dfs2(u, v, a);
  }
}

typedef bitset<100> mask;

signed main() {
  cin >> N >> M;
  UnionFindTree uf(N);
  vpint es;
  rep(i, M) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;

    A[i] = a;
    B[i] = b;
    if (uf.areSame(a, b)) {
      es.pb({a, b});
      mark[A[i]] = true;
      mark[B[i]] = true;
    } else {
      uf.unite(a, b);
      G[a].pb(b);
      G[b].pb(a);
    }
  }

  dfs(0, -1);
  dfs2(0, -1, -1);

  rep(i, es.size()) {
    es[i].fi = id[es[i].fi];
    es[i].se = id[es[i].se];

    aa[m] = es[i].fi;
    bb[m] = es[i].se;
    m++;
  }

  mask st[20];
  rep(i, es.size()) {
    int a = es[i].fi;
    int b = es[i].se;
    st[i][m - (int)es.size() + i] = 1;

    rep(latte, 2) {
      int v = a;
      while (par[v] != -1) {
        st[i][parEdgeId[v]] = 1 - st[i][parEdgeId[v]];
        v = par[v];
      }
      swap(a, b);
    }
  }

  rep(i, m) if (!(0 <= aa[i] && aa[i] < n) || !(0 <= bb[i] && bb[i] < n)) {
    for (;;)
      ;
  }

  int ans = 0;
  for (int i = 1; i < 1 << es.size(); i++) {
    UnionFindTree uf(n);

    mask x;
    rep(j, es.size()) if (i >> j & 1) x ^= st[j];
    int latte;
    rep(j, m) if (x[j]) uf.unite(aa[j], bb[j]), latte = aa[j];
    if (uf.size(latte) == x.count())
      ans++;
  }
  cout << ans << endl;
  return 0;
}