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

/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author
 */

// Created by White Knife on 15/04/20.
// doot diddly donger cuckerino Hahahahahah

#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx")
#pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
using namespace __gnu_cxx;
using namespace std;

// @formatter:off
#define F first
#define S second
#define all(x) (x).begin(), (x).end()
#define sz(x) (long long)(x).size()
#define sim template <typename T
#define ris return *this
#define dor > debug &operator<<
#define eni(x)                                                                 \\
  sim > typename enable_if<sizeof dud<T>(0) x 1, debug &>::type operator<<(T i)
sim > struct rge {
  T b, e;
};
sim > rge<T> rang(T i, T j) { return rge<T>{i, j}; }
sim > auto dud(T *x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef LOCAL
  ~debug() { cerr << endl; }
  eni(!=) {
    cerr << boolalpha << i;
    ris;
  }
  eni(==) { ris << rang(all(i)); }
  sim, typename U dor(pair<U, T> d) {
    ris << "(" << d.first << ", " << d.second << ")";
  }
  sim dor(rge<T> d) {
    *this << "[";
    for (auto it = d.b; it != d.e; ++it)
      *this << ", " + 2 * (it == d.b) << *it;
    ris << "]";
  }
#else
  sim dor(const T &) { ris; }
#endif
};
#define pr(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "

using ll = long long;
using ull = unsigned long long;
using ld = long double;
// using li = __int128;
// using uli = unsigned __int128;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using vi = vector<int>;
using vb = vector<bool>;

using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vpii = vector<pii>;
using vpll = vector<pll>;
template <typename T>
using ordered_set =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

const ld PI = acos(-1);

template <typename T> inline T mini(T &x, T y) { return x = min(x, y); }
template <typename T> inline T maxi(T &x, T y) { return x = max(x, y); }
template <typename T> T rand(T x, T y) { return rand() % (y - x + 1) + x; }
mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());

// @formatter:on

/*
A structure able to perform the following operation on an array A:
1. Sum x to A[i].
2. Get the sum A[l] + A[l+1] + ... + A[r].
Both the operation are O(log(N)).
Everything is 0-based.
Thanks to aryanc403 axiom sum(0,i) == arr[i]
*/

template <typename T> class fenwick {
public:
  vector<T> bit;
  int n;
  int LOGN;

  fenwick(int _n) : n(_n), LOGN(log2(_n)) { bit.resize(n, T{}); }

  fenwick(const vector<T> &arr) : fenwick(arr.size()) {
    for (size_t i = 0; i < arr.size(); ++i) {
      update(i, arr[i]);
    }
  }

  void update(int idx, T delta) {
    while (idx < n) {
      bit[idx] += delta;
      idx |= (idx + 1);
    }
  }

  void update(int l, int r, T delta) {
    update(l, delta);
    update(r + 1, -delta);
  }

  T query(int idx) {
    T res{};
    while (idx >= 0) {
      res += bit[idx];
      idx = (idx & (idx + 1)) - 1;
    }
    return res;
  }

  T query(int l, int r) { return query(r) - query(l - 1); }

  void set(int p, T x) { update(p, x - query(p)); }

  int lower_bound(T val) {
    T sum = 0;
    int pos = 0;
    for (int i = LOGN; i >= 0; --i) {
      int curr = pos + (1ll << i) - 1;
      if (curr < n && sum + bit[curr] < val) {
        sum += bit[curr];
        pos += 1 << i;
      }
    }
    return pos;
  }

  int upper_bound(T val) {
    int pos = 0;
    for (int i = LOGN; i >= 0; --i) {
      int curr = pos + (1ll << i) - 1;
      if (curr < n && bit[curr] <= val) {
        val -= bit[curr];
        pos += 1 << i;
      }
    }
    return pos;
  }
};

class FRangeSetQuery {
public:
  void solve(std::istream &cin, std::ostream &cout) {
    int n, q;
    cin >> n >> q;
    vi a(n);
    for (int i = 0; i < n; ++i)
      cin >> a[i];
    fenwick<int> fenwick(n);
    vector<vector<pair<int, pii>>> queries(n);
    for (int i = 0; i < q; ++i) {
      int l, r;
      cin >> l >> r;
      l--, r--;
      queries[r].push_back({l, {i, 1}});
      if (l)
        queries[l - 1].push_back({l, {i, -1}});
    }
    vector<int> res(q);
    vector<int> prev(n, -1);
    map<int, int> last;
    for (int i = 0; i < n; ++i) {
      if (last.count(a[i])) {
        prev[i] = last[a[i]];
      }
      last[a[i]] = i;
      fenwick.update(prev[i] + 1, 1);
      for (auto c : queries[i]) {
        res[c.second.first] += fenwick.query(c.first) * c.second.second;
      }
    }

    for (int i = 0; i < q; ++i) {
      cout << res[i] << '\\n';
    }
  }
};

