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


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

#ifdef LOCAL
#include "debug.h"
#else
#include <bits/stdc++.h>
using namespace std;
#define debug(x...)
#endif

/*
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
template<class T>
using ordered_set= tree<T, null_type,
                less<T>,
                rb_tree_tag, tree_order_statistics_node_update> ;
template<class T>
using ordered_mset= tree<T, null_type,
                less_equal<T>,
                rb_tree_tag, tree_order_statistics_node_update> ;

*/

/*

PBDS
-------------------------------------------------
                        0 based indexing
-------------------------------------------------
1) insert(value)
2) erase(value)
3) order_of_key(value) // Number of items strictly smaller than value
4) *find_by_order(k) : K-th element in a set (counting from zero)

*/

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

// mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

const int mx = 5e5 + 5;

int ara[mx], bit[mx], last[mx], ans[mx];

struct ques {
  int l, r, id;
} query[mx];

bool comp(ques a, ques b) { return a.r < b.r; }

void update(int idx, int val, int n) {
  for (; idx <= n; idx += (idx & -idx))
    bit[idx] += val;
}

int sum(int idx, int n) {
  int tot = 0;
  for (; idx > 0; idx -= (idx & -idx))
    tot += bit[idx];
  return tot;
}

void solve() {
  memset(last, -1, sizeof last);

  int n, q;
  cin >> n >> q;

  for (int i = 1; i <= n; i++)
    cin >> ara[i];

  for (int i = 1; i <= q; i++) {
    cin >> query[i].l >> query[i].r;
    query[i].id = i;
  }

  sort(query + 1, query + q + 1, comp);

  int now = 1;

  for (int i = 1; i <= n; i++) {
    if (last[ara[i]] != -1)
      update(last[ara[i]], -1, n);

    last[ara[i]] = i;
    update(i, 1, n);

    while (now <= q && query[now].r == i) {
      ans[query[now].id] = sum(query[now].r, n) - sum(query[now].l - 1, n);
      now++;
    }
  }

  for (int i = 1; i <= q; i++)
    cout << ans[i] << "\\n";
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);

  int t = 1;
  // cin>>t;

  for (int i = 1; i <= t; i++) {
    // cout<<"Case "<<i<<": ";
    solve();
  }

#ifdef LOCAL
  cerr << "\\nTime elapsed: " << 1000.0 * clock() / CLOCKS_PER_SEC << " ms\\n";
#endif

  return 0;
}


Error: TLE

Fixed submission:


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

#ifdef LOCAL
#include "debug.h"
#else
#include <bits/stdc++.h>
using namespace std;
#define debug(x...)
#endif

/*
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
template<class T>
using ordered_set= tree<T, null_type,
                less<T>,
                rb_tree_tag, tree_order_statistics_node_update> ;
template<class T>
using ordered_mset= tree<T, null_type,
                less_equal<T>,
                rb_tree_tag, tree_order_statistics_node_update> ;

*/

/*

PBDS
-------------------------------------------------
                        0 based indexing
-------------------------------------------------
1) insert(value)
2) erase(value)
3) order_of_key(value) // Number of items strictly smaller than value
4) *find_by_order(k) : K-th element in a set (counting from zero)

*/

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

// mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

const int mx = 5e5 + 5;

int ara[mx], fre[mx], ans[mx];
int n;
int sz = 750;
int q, now;

struct query {
  int l, r, id;

  bool operator<(const query &a) const {
    int x = l / sz;
    int y = a.l / sz;

    if (x == y)
      return r < a.r;
    return x < y;
  }
} ques[mx];

void solve() {
  cin >> n >> q;

  for (int i = 1; i <= n; i++)
    cin >> ara[i];

  for (int i = 1; i <= q; i++) {
    cin >> ques[i].l >> ques[i].r;
    ques[i].id = i;
  }

  sort(ques + 1, ques + q + 1);

  int l = 0, r = -1;
  now = 0;

  for (int i = 1; i <= q; i++) {
    while (l > ques[i].l) {
      --l;
      fre[ara[l]]++;

      if (fre[ara[l]] == 1)
        now++;
    }

    while (l < ques[i].l) {
      fre[ara[l]]--;

      if (fre[ara[l]] == 0)
        now--;

      l++;
    }
    while (r > ques[i].r) {
      fre[ara[r]]--;

      if (fre[ara[r]] == 0)
        now--;

      r--;
    }
    while (r < ques[i].r) {
      r++;
      fre[ara[r]]++;

      if (fre[ara[r]] == 1)
        now++;
    }

    ans[ques[i].id] = now;
  }

  for (int i = 1; i <= q; i++)
    cout << ans[i] << "\\n";
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);

  int t = 1;
  // cin>>t;

  for (int i = 1; i <= t; i++) {
    // cout<<"Case "<<i<<": ";
    solve();
  }

#ifdef LOCAL
  cerr << "\\nTime elapsed: " << 1000.0 * clock() / CLOCKS_PER_SEC << " ms\\n";
#endif

  return 0;
}