Problem p03058 (C++)

Buggy submission (status: Time Limit Exceeded):
#ifndef LOCAL
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#endif

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <numeric>
#include <set>
#include <string>
#include <vector>
using namespace std;

#ifdef LOCAL
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
#define eprintf(...) 42
#endif

typedef long long int int64;

const int N = 2005;
const int BLOCK = 64;
const int BLM = BLOCK - 1;
const int SZ = N / BLOCK + 1;

int nei[N];
int nsz;

struct BS {
  unsigned long long a[SZ];

  BS() : a() {}

  void doXor(int pos) { a[pos / BLOCK] ^= (1ULL << (pos & BLM)); }

  unsigned long long get(int pos) { return (a[pos / BLOCK] >> (pos & BLM)); }

  void operator|=(const BS &A) {
    for (int i = 0; i < SZ; i++)
      a[i] |= A.a[i];
  }
  void operator&=(const BS &A) {
    for (int i = 0; i < SZ; i++)
      a[i] &= A.a[i];
  }
  void operator*=(const BS &A) // & not
  {
    for (int i = 0; i < SZ; i++)
      a[i] &= ~A.a[i];
  }
  void operator^=(const BS &A) {
    for (int i = 0; i < SZ; i++)
      a[i] ^= A.a[i];
  }

  void copyFrom(const BS &A) {
    for (int i = 0; i < SZ; i++)
      a[i] = A.a[i];
  }

  void getNei() const {
    for (int i = 0; i < SZ; i++) {
      if (a[i] == 0)
        continue;

      for (int j = 0; j < BLOCK; j++)
        if ((a[i] >> j) & 1ULL)
          nei[nsz++] = i * BLOCK + j;
    }
  }

  void clear() { memset(a, 0, sizeof a); }
};

vector<int> t[N];
BS g[N];

BS good[N * N / 2];

int pairId(int x, int y) {
  if (x == y)
    throw;
  if (x < y)
    swap(x, y);
  return x * (x + 1) / 2 + y;
}

BS cur;
BS subTree[N];

void dfsSubtree(int v, int par) {
  subTree[v].clear();
  subTree[v].doXor(v);
  for (int to : t[v]) {
    if (to == par)
      continue;
    dfsSubtree(to, v);
    subTree[v] ^= subTree[to];
  }
}

void dfsCalc(int v, int par, int root) {
  if (v != root)
    good[pairId(v, root)].copyFrom(cur);
  for (int to : t[v]) {
    if (to == par)
      continue;
    if (v != root) {
      cur ^= subTree[v];
      cur.doXor(v);
      cur ^= subTree[to];
    }
    dfsCalc(to, v, root);
    if (v != root)
      cur.copyFrom(good[pairId(v, root)]);
  }
}

int main(int, char **) {
#ifdef LOCAL
  freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
#endif

  int n, m;
  scanf("%d%d", &n, &m);
  for (int i = 0; i < n - 1; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    a--;
    b--;
    t[a].push_back(b);
    t[b].push_back(a);
  }
  for (int i = 0; i < m; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    a--;
    b--;
    g[a].doXor(b);
    g[b].doXor(a);
  }

  for (int i = 0; i < n; i++) {
    cur.clear();
    dfsSubtree(i, i);
    cur.copyFrom(subTree[i]);
    dfsCalc(i, i, i);
  }

  vector<pair<int, int>> qu;

  for (int i = 0; i < n; i++) {
    nsz = 0;
    g[i].getNei();
    for (int j = 0; j < nsz; j++)
      qu.emplace_back(i, nei[j]);
  }

  for (int it = 0; it < (int)qu.size(); it++) {
    int a = qu[it].first, b = qu[it].second;
    if (g[b].get(a) == 0) {
      g[b].doXor(a);
      qu.emplace_back(b, a);
    }

    cur.copyFrom(good[pairId(a, b)]);
    cur &= g[b];
    cur *= g[a];

    nsz = 0;
    cur.getNei();
    for (int i = 0; i < nsz; i++) {
      int v = nei[i];
      if (v == a)
        continue;
      g[a].doXor(v);
      g[v].doXor(a);
      qu.emplace_back(a, v);
      qu.emplace_back(v, a);
    }
  }

  printf("%d\n", (int)qu.size() / 2);

  return 0;
}


