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

#include <bits/stdc++.h>

using namespace std;

struct UnionFind {
  vector<int> data;

  UnionFind(int sz) : data(sz, -1) {}

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

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

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

int main() {
  int N, C[100000], M;
  vector<int> g[100000];
  vector<pair<int, int>> beet[100000];
  int dp[100000];

  scanf("%d", &N);
  for (int i = 0; i < N; i++) {
    scanf("%d", &C[i]);
  }
  scanf("%d", &M);

  UnionFind tree(N);
  for (int i = 0; i < M; i++) {
    int a, b;
    scanf("%d %d", &a, &b);
    --a, --b;
    if (C[a] > C[b])
      swap(a, b);
    if (C[a] == C[b])
      tree.unite(a, b);
    else
      g[a].push_back(b);
    beet[a].emplace_back(C[b], b);
    beet[b].emplace_back(C[a], a);
  }

  for (int i = 0; i < N; i++) {
    sort(begin(beet[i]), end(beet[i]));
    for (int j = 1; j < beet[i].size(); j++) {
      auto &pv = beet[i][j - 1], cr = beet[i][j];
      if (pv.first == cr.first)
        tree.unite(pv.second, cr.second);
      else
        g[pv.second].push_back(cr.second);
    }
  }

  vector<int> order;
  for (int i = 0; i < N; i++) {
    if (tree.find(i) == i) {
      order.push_back(i);
      dp[i] = 1;
    } else {
      for (int j : g[i])
        g[tree.find(i)].push_back(j);
      copy(begin(g[i]), end(g[i]), back_inserter(g[tree.find(i)]));
      g[i].clear();
    }
  }

  sort(begin(order), end(order), [&](int a, int b) { return (C[a] < C[b]); });

  long long ret = 0;
  for (int idx : order) {
    for (int to : g[idx])
      dp[tree.find(to)] = max(dp[tree.find(to)], dp[idx] + 1);
    ret += 1LL * dp[idx] * tree.size(idx);
  }

  printf("%lld\\n", ret);
}

Error: -11

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

typedef long long int64;
const int64 INF = 1LL << 58;

struct UnionFind {
  vector<int> data;

  UnionFind(int sz) : data(sz, -1) {}

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

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

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

#define int long long

signed main() {
  int N, C[300000], M;
  vector<int> g[300000];
  vector<pair<int, int>> beet[300000];
  int64 dp[300000];

  scanf("%lld", &N);
  for (int i = 0; i < N; i++) {
    scanf("%lld", &C[i]);
  }
  scanf("%lld", &M);

  UnionFind tree(N);
  for (int i = 0; i < M; i++) {
    int a, b;
    scanf("%lld %lld", &a, &b);
    --a, --b;
    if (C[a] > C[b])
      swap(a, b);
    if (C[a] == C[b])
      tree.unite(a, b);
    else
      g[a].push_back(b);
    beet[a].emplace_back(C[b], b);
    beet[b].emplace_back(C[a], a);
  }

  for (int i = 0; i < N; i++) {
    sort(begin(beet[i]), end(beet[i]));
    for (int j = 1; j < beet[i].size(); j++) {
      auto &pv = beet[i][j - 1], cr = beet[i][j];
      if (pv.first == cr.first)
        tree.unite(pv.second, cr.second);
      else
        g[pv.second].push_back(cr.second);
    }
  }

  vector<int> order;
  for (int i = 0; i < N; i++) {
    if (tree.find(i) == i) {
      order.push_back(i);
      dp[i] = 1;
    } else {
      copy(begin(g[i]), end(g[i]), back_inserter(g[tree.find(i)]));
      g[i].clear();
    }
  }

  sort(begin(order), end(order), [&](int a, int b) { return (C[a] < C[b]); });

  int64 ret = 0;
  for (int idx : order) {
    for (int to : g[idx])
      dp[to] = max(dp[to], dp[idx] + 1);
    ret += 1LL * dp[idx] * tree.size(idx);
  }

  printf("%lld\\n", ret);
}