int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
  std::cout.tie(nullptr);
  FRangeSetQuery solver;
  std::istream &in(std::cin);
  std::ostream &out(std::cout);
  solver.solve(in, out);
  return 0;
}


Error: TLE

Fixed submission:

/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author
 */

// Created by White Knife on 15/04/20.
// doot diddly donger cuckerino Hahahahahah

#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx")
#pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
using namespace __gnu_cxx;
using namespace std;

// @formatter:off
#define F first
#define S second
#define all(x) (x).begin(), (x).end()
#define sz(x) (long long)(x).size()
#define sim template <typename T
#define ris return *this
#define dor > debug &operator<<
#define eni(x)                                                                 \\
  sim > typename enable_if<sizeof dud<T>(0) x 1, debug &>::type operator<<(T i)
sim > struct rge {
  T b, e;
};
sim > rge<T> rang(T i, T j) { return rge<T>{i, j}; }
sim > auto dud(T *x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef LOCAL
  ~debug() { cerr << endl; }
  eni(!=) {
    cerr << boolalpha << i;
    ris;
  }
  eni(==) { ris << rang(all(i)); }
  sim, typename U dor(pair<U, T> d) {
    ris << "(" << d.first << ", " << d.second << ")";
  }
  sim dor(rge<T> d) {
    *this << "[";
    for (auto it = d.b; it != d.e; ++it)
      *this << ", " + 2 * (it == d.b) << *it;
    ris << "]";
  }
#else
  sim dor(const T &) { ris; }
#endif
};
#define pr(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "

using ll = long long;
using ull = unsigned long long;
using ld = long double;
// using li = __int128;
// using uli = unsigned __int128;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using vi = vector<int>;
using vb = vector<bool>;

using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vpii = vector<pii>;
using vpll = vector<pll>;
template <typename T>
using ordered_set =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

const ld PI = acos(-1);

template <typename T> inline T mini(T &x, T y) { return x = min(x, y); }
template <typename T> inline T maxi(T &x, T y) { return x = max(x, y); }
template <typename T> T rand(T x, T y) { return rand() % (y - x + 1) + x; }
mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());

// @formatter:on

using node = set<int>;

static node NEUTERAL_ELEMENT = node();

struct segtreesum {
  int len{};
  vector<node> values;

  node unite(const node &left, const node &right) {
    node res = left;
    for (auto p : right)
      res.insert(p);
    return res;
  }
  node single(int val) {
    node res{val};
    return res;
  }
  void init(int n) {
    len = 1;
    while (len < n)
      len *= 2;
    values.assign(2 * len, node{});
  }

  explicit segtreesum(int n) { init(n); }

  explicit segtreesum(const vector<int> &a) {
    init(a.size());
    build(a, 0, 0, len);
  }

  void build(const vector<int> &a, int x, int lx, int rx) {
    if (rx - lx == 1) {
      if (lx < (int)a.size()) {
        values[x] = single(a[lx]);
      }
      return;
    }
    int m = mid(lx, rx);
    build(a, 2 * x + 1, lx, m);
    build(a, 2 * x + 2, m, rx);
    values[x] = unite(values[2 * x + 1], values[2 * x + 2]);
  }

  void update(int x, int lx, int rx, int i, int val) {
    if (rx - lx == 1) {
      values[x] = single(val);
      return;
    }
    int m = mid(lx, rx);
    if (i < m) {
      update(2 * x + 1, lx, m, i, val);
    } else {
      update(2 * x + 2, m, rx, i, val);
    }
    values[x] = unite(values[2 * x + 1], values[2 * x + 2]);
  }

  void update(int i, long long val) { update(0, 0, len, i, val); }

  node query(int x, int lx, int rx, int l, int r) {
    if (lx >= r || l >= rx)
      return NEUTERAL_ELEMENT;
    if (lx >= l && rx <= r)
      return values[x];
    int m = mid(lx, rx);
    node sl = query(2 * x + 1, lx, m, l, r);
    node sr = query(2 * x + 2, m, rx, l, r);
    return unite(sl, sr);
  }

  node query(int l, int r) { return query(0, 0, len, l, r); }

  int mid(int lx, int rx) { return (lx + rx) / 2; }
};

class FRangeSetQuery {
public:
  void solve(std::istream &cin, std::ostream &cout) {
    int n, q;
    cin >> n >> q;
    vector<int> a(n);
    for (int i = 0; i < n; ++i) {
      cin >> a[i];
    }
    segtreesum st(a);

    while (q--) {
      int l, r;
      cin >> l >> r;
      cout << st.query(l - 1, r).size() << '\\n';
    }
  }
};

int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
  std::cout.tie(nullptr);
  FRangeSetQuery solver;
  std::istream &in(std::cin);
  std::ostream &out(std::cout);
  solver.solve(in, out);
  return 0;
}