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

#include <algorithm>
#include <cstdio>
#include <queue>

#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;

const ll INF = 1LL << 61;
const int V_MAX = 100000;

struct edge {
  int v, cost;
};

void pairsort(int n, ll *a, ll *b) {
  static pair<ll, ll> c[V_MAX];
  rep(u, n) c[u] = make_pair(a[u], b[u]);
  sort(c, c + n);
  rep(u, n) a[u] = c[u].first, b[u] = c[u].second;
}

template <class T> class segment_tree {
  static const int N_MAX = 1 << 17;
  int n;
  vector<T> dat[2 * N_MAX];

  int query(int l, int r, int a, int b, int u, ll key) {
    if (l <= a && b <= r)
      return dat[u].end() - lower_bound(dat[u].begin(), dat[u].end(), key);

    int res = 0;
    int c = (a + b + 1) / 2;
    if (l < c && a < r)
      res += query(l, r, a, c, 2 * u, key);
    if (l < b && c < r)
      res += query(l, r, c, b, 2 * u + 1, key);
    return res;
  }

public:
  void build(int N, const T *a) {
    for (n = 1; n < N; n *= 2)
      ;
    rep(u, 2 * n) dat[u].clear();
    rep(i, n) dat[n + i].push_back(a[i]);
    for (int u = n - 1; u >= 1; u--) {
      int l = 2 * u, r = 2 * u + 1;
      dat[u].resize(dat[l].size() + dat[r].size());
      merge(dat[l].begin(), dat[l].end(), dat[r].begin(), dat[r].end(),
            dat[u].begin());
    }
  }

  int query(int l, int r, ll key) { return query(l, r, 0, n, 1, key); }
};

int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  static vector<edge> G[V_MAX];
  rep(i, m) {
    int u, v, cost;
    scanf("%d%d%d", &u, &v, &cost);
    G[u].push_back((edge){v, cost});
    G[v].push_back((edge){u, cost});
  }

  static ll ds[V_MAX], dg[V_MAX]; // d_start, d_goal
  rep(t, 2) {
    ll *d = (t == 0 ? ds : dg);
    int s = (t == 0 ? 0 : n - 1);
    rep(u, n) d[u] = (u == s ? 0 : INF);
    priority_queue<pair<ll, int>> Q;
    Q.push(make_pair(0, s));
    while (!Q.empty()) {
      ll d_now = -Q.top().first;
      int u = Q.top().second;
      Q.pop();

      if (d[u] < d_now)
        continue;

      rep(i, G[u].size()) {
        int v = G[u][i].v, cost = G[u][i].cost;
        if (d[v] > d[u] + cost) {
          d[v] = d[u] + cost;
          Q.push(make_pair(-d[v], v));
        }
      }
    }
  }

  pairsort(n, ds, dg);

  static segment_tree<ll> S;
  S.build(n, dg);

  int q;
  scanf("%d", &q);
  while (q--) {
    ll a, b;
    scanf("%lld%lld", &a, &b);
    int i = upper_bound(ds, ds + n, a) - ds;
    printf("%d\\n", S.query(0, i, b));
  }

  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <queue>

#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;

const ll INF = 1LL << 61;
const int V_MAX = 100000;

struct edge {
  int v;
  ll cost;
};

void pairsort(int n, ll *a, ll *b) {
  static pair<ll, ll> c[V_MAX];
  rep(u, n) c[u] = make_pair(a[u], b[u]);
  sort(c, c + n);
  rep(u, n) a[u] = c[u].first, b[u] = c[u].second;
}

template <class T> class segment_tree {
  static const int N_MAX = 100000;
  int n;
  vector<T> dat[2 * N_MAX];

  int query(int l, int r, int a, int b, int u, ll key) {
    if (l <= a && b <= r)
      return dat[u].end() - lower_bound(dat[u].begin(), dat[u].end(), key);

    int res = 0;
    int c = (a + b + 1) / 2;
    if (l < c && a < r)
      res += query(l, r, a, c, 2 * u, key);
    if (l < b && c < r)
      res += query(l, r, c, b, 2 * u + 1, key);
    return res;
  }

public:
  void build(int N, const T *a) {
    for (n = 1; n < N; n *= 2)
      ;
    rep(u, 2 * n) dat[u].clear();
    rep(i, n) dat[n + i].push_back(a[i]);
    for (int u = n - 1; u >= 1; u--) {
      int l = 2 * u, r = 2 * u + 1;
      dat[u].resize(dat[l].size() + dat[r].size());
      merge(dat[l].begin(), dat[l].end(), dat[r].begin(), dat[r].end(),
            dat[u].begin());
    }
  }

  int query(int l, int r, ll key) { return query(l, r, 0, n, 1, key); }
};

int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  static vector<edge> G[V_MAX];
  rep(i, m) {
    int u, v, cost;
    scanf("%d%d%d", &u, &v, &cost);
    G[u].push_back((edge){v, cost});
    G[v].push_back((edge){u, cost});
  }

  static ll ds[V_MAX], dg[V_MAX]; // d_start, d_goal
  rep(t, 2) {
    ll *d = (t == 0 ? ds : dg);
    int s = (t == 0 ? 0 : n - 1);
    rep(u, n) d[u] = (u == s ? 0 : INF);
    priority_queue<pair<ll, int>> Q;
    Q.push(make_pair(0, s));
    while (!Q.empty()) {
      ll d_now = -Q.top().first;
      int u = Q.top().second;
      Q.pop();

      if (d[u] < d_now)
        continue;

      rep(i, G[u].size()) {
        int v = G[u][i].v, cost = G[u][i].cost;
        if (d[v] > d[u] + cost) {
          d[v] = d[u] + cost;
          Q.push(make_pair(-d[v], v));
        }
      }
    }
  }

  pairsort(n, ds, dg);

  static segment_tree<ll> S;
  S.build(n, dg);

  int q;
  scanf("%d", &q);
  while (q--) {
    ll a, b;
    scanf("%lld%lld", &a, &b);
    int i = upper_bound(ds, ds + n, a) - ds;
    printf("%d\\n", S.query(0, i, b));
  }

  return 0;
}