Problem p03750 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cstdio>
#include <vector>
int N, Q, A[100002], B[100002], C[100002];
int O[100003], L[100003], R[100003], W[100003], M;
std::pair<int, int> S[100002];
int TL[262144], TR[262144], TW[262144], AW[262144];
void build(int *T, int *A, int *a, int p, int l, int r) {
  if (l == r) {
    T[p] = a[l];
    if (A != NULL)
      A[p] = 0;
    return;
  }
  int m = l + r >> 1;
  build(T, A, a, p << 1, l, m);
  build(T, A, a, p << 1 | 1, m + 1, r);
  T[p] = T[p << 1] + T[p << 1 | 1];
  if (A != NULL)
    A[p] = 0;
}
int G(int *T, int *A, int p, int l, int r, int x) {
  int SA = A == NULL ? 0 : A[p];
  while (l < r) {
    int m = l + r >> 1;
    if (x <= m)
      p <<= 1, r = m;
    else
      p = p << 1 | 1, l = m + 1;
    if (A != NULL)
      SA += A[p];
  }
  return T[p] + SA;
}
int LM(int *T, int p, int l, int r) {
  if (!T[p])
    return 0;
  while (l < r) {
    int m = l + r >> 1;
    if (T[p << 1])
      p <<= 1, r = m;
    else
      p = p << 1 | 1, l = m + 1;
  }
  return l;
}
int RM(int *T, int p, int l, int r) {
  if (!T[p])
    return 0;
  while (l < r) {
    int m = l + r >> 1;
    if (T[p << 1 | 1])
      p = p << 1 | 1, l = m + 1;
    else
      p <<= 1, r = m;
  }
  return l;
}
void P(int *A, int p, int l, int r, int L, int R, int w) {
  if (L <= l && r <= R) {
    A[p] += w;
    return;
  }
  int m = l + r >> 1;
  if (L <= m)
    P(A, p << 1, l, m, L, R, w);
  if (R > m)
    P(A, p << 1 | 1, m + 1, r, L, R, w);
}
void P(int *T, int p, int l, int r, int x, int w) {
  T[p] += w;
  while (l < r) {
    int m = l + r >> 1;
    if (x <= m)
      p <<= 1, r = m;
    else
      p = p << 1 | 1, l = m + 1;
    T[p] += w;
  }
}
void AssignExport(int *T, int *A, int p, int l, int r, int SA, int *__w) {
  if (l == r) {
    __w[l] = SA + T[p] + A[p];
    return;
  }
  int m = l + r >> 1;
  AssignExport(T, A, p << 1, l, m, SA + A[p], __w);
  AssignExport(T, A, p << 1 | 1, m + 1, r, SA + A[p], __w);
}
void AssignExport(int *T, int p, int l, int r, int *__w) {
  if (l == r) {
    __w[l] = T[p];
    return;
  }
  int m = l + r >> 1;
  AssignExport(T, p << 1, l, m, __w);
  AssignExport(T, p << 1 | 1, m + 1, r, __w);
}
void NiroBC(int l, int r, int sl, int sr) {
  if (l == r) {
    int have = L[l] + R[l] + sr - sl + 1, need = std::max(0, -W[l] + 1);
    O[l] = have < need ? N + 1 : need;
    return;
  }
  int m = l + r >> 1;
  build(TL, NULL, L, 1, l, r);
  build(TR, NULL, R, 1, l, r);
  build(TW, AW, W, 1, l, r);
  static std::vector<int> ME[100002];
  for (int i = l; i <= r; i++)
    ME[i].clear();
  for (int i = sl; i <= sr; i++)
    ME[S[i].first].push_back(S[i].second);
  int RANS_BASE = 0, LANS_BASE = 0;
  for (int i = l; i <= m; i++) {
    for (int e : ME[i])
      P(TL, 1, l, r, e, 1);
    P(TL, 1, l, r, r, R[i]);
    int need = std::max(0, -G(TW, AW, 1, l, r, i) + 1);
    while (need) {
      int use = RM(TL, 1, l, r);
      if (!use || use < i) {
        for (int j = m + 1; j <= r; j++)
          O[j] = N + 1;
        break;
      }
      P(TL, 1, l, r, use, -1);
      P(AW, 1, l, r, i, use, 1);
      RANS_BASE++;
      need--;
    }
    if (need) {
      RANS_BASE = N + 1;
      break;
    }
  }
  static int __wr[100003], __wl[100003];
  AssignExport(TW, AW, 1, l, r, 0, __wr);
  for (int i = l; i <= r; i++)
    ME[i].clear();
  for (int i = sl; i <= sr; i++)
    ME[S[i].second].push_back(S[i].first);
  build(TW, AW, W, 1, l, r);
  for (int i = r; i > m; i--) {
    for (int e : ME[i])
      P(TR, 1, l, r, e, 1);
    P(TR, 1, l, r, l, L[i]);
    int need = std::max(0, -G(TW, AW, 1, l, r, i));
    while (need) {
      int use = LM(TR, 1, l, r);
      if (!use || use > i) {
        for (int j = l; j <= m; j++)
          O[j] = N + 1;
        break;
      }
      P(TR, 1, l, r, use, -1);
      P(AW, 1, l, r, use, i, 1);
      LANS_BASE++;
      need--;
    }
    if (need) {
      LANS_BASE = N + 1;
      break;
    }
  }
  AssignExport(TW, AW, 1, l, r, 0, __wl);
  std::copy(__wl + l, __wl + m + 1, W + l);
  std::copy(__wr + m + 1, __wr + r + 1, W + m + 1);
  AssignExport(TL, 3, m + 1, r, L);
  AssignExport(TR, 2, l, m, R);
  static std::pair<int, int> __S[100003];
  int cl = sl - 1, cr = sr + 1;
  for (int i = sl; i <= sr; i++)
    if (S[i].second <= m)
      __S[++cl] = S[i];
  for (int i = sr; i >= sl; i--)
    if (S[i].first > m)
      __S[--cr] = S[i];
  std::copy(__S + sl, __S + cl + 1, S + sl);
  std::copy(__S + cr, __S + sr + 1, S + cr);
  if (LANS_BASE != N + 1) {
    NiroBC(l, m, sl, cl);
    for (int i = l; i <= m; i++)
      O[i] += LANS_BASE;
  }
  if (RANS_BASE != N + 1) {
    NiroBC(m + 1, r, cr, sr);
    for (int i = m + 1; i <= r; i++)
      O[i] += RANS_BASE;
  }
}
int main() {
  scanf("%d", &N);
  N++;
  for (int i = 1; i < N; i++)
    scanf("%d%d", A + i, B + i);
  for (int i = 1; i <= N; i++)
    scanf("%d", C + i);
  std::sort(C + 1, C + N + 1);
  for (int i = 1; i < N; i++) {
    A[i] = std::lower_bound(C + 1, C + N + 1, A[i]) - C;
    B[i] = std::lower_bound(C + 1, C + N + 1, B[i]) - C;
    W[A[i]]++;
    if (A[i] > B[i])
      S[++M] = {B[i] + 1, A[i]};
  }
  for (int i = N; i; i--)
    W[i] += W[i + 1];
  for (int i = 1; i <= N + 1; i++)
    W[i] = N + 1 - i - W[i];
  NiroBC(1, N + 1, 1, M);
  for (int i = 1; i <= N + 1; i++)
    O[i] = std::min(O[i], N + 1);
  for (scanf("%d", &Q); Q--;) {
    int D, E;
    scanf("%d%d", &D, &E);
    D = std::lower_bound(C + 1, C + N + 1, D) - C;
    E = std::lower_bound(C + 1, C + N + 1, E) - C;
    printf("%d\n", N - std::min(O[D], O[E] + 1));
  }
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cstdio>
#include <vector>
int N, Q, A[100002], B[100002], C[100002];
int O[100003], L[100003], R[100003], W[100003], M;
std::pair<int, int> S[100002];
int TL[262144], TR[262144], TW[262144], AW[262144];
void build(int *T, int *A, int *a, int p, int l, int r) {
  if (l == r) {
    T[p] = a[l];
    if (A != NULL)
      A[p] = 0;
    return;
  }
  int m = l + r >> 1;
  build(T, A, a, p << 1, l, m);
  build(T, A, a, p << 1 | 1, m + 1, r);
  T[p] = T[p << 1] + T[p << 1 | 1];
  if (A != NULL)
    A[p] = 0;
}
int G(int *T, int *A, int p, int l, int r, int x) {
  int SA = A == NULL ? 0 : A[p];
  while (l < r) {
    int m = l + r >> 1;
    if (x <= m)
      p <<= 1, r = m;
    else
      p = p << 1 | 1, l = m + 1;
    if (A != NULL)
      SA += A[p];
  }
  return T[p] + SA;
}
int LM(int *T, int p, int l, int r) {
  if (!T[p])
    return 0;
  while (l < r) {
    int m = l + r >> 1;
    if (T[p << 1])
      p <<= 1, r = m;
    else
      p = p << 1 | 1, l = m + 1;
  }
  return l;
}
int RM(int *T, int p, int l, int r) {
  if (!T[p])
    return 0;
  while (l < r) {
    int m = l + r >> 1;
    if (T[p << 1 | 1])
      p = p << 1 | 1, l = m + 1;
    else
      p <<= 1, r = m;
  }
  return l;
}
void P(int *A, int p, int l, int r, int L, int R, int w) {
  if (L <= l && r <= R) {
    A[p] += w;
    return;
  }
  int m = l + r >> 1;
  if (L <= m)
    P(A, p << 1, l, m, L, R, w);
  if (R > m)
    P(A, p << 1 | 1, m + 1, r, L, R, w);
}
void P(int *T, int p, int l, int r, int x, int w) {
  T[p] += w;
  while (l < r) {
    int m = l + r >> 1;
    if (x <= m)
      p <<= 1, r = m;
    else
      p = p << 1 | 1, l = m + 1;
    T[p] += w;
  }
}
void AssignExport(int *T, int *A, int p, int l, int r, int SA, int *__w) {
  if (l == r) {
    __w[l] = SA + T[p] + A[p];
    return;
  }
  int m = l + r >> 1;
  AssignExport(T, A, p << 1, l, m, SA + A[p], __w);
  AssignExport(T, A, p << 1 | 1, m + 1, r, SA + A[p], __w);
}
void AssignExport(int *T, int p, int l, int r, int *__w) {
  if (l == r) {
    __w[l] = T[p];
    return;
  }
  int m = l + r >> 1;
  AssignExport(T, p << 1, l, m, __w);
  AssignExport(T, p << 1 | 1, m + 1, r, __w);
}
void NiroBC(int l, int r, int sl, int sr) {
  if (l == r) {
    int have = L[l] + R[l] + sr - sl + 1, need = std::max(0, -W[l] + 1);
    O[l] = have < need ? N + 1 : need;
    return;
  }
  int m = l + r >> 1;
  build(TL, NULL, L, 1, l, r);
  build(TR, NULL, R, 1, l, r);
  build(TW, AW, W, 1, l, r);
  static std::vector<int> ME[100003];
  for (int i = l; i <= r; i++)
    ME[i].clear();
  for (int i = sl; i <= sr; i++)
    ME[S[i].first].push_back(S[i].second);
  int RANS_BASE = 0, LANS_BASE = 0;
  for (int i = l; i <= m; i++) {
    for (int e : ME[i])
      P(TL, 1, l, r, e, 1);
    P(TL, 1, l, r, r, R[i]);
    int need = std::max(0, -G(TW, AW, 1, l, r, i) + 1);
    while (need) {
      int use = RM(TL, 1, l, r);
      if (!use || use < i) {
        for (int j = m + 1; j <= r; j++)
          O[j] = N + 1;
        break;
      }
      P(TL, 1, l, r, use, -1);
      P(AW, 1, l, r, i, use, 1);
      RANS_BASE++;
      need--;
    }
    if (need) {
      RANS_BASE = N + 1;
      break;
    }
  }
  static int __wr[100003], __wl[100003];
  AssignExport(TW, AW, 1, l, r, 0, __wr);
  for (int i = l; i <= r; i++)
    ME[i].clear();
  for (int i = sl; i <= sr; i++)
    ME[S[i].second].push_back(S[i].first);
  build(TW, AW, W, 1, l, r);
  for (int i = r; i > m; i--) {
    for (int e : ME[i])
      P(TR, 1, l, r, e, 1);
    P(TR, 1, l, r, l, L[i]);
    int need = std::max(0, -G(TW, AW, 1, l, r, i));
    while (need) {
      int use = LM(TR, 1, l, r);
      if (!use || use > i) {
        for (int j = l; j <= m; j++)
          O[j] = N + 1;
        break;
      }
      P(TR, 1, l, r, use, -1);
      P(AW, 1, l, r, use, i, 1);
      LANS_BASE++;
      need--;
    }
    if (need) {
      LANS_BASE = N + 1;
      break;
    }
  }
  AssignExport(TW, AW, 1, l, r, 0, __wl);
  std::copy(__wl + l, __wl + m + 1, W + l);
  std::copy(__wr + m + 1, __wr + r + 1, W + m + 1);
  AssignExport(TL, 3, m + 1, r, L);
  AssignExport(TR, 2, l, m, R);
  static std::pair<int, int> __S[100003];
  int cl = sl - 1, cr = sr + 1;
  for (int i = sl; i <= sr; i++)
    if (S[i].second <= m)
      __S[++cl] = S[i];
  for (int i = sr; i >= sl; i--)
    if (S[i].first > m)
      __S[--cr] = S[i];
  std::copy(__S + sl, __S + cl + 1, S + sl);
  std::copy(__S + cr, __S + sr + 1, S + cr);
  if (LANS_BASE != N + 1) {
    NiroBC(l, m, sl, cl);
    for (int i = l; i <= m; i++)
      O[i] += LANS_BASE;
  }
  if (RANS_BASE != N + 1) {
    NiroBC(m + 1, r, cr, sr);
    for (int i = m + 1; i <= r; i++)
      O[i] += RANS_BASE;
  }
}
int main() {
  scanf("%d", &N);
  N++;
  for (int i = 1; i < N; i++)
    scanf("%d%d", A + i, B + i);
  for (int i = 1; i <= N; i++)
    scanf("%d", C + i);
  std::sort(C + 1, C + N + 1);
  for (int i = 1; i < N; i++) {
    A[i] = std::lower_bound(C + 1, C + N + 1, A[i]) - C;
    B[i] = std::lower_bound(C + 1, C + N + 1, B[i]) - C;
    W[A[i]]++;
    if (A[i] > B[i])
      S[++M] = {B[i] + 1, A[i]};
  }
  for (int i = N; i; i--)
    W[i] += W[i + 1];
  for (int i = 1; i <= N + 1; i++)
    W[i] = N + 1 - i - W[i];
  NiroBC(1, N + 1, 1, M);
  for (int i = 1; i <= N + 1; i++)
    O[i] = std::min(O[i], N + 1);
  for (scanf("%d", &Q); Q--;) {
    int D, E;
    scanf("%d%d", &D, &E);
    D = std::lower_bound(C + 1, C + N + 1, D) - C;
    E = std::lower_bound(C + 1, C + N + 1, E) - C;
    printf("%d\n", N - std::min(O[D], O[E] + 1));
  }
  return 0;
}