Problem p02599 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>
using namespace std;
int n, m;
const int Maxn = 3e7;
int a[500005], li[500005];
int was[500005];
int last[500005];
struct t {
  int ls, rs, sum;
} tree[Maxn];
int root[500005];
int tot = 0;
int build(int l, int r) {
  int now = ++tot;
  if (l == r)
    return now;
  int mid = (l + r) / 2;
  tree[now].ls = build(l, mid);
  tree[now].rs = build(mid + 1, r);
  return now;
}
int modify(int now, int l, int r, int goal, int sum) { //
  int pos = ++tot;
  tree[pos] = tree[now];
  //	cout<<"l:"<<l<<" r:"<<r<<endl;
  if (l == r) {
    tree[pos].sum += sum;
    return pos;
  }
  int mid = (l + r) >> 1;
  if (goal <= mid) {
    tree[pos].ls = modify(tree[now].ls, l, mid, goal, sum);
  } else if (goal > mid) {
    tree[pos].rs = modify(tree[now].rs, mid + 1, r, goal, sum);
  }
  tree[pos].sum = tree[tree[pos].ls].sum + tree[tree[pos].rs].sum;
  return pos;
}
int anss = 0;
void query(int pos1, int pos2, int gl, int gr, int l, int r) {
  //	cout<<"l:"<<l<<" r:"<<r<<"gl:"<<gl<<"gr:"<<gr<<endl;
  if (gl <= l && r <= gr) {
    anss = anss + tree[pos2].sum - tree[pos1].sum;
    return;
  }
  int mid = (l + r) >> 1;
  if (mid >= gl) {
    query(tree[pos1].ls, tree[pos2].ls, gl, gr, l, mid);
  }
  if (mid < gr)
    query(tree[pos1].rs, tree[pos2].rs, gl, gr, mid + 1, r);
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &a[i]);
    was[i] = last[a[i]];
    last[a[i]] = i;
  }
  root[0] = build(0, n);
  //	cout<<"alive"<<endl;
  for (int i = 1; i <= n; i++) {
    root[i] = modify(root[i - 1], 0, n, was[i], 1);
  }
  int l, r;
  for (int i = 1; i <= m; i++) {
    scanf("%d%d", &l, &r);
    anss = 0;
    query(root[l - 1], root[r], 0, l - 1, 0, n);
    cout << anss << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
int n, m;
const int Maxn = 3e7;
int a[500005], li[500005];
struct t {
  int ls, rs, sum;
} tree[Maxn];
int root[500005];
int tot = 0;
int build(int l, int r) {
  int now = ++tot;
  if (l == r)
    return now;
  int mid = (l + r) / 2;
  tree[now].ls = build(l, mid);
  tree[now].rs = build(mid + 1, r);
  return now;
}
int modify(int now, int l, int r, int goal, int sum) { //
  int pos = ++tot;
  tree[pos] = tree[now];
  //	cout<<"l:"<<l<<" r:"<<r<<endl;
  if (l == r) {
    tree[pos].sum += sum;
    return pos;
  }
  int mid = (l + r) >> 1;
  if (goal <= mid) {
    tree[pos].ls = modify(tree[now].ls, l, mid, goal, sum);
  } else if (goal > mid) {
    tree[pos].rs = modify(tree[now].rs, mid + 1, r, goal, sum);
  }
  tree[pos].sum = tree[tree[pos].ls].sum + tree[tree[pos].rs].sum;

  return pos;
}
int anss = 0;
void query(int pos1, int pos2, int l, int r) {
  //	cout<<"l:"<<l<<" r:"<<r<<endl;
  if (l == r) {
    //		cout<<tree[pos2].sum<<"\\t"<<tree[pos1].sum<<endl;
    if (tree[pos2].sum - tree[pos1].sum > 0)
      anss++;
    return;
  }
  int mid = (l + r) >> 1;
  if (tree[tree[pos1].ls].sum < tree[tree[pos2].ls].sum) {
    query(tree[pos1].ls, tree[pos2].ls, l, mid);
  }
  if (tree[tree[pos1].rs].sum < tree[tree[pos2].rs].sum) {
    query(tree[pos1].rs, tree[pos2].rs, mid + 1, r);
  }
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &a[i]);
    li[i] = a[i];
  }
  sort(li + 1, li + 1 + n);
  int ed = unique(li + 1, li + 1 + n) - li;
  //	cout<<"alive"<<endl;
  root[0] = build(1, ed - 1);
  //	cout<<"alive"<<endl;
  for (int i = 1; i <= n; i++) {
    //		cout<<"alive"<<i<<endl;
    int sum = lower_bound(li + 1, li + ed, a[i]) - li;
    root[i] = modify(root[i - 1], 1, ed - 1, sum, 1);
    //		cout<<"alive"<<i<<endl;
  }
  int l, r;
  for (int i = 1; i <= m; i++) {
    scanf("%d%d", &l, &r);
    anss = 0;
    query(root[l - 1], root[r], 1, ed - 1);
    cout << anss << endl;
  }
  return 0;
}