Problem p01352 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
using namespace std;

typedef pair<int, int> P;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define all(c) (c).begin(), (c).end()
#define uniq(c) c.erase(unique(all(c)), (c).end())
#define index(xs, x) (int)(lower_bound(all(xs), x) - xs.begin())
#define _1 first
#define _2 second
#define pb push_back
#define INF 1145141919
#define MOD 1000000007
// const int B = 200;
const int B = 3;

int N, Q;
int U[40000], R[40000];
int find(int x) {
  if (U[x] == x)
    return x;
  return U[x] = find(U[x]);
}
void unite(int x, int y) {
  x = find(x), y = find(y);
  if (x == y)
    return;
  if (R[x] < R[y])
    swap(x, y);
  U[x] = y;
}

int QT[40000], QU[40000], QV[40000];
bool used[40000];
set<int> G[40000];

void dfs(int x) {
  used[x] = true;
  for (int t : G[x])
    if (!used[t])
      dfs(t);
}

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> N >> Q;
  rep(i, Q) { cin >> QT[i] >> QU[i] >> QV[i]; }
  set<P> edges;
  vector<int> vs;
  vector<P> dyn;
  rep(q, Q) {
    if (q % B == 0) {
      rep(i, N) U[i] = i, R[i] = 1, G[i].clear();
      rep(i, N) used[i] = true;
      vs.clear();
      dyn.clear();
      for (int i = q; i < min(q + B, Q); i++) {
        vs.pb(QU[i]);
        vs.pb(QV[i]);
        dyn.pb(P(QU[i], QV[i]));
      }
      sort(all(vs));
      uniq(vs);
      sort(all(dyn));
      uniq(dyn);
      for (P p : edges)
        if (!binary_search(all(dyn), p))
          unite(p._1, p._2);
      for (P p : edges)
        if (binary_search(all(dyn), p)) {
          int u = find(p._1), v = find(p._2);
          G[u].insert(v);
          G[v].insert(u);
        }
    }
    int u = find(QU[q]), v = find(QV[q]);
    if (QT[q] == 1) {
      edges.insert(P(QU[q], QV[q]));
      G[u].insert(v);
      G[v].insert(u);
    } else if (QT[q] == 2) {
      edges.erase(P(QU[q], QV[q]));
      G[u].erase(v);
      G[v].erase(u);
    } else {
      for (int x : vs)
        used[find(x)] = false;
      dfs(u);
      if (used[v])
        cout << "YES\n";
      else
        cout << "NO\n";
    }
  }
  return 0;
}


Fixed submission:
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
using namespace std;

typedef pair<int, int> P;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define all(c) (c).begin(), (c).end()
#define uniq(c) c.erase(unique(all(c)), (c).end())
#define index(xs, x) (int)(lower_bound(all(xs), x) - xs.begin())
#define _1 first
#define _2 second
#define pb push_back
#define INF 1145141919
#define MOD 1000000007
const int B = 200;

int N, Q;
int U[40000], R[40000];
int find(int x) {
  if (U[x] == x)
    return x;
  return U[x] = find(U[x]);
}
void unite(int x, int y) {
  x = find(x), y = find(y);
  if (x == y)
    return;
  if (R[x] < R[y])
    swap(x, y);
  U[x] = y;
}

int QT[40000], QU[40000], QV[40000];
bool used[40000];
set<int> G[40000];

void dfs(int x) {
  used[x] = true;
  for (int t : G[x])
    if (!used[t])
      dfs(t);
}

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> N >> Q;
  rep(i, Q) { cin >> QT[i] >> QU[i] >> QV[i]; }
  set<P> edges;
  vector<int> vs;
  vector<P> dyn;
  rep(q, Q) {
    if (q % B == 0) {
      rep(i, N) U[i] = i, R[i] = 1, G[i].clear();
      rep(i, N) used[i] = true;
      vs.clear();
      dyn.clear();
      for (int i = q; i < min(q + B, Q); i++) {
        vs.pb(QU[i]);
        vs.pb(QV[i]);
        dyn.pb(P(QU[i], QV[i]));
      }
      sort(all(vs));
      uniq(vs);
      sort(all(dyn));
      uniq(dyn);
      for (P p : edges)
        if (!binary_search(all(dyn), p))
          unite(p._1, p._2);
      for (P p : edges)
        if (binary_search(all(dyn), p)) {
          int u = find(p._1), v = find(p._2);
          G[u].insert(v);
          G[v].insert(u);
        }
    }
    int u = find(QU[q]), v = find(QV[q]);
    if (QT[q] == 1) {
      edges.insert(P(QU[q], QV[q]));
      G[u].insert(v);
      G[v].insert(u);
    } else if (QT[q] == 2) {
      edges.erase(P(QU[q], QV[q]));
      G[u].erase(v);
      G[v].erase(u);
    } else {
      for (int x : vs)
        used[find(x)] = false;
      dfs(u);
      if (used[v])
        cout << "YES\n";
      else
        cout << "NO\n";
    }
  }
  return 0;
}