Problem p03504 (C++)

Buggy submission (status: Runtime Error):
typedef long long ll;
#include <bits/stdc++.h>

using namespace std;

template <typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val) {
  std::fill((T *)array, (T *)(array + N), val);
}
ll n, c;

priority_queue<pair<ll, ll>, vector<pair<ll, ll>>, greater<pair<ll, ll>>> q;
struct p {
  ll s, t, c;
};

p ps[100010];
ll pro[35][100010];

bool comp(const p x, const p y) { return x.s < y.s; }

int main() {
  cin >> n >> c;
  Fill(pro, -1);
  for (int i = 0; i < n; i++) {
    cin >> ps[i].s >> ps[i].t >> ps[i].c;

    if (pro[ps[i].c][ps[i].s] == -1 && pro[ps[i].c][ps[i].t] == -1) {
      // 空なら更新
      pro[ps[i].c][ps[i].s] = i;
      pro[ps[i].c][ps[i].t] = i;
    } else if (pro[ps[i].c][ps[i].t] != -1 && pro[ps[i].c][ps[i].s] == -1) {
      // 新しい方の終わりの方がからでなければ、以前の方の開始を伸ばして合体
      ps[pro[ps[i].c][ps[i].t]].s = ps[i].s;

      // 新しい開始に以前の値を入れる。
      pro[ps[i].c][ps[i].s] = pro[ps[i].c][ps[i].t];

      // 新しいやつは影響を与えないように再配置。
      ps[i].s = -2 * i - 2;
      ps[i].t = -2 * i - 1;
    } else if (pro[ps[i].c][ps[i].s] != -1 && pro[ps[i].c][ps[i].t] == -1) {
      ps[pro[ps[i].c][ps[i].s]].t = ps[i].t;
      pro[ps[i].c][ps[i].t] = pro[ps[i].c][ps[i].s];

      ps[i].s = -2 * i - 2;
      ps[i].t = -2 * i - 1;
    } else {
      throw invalid_argument("error");
    }
  }
  sort(ps, ps + n, comp);

  q.push({ps[0].t, ps[0].c});
  ll cnt = 1;
  for (int i = 1; i < n; i++) {
    if (q.top().second == ps[i].c || q.top().first < ps[i].s) {
      q.pop();
    } else {
      cnt++;
    }
    q.push({ps[i].t, ps[i].c});
  }
  std::cout << cnt << std::endl;
}


Fixed submission:
typedef long long ll;
#include <bits/stdc++.h>

using namespace std;

template <typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val) {
  std::fill((T *)array, (T *)(array + N), val);
}
ll n, c;

priority_queue<pair<ll, ll>, vector<pair<ll, ll>>, greater<pair<ll, ll>>> q;
struct p {
  ll s, t, c;
};

p ps[100010];
ll pro[35][100010];

bool comp(const p x, const p y) { return x.s < y.s; }

int main() {
  cin >> n >> c;
  Fill(pro, -1);
  for (int i = 0; i < n; i++) {
    cin >> ps[i].s >> ps[i].t >> ps[i].c;

    if (pro[ps[i].c][ps[i].s] == -1 && pro[ps[i].c][ps[i].t] == -1) {
      // 空なら更新
      pro[ps[i].c][ps[i].s] = i;
      pro[ps[i].c][ps[i].t] = i;
    } else if (pro[ps[i].c][ps[i].t] != -1 && pro[ps[i].c][ps[i].s] == -1) {
      // 新しい方の終わりの方がからでなければ、以前の方の開始を伸ばして合体
      ps[pro[ps[i].c][ps[i].t]].s = ps[i].s;

      // 新しい開始に以前の値を入れる。
      pro[ps[i].c][ps[i].s] = pro[ps[i].c][ps[i].t];

      // 新しいやつは影響を与えないように再配置。
      ps[i].s = -2 * i - 2;
      ps[i].t = -2 * i - 1;
    } else if (pro[ps[i].c][ps[i].s] != -1 && pro[ps[i].c][ps[i].t] == -1) {
      ps[pro[ps[i].c][ps[i].s]].t = ps[i].t;
      pro[ps[i].c][ps[i].t] = pro[ps[i].c][ps[i].s];

      ps[i].s = -2 * i - 2;
      ps[i].t = -2 * i - 1;
    } else {
      // stが間に入っている。先頭のやつに吸収させるか
      ll sen = pro[ps[i].c][ps[i].s];
      ll las = pro[ps[i].c][ps[i].t];

      // 先頭のやつの最後を最後にまで伸ばす。
      ps[sen].t = ps[las].t;
      pro[ps[i].c][ps[las].t] = sen;
      // いらんやつを再配置
      ps[i].s = -2 * i - 2;
      ps[i].t = -2 * i - 1;

      // いらんやつを再配置
      ps[las].s = i + (ll)1e7;
      ps[las].t = i + (ll)1e7 + 1;
    }
  }
  sort(ps, ps + n, comp);

  q.push({ps[0].t, ps[0].c});
  ll cnt = 1;
  for (int i = 1; i < n; i++) {
    if (q.top().second == ps[i].c || q.top().first < ps[i].s) {
      q.pop();
    } else {
      cnt++;
    }
    q.push({ps[i].t, ps[i].c});
  }
  std::cout << cnt << std::endl;
}