Problem p02599 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define ll long long
#define scn(n) scanf("%d", &n)
#define lscn(n) scanf("%lld", &n)
#define lpri(n) printf("%lld", n)
#define pri(n) printf("%d", n)
#define pln() printf("\n")
#define priln(n) printf("%d\n", n)
#define lpriln(n) printf("%lld\n", n)
#define rep(i, init, n) for (int i = init; i < n; i++)
#define pb push_back
#define mp make_pair
#define F first
#define S second
#define gcd __gcd
#define inf INT_MAX
#define ninf INT_MIN
using namespace std;
const ll mod = 1e9 + 7;
const int N = 1e5 + 4;

struct util {
  int sum, mx;
};

util tree[4 * N];

int arr[N];

void build(int node, int st, int end) {
  if (st == end) {
    tree[node].sum = 0;

    tree[node].mx = arr[st];

    return;
  }

  int mid = (st + end) / 2;

  build(2 * node, st, mid);

  build(2 * node + 1, mid + 1, end);

  tree[node].mx = max(tree[2 * node].mx, tree[2 * node + 1].mx);
}

void update(int node, int st, int end, int ind, int val) {
  if (st == end) {
    tree[node].sum += val;

    return;
  }

  int mid = (st + end) / 2;

  if (ind <= mid)
    update(2 * node, st, mid, ind, val);
  else
    update(2 * node + 1, mid + 1, end, ind, val);

  tree[node].sum = tree[2 * node].sum + tree[2 * node + 1].sum;
}

util query(int node, int st, int end, int l, int r) {
  if (st > r or end < l) {
    util aux;

    aux.sum = aux.mx = 0;

    return aux;
  }

  if (st >= l and end <= r)
    return tree[node];

  int mid = (st + end) / 2;

  util a, b, here;

  a = query(2 * node, st, mid, l, r);

  b = query(2 * node + 1, mid + 1, end, l, r);

  here.sum = a.sum + b.sum;

  here.mx = max(a.mx, b.mx);

  return here;
}

int main() {
  int n, q;

  scn(n);
  scn(q);

  rep(i, 0, n) scn(arr[i]);

  build(1, 0, n - 1);

  vector<pair<int, int>> v[n];

  int ans[q];

  int prev[N]; // last[x] denotes the previous index in which x was present

  memset(prev, -1, sizeof(prev));

  rep(i, 0, q) {
    int l, r;

    scn(l);
    scn(r);

    l--;
    r--;

    // cout<<l<<" "<<r<<" "<<i<<endl;

    v[r].emplace_back(l, i);
  }

  rep(i, 0, n) {
    int here = arr[i];

    if (prev[here] != -1)
      update(1, 0, n - 1, prev[here], -1);

    update(1, 0, n - 1, i, 1);

    prev[here] = i;

    for (auto it : v[i]) {
      int hr = i, hl = it.F, hind = it.S;

      // cout<<hl<<" "<<hr<<" "<<hind<<endl;

      util temp = query(1, 0, n - 1, hl, hr);

      ans[hind] = temp.sum;
    }
  }

  rep(i, 0, q) priln(ans[i]);
}

Fixed submission:
#include <bits/stdc++.h>
#define ll long long
#define scn(n) scanf("%d", &n)
#define lscn(n) scanf("%lld", &n)
#define lpri(n) printf("%lld", n)
#define pri(n) printf("%d", n)
#define pln() printf("\n")
#define priln(n) printf("%d\n", n)
#define lpriln(n) printf("%lld\n", n)
#define rep(i, init, n) for (int i = init; i < n; i++)
#define pb push_back
#define mp make_pair
#define F first
#define S second
#define gcd __gcd
#define inf INT_MAX
#define ninf INT_MIN
using namespace std;
const ll mod = 1e9 + 7;
const int N = 5e5 + 4;

struct util {
  int sum, mx;
};

util tree[4 * N];

int arr[N];

void build(int node, int st, int end) {
  if (st == end) {
    tree[node].sum = 0;

    tree[node].mx = arr[st];

    return;
  }

  int mid = (st + end) / 2;

  build(2 * node, st, mid);

  build(2 * node + 1, mid + 1, end);

  tree[node].mx = max(tree[2 * node].mx, tree[2 * node + 1].mx);
}

void update(int node, int st, int end, int ind, int val) {
  if (st == end) {
    tree[node].sum += val;

    return;
  }

  int mid = (st + end) / 2;

  if (ind <= mid)
    update(2 * node, st, mid, ind, val);
  else
    update(2 * node + 1, mid + 1, end, ind, val);

  tree[node].sum = tree[2 * node].sum + tree[2 * node + 1].sum;
}

util query(int node, int st, int end, int l, int r) {
  if (st > r or end < l) {
    util aux;

    aux.sum = aux.mx = 0;

    return aux;
  }

  if (st >= l and end <= r)
    return tree[node];

  int mid = (st + end) / 2;

  util a, b, here;

  a = query(2 * node, st, mid, l, r);

  b = query(2 * node + 1, mid + 1, end, l, r);

  here.sum = a.sum + b.sum;

  here.mx = max(a.mx, b.mx);

  return here;
}

int main() {
  int n, q;

  scn(n);
  scn(q);

  rep(i, 0, n) scn(arr[i]);

  build(1, 0, n - 1);

  vector<pair<int, int>> v[n];

  int ans[q];

  int prev[N]; // last[x] denotes the previous index in which x was present

  memset(prev, -1, sizeof(prev));

  rep(i, 0, q) {
    int l, r;

    scn(l);
    scn(r);

    l--;
    r--;

    // cout<<l<<" "<<r<<" "<<i<<endl;

    v[r].emplace_back(l, i);
  }

  rep(i, 0, n) {
    int here = arr[i];

    if (prev[here] != -1)
      update(1, 0, n - 1, prev[here], -1);

    update(1, 0, n - 1, i, 1);

    prev[here] = i;

    for (auto it : v[i]) {
      int hr = i, hl = it.F, hind = it.S;

      // cout<<hl<<" "<<hr<<" "<<hind<<endl;

      util temp = query(1, 0, n - 1, hl, hr);

      ans[hind] = temp.sum;
    }
  }

  rep(i, 0, q) priln(ans[i]);
}