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

#include <bits/stdc++.h>
#define ff first
#define ss second
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define mset(x, y) memset((x), (y), sizeof(x))
#define sz(x) ((int)(x).size())
#define rep(i, a, b) for (i = a; i < b; i++)
#define per(i, a, b) for (i = a; i >= b; i--)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define cerr cout
#define endl '\\n'
using namespace std;

string to_string(string s) { return '"' + s + '"'; }
string to_string(char s) { return string(1, s); }
string to_string(const char *s) { return to_string((string)s); }
string to_string(bool b) { return (b ? "true" : "false"); }
template <typename A> string to_string(A);
template <typename A, typename B> string to_string(pair<A, B> p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}
template <typename A> string to_string(A v) {
  bool f = 1;
  string r = "{";
  for (const auto &x : v) {
    if (!f)
      r += ", ";
    f = 0;
    r += to_string(x);
  }
  return r + "}";
}
void debug_out() { cerr << endl; }
template <typename Head, typename... Tail> void debug_out(Head H, Tail... T) {
  cerr << " " << to_string(H);
  debug_out(T...);
}
#define pr(...) cerr << "[" << #__VA_ARGS__ << "] :", debug_out(__VA_ARGS__)

typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
const ld eps = 1e-7;
const ll mod = 1000000007;
const ll N = 998244353;

ll binpow(ll b, ll p) {
  ll ans = 1;
  while (p > 0) {
    if (p & 1)
      ans = (ans * b) % mod;
    b = (b * b) % mod;
    p >>= 1;
  }
  return ans;
}
ll modinv(ll x) { return binpow(x, mod - 2); }

const int mxn = 5e5 + 100;
int a[mxn], last[mxn];
vector<int> t(4 * mxn);

int query(int v, int tl, int tr, int l, int r) {
  if (l > r)
    return 0;
  if (l == tl && r == tr)
    return t[v];
  else {
    int mid = (tl + tr) / 2;
    return query(2 * v, tl, mid, l, min(r, mid)) +
           query(2 * v + 1, mid + 1, tr, max(l, mid + 1), r);
  }
}

void update(int v, int tl, int tr, int pos, int val) {
  if (tl == tr)
    t[v] = val;
  else {
    int mid = (tl + tr) / 2;
    if (pos <= mid)
      update(2 * v, tl, mid, pos, val);
    else
      update(2 * v + 1, mid + 1, tr, pos, val);
    t[v] = t[2 * v] + t[2 * v + 1];
  }
}

signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);

  int n, q, i, l, r;
  cin >> n >> q;
  mset(last, -1);
  rep(i, 0, n) cin >> a[i];
  // build(1, 0, n - 1);
  vector<vpii> que(n);
  vi ans(q);
  rep(i, 0, q) {
    cin >> l >> r;
    l--;
    r--;
    que[r].pb({l, i});
  }

  rep(i, 0, n) {
    update(1, 0, n - 1, i, 1);
    if (last[a[i]] != -1)
      update(1, 0, n - 1, last[a[i]], 0);
    last[a[i]] = i;
    for (pii &curr : que[i])
      ans[curr.ss] = query(1, 0, n - 1, curr.first, i);
  }

  rep(i, 0, q) cout << ans[i] << endl;
}

Error: WA

Fixed submission:

// C++ implementation of above approach
#include <bits/stdc++.h>
using namespace std;

// Each segment of the segment tree would be a set
// to maintain distinct elements
set<int> *segment;

// Build the segment tree
// i denotes current node, s denotes start and
// e denotes the end of range for current node
void build(int i, int s, int e, int arr[]) {

  // If start is equal to end then
  // insert the array element
  if (s == e) {
    segment[i].insert(arr[s]);
    return;
  }

  // Else divide the range into two halves
  // (start to mid) and (mid+1 to end)
  // first half will be the left node
  // and the second half will be the right node
  build(2 * i, s, (s + e) / 2, arr);
  build(1 + 2 * i, 1 + (s + e) / 2, e, arr);

  // Insert the sets of right and left
  // node of the segment tree
  segment[i].insert(segment[2 * i].begin(), segment[2 * i].end());

  segment[i].insert(segment[2 * i + 1].begin(), segment[2 * i + 1].end());
}

// Query in an range a to b
set<int> query(int node, int l, int r, int a, int b) {
  set<int> left, right, result;

  // If the range is out of the bounds
  // of this segment
  if (b < l || a > r)
    return result;

  // If the range lies in this segment
  if (a <= l && r <= b)
    return segment[node];

  // Else query for the right and left
  // leaf node of this subtree
  // and insert them into the set
  left = query(2 * node, l, (l + r) / 2, a, b);
  result.insert(left.begin(), left.end());

  right = query(1 + 2 * node, 1 + (l + r) / 2, r, a, b);
  result.insert(right.begin(), right.end());

  // Return the result
  return result;
}

// Initialize the segment tree
void init(int n) {
  // Get the height of the segment tree
  int h = (int)ceil(log2(n));
  h = (2 * (pow(2, h))) - 1;

  // Initialize the segment tree
  segment = new set<int>[h];
}

// Function to get the result for the
// subarray from arr[l] to arr[r]
int getDistinct(int l, int r, int n) {
  // Query for the range set
  set<int> ans = query(1, 0, n - 1, l, r);

  return ans.size();
}

// Driver code
int main() {
  int n, i, q, l, r;
  cin >> n >> q;
  int arr[n];
  for (i = 0; i < n; i++)
    cin >> arr[i];
  // int n = sizeof(arr) / sizeof(arr[0]);

  init(n);

  // Bulid the segment tree v
  build(1, 0, n - 1, arr);
  while (q--) {
    cin >> l >> r;
    cout << getDistinct(l, r, n) << endl;
  }
  // Query in range 0 to 4
  // getDistinct(0, 4, n);

  // return 0;
}