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

#include "iostream"
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <map>
using namespace std;
#define dir(a, b) (a >> b)
const int Max = 500010;
int root[Max], tot, val[Max];
using namespace std;
struct node {
  int lef, rig, sum;
} msegtr[Max * 40];
map<int, int> mp;
void Init() {
  tot = 0;
  msegtr[0].lef = msegtr[0].rig = msegtr[0].sum = 0;
  root[0] = 0;
  mp.clear();
  return;
}
void Create(int sta, int enn, int &x, int y, int pos, int aad) {
  msegtr[++tot] = msegtr[y];
  msegtr[tot].sum += aad;
  x = tot;
  if (sta == enn)
    return;
  int mid = dir(sta + enn, 1);
  if (mid >= pos)
    Create(sta, mid, msegtr[x].lef, msegtr[y].lef, pos, aad);
  else
    Create(mid + 1, enn, msegtr[x].rig, msegtr[y].rig, pos, aad);
  return;
}
int Query(int sta, int enn, int x, int y) // 只有左边有界限
{
  if (sta >= y)
    return msegtr[x].sum;
  int mid = dir(sta + enn, 1);
  if (mid >= y)
    return Query(sta, mid, msegtr[x].lef, y) + msegtr[msegtr[x].rig].sum;
  else
    return Query(mid + 1, enn, msegtr[x].rig, y);
}
int main() {
  int n, m, temp;
  int lef, rig;
  cin >> n >> m;
  Init();
  for (int i = 1; i <= n; ++i) {
    scanf("%d", &val[i]);
    if (!mp.count(val[i])) // 直接加
    {
      Create(1, n, root[i], root[i - 1], i,
             1); // 注意是在i这个位置加1，不是权值线段树的val[i]位置加1
    } else {
      Create(1, n, temp, root[i - 1], mp[val[i]], -1); // 先在原位置减去1
      Create(1, n, root[i], temp, i, 1);
    }
    mp[val[i]] = i;
  }

  for (int i = 0; i < m; ++i) {
    scanf("%d %d", &lef, &rig);
    printf("%d\\n",
           Query(1, n, root[rig], lef)); // 在rig的历史版本上找(lef,rig)的值
  }

  return 0;
}

Error: -11

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int maxn = 5e5 + 2;

int root[maxn], tot;
int m;
int a[maxn], b[maxn];
void quchong(int n) {
  sort(b + 1, b + 1 + n);
  m = unique(b + 1, b + 1 + n) - b - 1;
}

int getid(int x) { return lower_bound(b + 1, b + 1 + m, x) - b; }

const int xx = 1e7 + 100;
struct Tree {
  int lc, rc;
  int sum;
} tree[xx];

void pushup(int k) {
  tree[k].sum = tree[tree[k].lc].sum + tree[tree[k].rc].sum;
}

int build(int l, int r) {
  int k = ++tot;
  tree[k].sum = 0;
  if (l == r)
    return k;
  int mid = (l + r) >> 1;
  tree[k].lc = build(l, mid);
  tree[k].rc = build(mid + 1, r);
  return k;
}

int updata(int p, int id, int v, int l, int r) {
  int k = ++tot;
  tree[k] = tree[p];
  if (l == r) {
    tree[k].sum += v;
    return k;
  }
  int mid = (l + r) >> 1;
  if (id <= mid)
    tree[k].lc = updata(tree[p].lc, id, v, l, mid);
  else
    tree[k].rc = updata(tree[p].rc, id, v, mid + 1, r);
  pushup(k);
  return k;
}

int myfind(int p, int id, int l, int r) {
  if (l == r)
    return tree[p].sum;
  int mid = (l + r) >> 1;
  if (id <= mid)
    return tree[tree[p].rc].sum + myfind(tree[p].lc, id, l, mid);
  return myfind(tree[p].rc, id, mid + 1, r);
}

int belong[maxn];

int main() {
#ifdef LOCAL
  freopen("in1.txt", "r", stdin);
  freopen("out1.txt", "w", stdout);
#endif
  int n, q;
  scanf("%d%d", &n, &q);
  for (int i = 1; i <= n; ++i) {
    scanf("%d", &a[i]);
    b[i] = a[i];
  }
  int l, r;
  quchong(n);

  root[0] = build(1, n);
  for (int i = 1; i <= n; ++i) {
    int id = getid(a[i]);
    if (belong[id]) {
      int t = updata(root[i - 1], belong[id], -1, 1, n);
      root[i] = updata(t, i, 1, 1, n);
    } else {
      root[i] = updata(root[i - 1], i, 1, 1, n);
    }
    belong[id] = i;
  }

  while (q--) {
    scanf("%d%d", &l, &r);
    printf("%d\\n", myfind(root[r], l, 1, n));
  }

  return 0;
}