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



#include <algorithm>
#include <bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>

using namespace std;

const int MAX_N = int(1e6) + 10;
long long int MOD = 1e9 + 7;
const long long int INF = 1e18;

typedef long long int ll;
typedef unsigned long long int llu;

inline ll mul(ll a, ll b) {

  a = (a + MOD) % MOD;
  b = (b + MOD) % MOD;
  ll c = a * b;
  c = (c + MOD) % MOD;
  return c;
}
inline ll add(ll a, ll b) {
  a = (a + MOD) % MOD;
  b = (b + MOD) % MOD;
  ll ans = (a + b);
  ans = (ans + MOD) % MOD;
  return ans;
}
ll power(ll a, ll b, ll c = 0) {
  ll ans = 1;
  while (b) {
    if (b & 1) {
      ans = mul(ans, a);
    }
    a = mul(a, a);
    b = b / 2;
  }
  return ans;
}

#define all(x) (x).begin(), (x).end()

// s.reserve(32768); //updated !
// s.max_load_factor(0.25);

const int N = 1e5 + 5;

bool ok(ll x, vector<ll> &a, int n, ll K) {
  ll cnt = 0;
  for (int i = 0; i < n; i++) {
    if (a[i] <= x)
      continue;
    else if (a[i] % x == 0)
      cnt += a[i] / x - 1;
    else
      cnt += a[i] / x;
  }

  if (cnt <= K)
    return true;
  else
    return false;
}

int last[500005];
int tree[500005];
int a[500005];
int ans[500005];

void update(int x, int v) {
  while (x < 500005) {
    tree[x] += v;
    x += x & (-x);
  }
}

int query(int x) {
  int ans = 0;
  while (x > 0) {
    ans += tree[x];
    x -= x & (-x);
  }
  return ans;
}

vector<pair<int, pair<int, int>>> queries;
int main() {

  int n, q;
  scanf("%d%d", &n, &q);
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
  }

  for (int i = 1; i <= q; i++) {
    int l, r;
    scanf("%d%d", &l, &r);
    queries.push_back({r, {i, l}});
  }

  sort(queries.begin(), queries.end());

  int query_counter = 0;

  memset(last, -1, sizeof(last));

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

    update(i, 1);
    last[a[i]] = i;

    while (query_counter < q && queries[query_counter].first == i) {
      int L = queries[query_counter].second.second;
      int R = queries[query_counter].first;
      int indx = queries[query_counter].second.first;
      ans[indx] = query(R) - query(L - 1);
      // cout<<query_counter<<" "<<R<<" "<<L<<" "<<query(R)-query(L-1)<<endl;
      query_counter++;
    }
  }

  for (int i = 1; i <= q; i++) {
    printf("%d\\n", ans[i]);
  }
}


Error: TLE

Fixed submission:



#include <algorithm>
#include <bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>

using namespace std;

const int MAX_N = int(1e6) + 10;
long long int MOD = 1e9 + 7;
const long long int INF = 1e18;

typedef long long int ll;
typedef unsigned long long int llu;

inline ll mul(ll a, ll b) {

  a = (a + MOD) % MOD;
  b = (b + MOD) % MOD;
  ll c = a * b;
  c = (c + MOD) % MOD;
  return c;
}
inline ll add(ll a, ll b) {
  a = (a + MOD) % MOD;
  b = (b + MOD) % MOD;
  ll ans = (a + b);
  ans = (ans + MOD) % MOD;
  return ans;
}
ll power(ll a, ll b, ll c = 0) {
  ll ans = 1;
  while (b) {
    if (b & 1) {
      ans = mul(ans, a);
    }
    a = mul(a, a);
    b = b / 2;
  }
  return ans;
}

#define all(x) (x).begin(), (x).end()

// s.reserve(32768); //updated !
// s.max_load_factor(0.25);

const int N = 1e5 + 5;

bool ok(ll x, vector<ll> &a, int n, ll K) {
  ll cnt = 0;
  for (int i = 0; i < n; i++) {
    if (a[i] <= x)
      continue;
    else if (a[i] % x == 0)
      cnt += a[i] / x - 1;
    else
      cnt += a[i] / x;
  }

  if (cnt <= K)
    return true;
  else
    return false;
}

int has[500005];
int cnt = 0;

inline void add(int &x) {
  if (has[x] == 0)
    cnt++;
  has[x]++;
}

inline void remove(int &x) {
  if (has[x] == 1)
    cnt--;
  has[x]--;
}

int ans[500005];
int a[500005];

vector<pair<int, pair<int, int>>> queries[1005];
int main() {

  int n, q;
  scanf("%d%d", &n, &q);
  for (int i = 0; i < n; i++) {
    cin >> a[i];
  }
  int sz = sqrt(n);

  for (int i = 0; i < q; i++) {
    int l, r;
    scanf("%d%d\\n", &l, &r);
    --l;
    --r;
    queries[l / sz].push_back({r, {i, l}});
  }

  for (int i = 0; i <= 1000; i++) {
    sort(queries[i].begin(), queries[i].end());
  }

  int low = 0;
  int right = -1;

  for (int i = 0; i <= 1000; i++) {
    for (auto it : queries[i]) {
      int L = it.second.second;
      int R = it.first;
      int indx = it.second.first;

      while (right < R) {
        add(a[right + 1]);
        right++;
      }

      while (low < L) {
        remove(a[low]);
        low++;
      }

      while (right > R) {
        remove(a[right]);
        right--;
      }

      while (low > L) {
        add(a[low - 1]);
        low--;
      }

      ans[indx] = cnt;
    }
  }

  for (int i = 0; i < q; i++) {
    printf("%d\\n", ans[i]);
  }
}