Fixed submission:
#ifndef LOCAL
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#endif

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <numeric>
#include <set>
#include <string>
#include <vector>
using namespace std;

#ifdef LOCAL
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
#define eprintf(...) 42
#endif

typedef long long int int64;

const int N = 2005;
const int BLOCK = 64;
const int BLM = BLOCK - 1;
const int SZ = N / BLOCK + 1;

int nei[N];
int nsz;

struct BS {
  unsigned long long a[SZ];

  BS() : a() {}

  void doXor(int pos) { a[pos / BLOCK] ^= (1ULL << (pos & BLM)); }

  unsigned long long get(int pos) { return (a[pos / BLOCK] >> (pos & BLM)); }

  void operator|=(const BS &A) {
    for (int i = 0; i < SZ; i++)
      a[i] |= A.a[i];
  }
  void operator&=(const BS &A) {
    for (int i = 0; i < SZ; i++)
      a[i] &= A.a[i];
  }
  void operator*=(const BS &A) // & not
  {
    for (int i = 0; i < SZ; i++)
      a[i] &= ~A.a[i];
  }
  void operator^=(const BS &A) {
    for (int i = 0; i < SZ; i++)
      a[i] ^= A.a[i];
  }

  void copyFrom(const BS &A) {
    for (int i = 0; i < SZ; i++)
      a[i] = A.a[i];
  }

  void getNei() const {
    for (int i = 0; i < SZ; i++) {
      if (a[i] == 0)
        continue;

      for (int h = 0; h < 8; h++) {
        if (((a[i] >> (h * 8)) & 255) == 0)
          continue;
        for (int j = 8 * h; j < 8 * h + 8; j++)
          if ((a[i] >> j) & 1ULL)
            nei[nsz++] = i * BLOCK + j;
      }
    }
  }

  void clear() { memset(a, 0, sizeof a); }
};

vector<int> t[N];
BS g[N];

BS good[N * N / 2];

int pairId(int x, int y) {
  if (x == y)
    throw;
  if (x < y)
    swap(x, y);
  return x * (x + 1) / 2 + y;
}

BS cur;
BS subTree[N];

void dfsSubtree(int v, int par) {
  subTree[v].clear();
  subTree[v].doXor(v);
  for (int to : t[v]) {
    if (to == par)
      continue;
    dfsSubtree(to, v);
    subTree[v] ^= subTree[to];
  }
}

void dfsCalc(int v, int par, int root) {
  if (v != root)
    good[pairId(v, root)].copyFrom(cur);
  for (int to : t[v]) {
    if (to == par)
      continue;
    if (v != root) {
      cur ^= subTree[v];
      cur.doXor(v);
      cur ^= subTree[to];
    }
    dfsCalc(to, v, root);
    if (v != root)
      cur.copyFrom(good[pairId(v, root)]);
  }
}

int main(int, char **) {
#ifdef LOCAL
  freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
#endif

  int n, m;
  scanf("%d%d", &n, &m);
  for (int i = 0; i < n - 1; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    a--;
    b--;
    t[a].push_back(b);
    t[b].push_back(a);
  }
  for (int i = 0; i < m; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    a--;
    b--;
    g[a].doXor(b);
    g[b].doXor(a);
  }

  for (int i = 0; i < n; i++) {
    cur.clear();
    dfsSubtree(i, i);
    cur.copyFrom(subTree[i]);
    dfsCalc(i, i, i);
  }

  vector<pair<int, int>> qu;

  for (int i = 0; i < n; i++) {
    nsz = 0;
    g[i].getNei();
    for (int j = 0; j < nsz; j++)
      qu.emplace_back(i, nei[j]);
  }

  for (int it = 0; it < (int)qu.size(); it++) {
    int a = qu[it].first, b = qu[it].second;
    if (g[b].get(a) == 0) {
      g[b].doXor(a);
      qu.emplace_back(b, a);
    }

    cur.copyFrom(good[pairId(a, b)]);
    cur &= g[b];
    cur *= g[a];

    nsz = 0;
    cur.getNei();
    for (int i = 0; i < nsz; i++) {
      int v = nei[i];
      if (v == a)
        continue;
      g[a].doXor(v);
      g[v].doXor(a);
      qu.emplace_back(a, v);
      qu.emplace_back(v, a);
    }
  }

  printf("%d\n", (int)qu.size() / 2);

  return 0;
}