Problem p02108 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>

using namespace std;

#define BEGIN_STACK_EXTEND(size)                                               \\
  void *stack_extend_memory_ = malloc(size);                                   \\
  void *stack_extend_origin_memory_;                                           \\
  char *stack_extend_dummy_memory_ = (char *)alloca(                           \\
      (1 + (int)(((long long)stack_extend_memory_) & 127)) * 16);              \\
  *stack_extend_dummy_memory_ = 0;                                             \\
  asm volatile("mov %%rsp, %%rbx\\nmov %%rax, %%rsp"                            \\
               : "=b"(stack_extend_origin_memory_)                             \\
               : "a"((char *)stack_extend_memory_ + (size)-1024));

#define END_STACK_EXTEND                                                       \\
  asm volatile("mov %%rax, %%rsp" ::"a"(stack_extend_origin_memory_));         \\
  free(stack_extend_memory_);

struct UnionFind {
  vector<int> data;

  UnionFind(int sz) { data.assign(sz, -1); }

  bool unite(int x, int y) {
    x = find(x), y = find(y);
    if (x == y)
      return (false);
    if (data[x] > data[y])
      swap(x, y);
    data[x] += data[y];
    data[y] = x;
    return (true);
  }

  int find(int k) {
    if (data[k] < 0)
      return (k);
    return (data[k] = find(data[k]));
  }

  int size(int k) { return (-data[find(k)]); }
};

struct Bipartite_Graph : UnionFind {
  vector<int> color;
  bool las;

  Bipartite_Graph(int v) : color(v + v, -1), UnionFind(v + v), las(false) {}

  bool bipartite_graph_coloring() {
    for (int i = 0; i < color.size() / 2; i++) {
      int a = find(i);
      int b = find(i + (int)color.size() / 2);
      if (a == b)
        return (las = false);
      if (color[a] < 0)
        color[a] = 0, color[b] = 1;
    }
    return (las = true);
  }

  bool operator[](int k) {
    if (!las)
      return (0);
    return (bool(max(0, color[find(k)])));
  }
};

struct StronglyConnectedComponents {
  vector<vector<int>> gg, rg;
  vector<int> comp, order, used;

  StronglyConnectedComponents(size_t v)
      : gg(v), rg(v), comp(v, -1), used(v, 0) {}

  void add_edge(int x, int y) {
    gg[x].push_back(y);
    rg[y].push_back(x);
  }

  int operator[](int k) { return (comp[k]); }

  void dfs(int idx) {
    if (used[idx])
      return;
    used[idx] = true;
    for (int to : gg[idx])
      dfs(to);
    order.push_back(idx);
  }

  void rdfs(int idx, int cnt) {
    if (comp[idx] != -1)
      return;
    comp[idx] = cnt;
    for (int to : rg[idx])
      rdfs(to, cnt);
  }

  int build() {
    for (int i = 0; i < gg.size(); i++)
      dfs(i);
    reverse(begin(order), end(order));
    int ptr = 0;
    for (int i : order)
      if (comp[i] == -1)
        rdfs(i, ptr), ptr++;
    return (ptr);
  }
};

int dp[200000][5];
vector<Bipartite_Graph> bb;
int SUM[2][200000];
vector<vector<int>> ventex;
int convert[200000];

int rec(int idx, int in, StronglyConnectedComponents &scc) {
  if (~dp[idx][in])
    return (dp[idx][in]);
  int ret = 0;
  for (auto &j : ventex[idx]) {
    for (auto &to : scc.gg[j]) {
      if (scc[to] == idx)
        continue;
      if (bb[idx].las) {
        ret = max(ret,
                  rec(scc[to],
                      bb[scc[to]][convert[to]] ^ bb[idx][convert[j]] ^ in ^ 1,
                      scc));
      } else {
        ret = max(ret, rec(scc[to], in, scc));
        ret = max(ret, rec(scc[to], in ^ 1, scc));
      }
    }
  }
  return (dp[idx][in] = SUM[in][idx] + ret);
}

int main() {
  BEGIN_STACK_EXTEND(128 * 1024 * 1024);

  int N, M, C[200000];

  cin >> N >> M;
  StronglyConnectedComponents scc(N);

  for (int i = 0; i < N; i++) {
    cin >> C[i];
  }
  for (int i = 0; i < M; i++) {
    int a, b;
    cin >> a >> b;
    scc.add_edge(a, b);
  }

  int gg = scc.build();
  ventex.resize(gg);
  for (int i = 0; i < N; i++)
    ventex[scc[i]].push_back(i);
  for (int i = 0; i < ventex.size(); i++) {
    Bipartite_Graph tree(ventex[i].size());

    if (ventex[i].size() > 1) {
      for (int j = 0; j < ventex[i].size(); j++) {
        convert[ventex[i][j]] = j;
      }
      for (auto &j : ventex[i]) {
        for (auto &to : scc.gg[j]) {
          if (scc[to] != i)
            continue;
          tree.unite(convert[j], convert[to] + ventex[i].size());
          tree.unite(convert[j] + ventex[i].size(), convert[to]);
        }
      }
    }
    if (tree.bipartite_graph_coloring()) {
      for (auto &j : ventex[i]) {
        SUM[tree[convert[j]]][i] += C[j];
      }
    } else {
      for (auto &j : ventex[i]) {
        SUM[0][i] += C[j];
        SUM[1][i] += C[j];
      }
    }
    bb.emplace_back(tree);
  }
  memset(dp, -1, sizeof(dp));
  cout << rec(scc[0], bb[scc[0]][convert[0]], scc) << endl;
  END_STACK_EXTEND;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

struct UnionFind {
  vector<int> data;

  UnionFind(int sz) { data.assign(sz, -1); }

  bool unite(int x, int y) {
    x = find(x), y = find(y);
    if (x == y)
      return (false);
    if (data[x] > data[y])
      swap(x, y);
    data[x] += data[y];
    data[y] = x;
    return (true);
  }

  int find(int k) {
    if (data[k] < 0)
      return (k);
    return (data[k] = find(data[k]));
  }

  int size(int k) { return (-data[find(k)]); }
};

struct Bipartite_Graph : UnionFind {
  vector<int> color;
  bool las;

  Bipartite_Graph(int v) : color(v + v, -1), UnionFind(v + v), las(false) {}

  bool bipartite_graph_coloring() {
    for (int i = 0; i < color.size() / 2; i++) {
      int a = find(i);
      int b = find(i + (int)color.size() / 2);
      if (a == b)
        return (las = false);
      if (color[a] < 0)
        color[a] = 0, color[b] = 1;
    }
    return (las = true);
  }

  bool operator[](int k) {
    if (!las)
      return (0);
    return (bool(max(0, color[find(k)])));
  }
};

struct StronglyConnectedComponents {
  vector<vector<int>> gg, rg;
  vector<int> comp, order, used;

  StronglyConnectedComponents(size_t v)
      : gg(v), rg(v), comp(v, -1), used(v, 0) {}

  void add_edge(int x, int y) {
    gg[x].push_back(y);
    rg[y].push_back(x);
  }

  int operator[](int k) { return (comp[k]); }

  void dfs(int idx) {
    if (used[idx])
      return;
    used[idx] = true;
    for (int to : gg[idx])
      dfs(to);
    order.push_back(idx);
  }

  void rdfs(int idx, int cnt) {
    if (comp[idx] != -1)
      return;
    comp[idx] = cnt;
    for (int to : rg[idx])
      rdfs(to, cnt);
  }

  int build() {
    for (int i = 0; i < gg.size(); i++)
      dfs(i);
    reverse(begin(order), end(order));
    int ptr = 0;
    for (int i : order)
      if (comp[i] == -1)
        rdfs(i, ptr), ptr++;
    return (ptr);
  }
};

int dp[200000][5];
vector<Bipartite_Graph> bb;
int SUM[2][200000];
vector<vector<int>> ventex;
int convert[200000];

int rec(int idx, int in, StronglyConnectedComponents &scc) {
  if (~dp[idx][in])
    return (dp[idx][in]);
  int ret = 0;
  for (auto &j : ventex[idx]) {
    for (auto &to : scc.gg[j]) {
      if (scc[to] == idx)
        continue;
      if (bb[idx].las) {
        ret = max(ret,
                  rec(scc[to],
                      bb[scc[to]][convert[to]] ^ bb[idx][convert[j]] ^ in ^ 1,
                      scc));
      } else {
        ret = max(ret, rec(scc[to], in, scc));
        ret = max(ret, rec(scc[to], in ^ 1, scc));
      }
    }
  }
  return (dp[idx][in] = SUM[in][idx] + ret);
}

int main() {
  int N, M, C[200000];

  cin >> N >> M;
  StronglyConnectedComponents scc(N);

  for (int i = 0; i < N; i++) {
    cin >> C[i];
  }
  for (int i = 0; i < M; i++) {
    int a, b;
    cin >> a >> b;
    scc.add_edge(a, b);
  }

  int gg = scc.build();
  ventex.resize(gg);
  for (int i = 0; i < N; i++)
    ventex[scc[i]].push_back(i);
  for (int i = 0; i < ventex.size(); i++) {
    Bipartite_Graph tree(ventex[i].size());

    if (ventex[i].size() > 1) {
      for (int j = 0; j < ventex[i].size(); j++) {
        convert[ventex[i][j]] = j;
      }
      for (auto &j : ventex[i]) {
        for (auto &to : scc.gg[j]) {
          if (scc[to] != i)
            continue;
          tree.unite(convert[j], convert[to] + ventex[i].size());
          tree.unite(convert[j] + ventex[i].size(), convert[to]);
        }
      }
    }
    if (tree.bipartite_graph_coloring()) {
      for (auto &j : ventex[i]) {
        SUM[tree[convert[j]]][i] += C[j];
      }
    } else {
      for (auto &j : ventex[i]) {
        SUM[0][i] += C[j];
        SUM[1][i] += C[j];
      }
    }
    bb.emplace_back(tree);
  }
  memset(dp, -1, sizeof(dp));
  cout << rec(scc[0], bb[scc[0]][convert[0]], scc) << endl;
}