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


#include <bits/stdc++.h>
#define rep(i, n) for (ll i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
const ll INF = 1e18;

namespace internal {

// @param n `0 <= n`
// @return minimum non-negative `x` s.t. `n <= 2**x`
int ceil_pow2(int n) {
  int x = 0;
  while ((1U << x) < (unsigned int)(n))
    x++;
  return x;
}

// @param n `1 <= n`
// @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`
int bsf(unsigned int n) {
#ifdef _MSC_VER
  unsigned long index;
  _BitScanForward(&index, n);
  return index;
#else
  return __builtin_ctz(n);
#endif
}

} // namespace internal

template <class S, S (*op)(S, S), S (*e)()> struct segtree {
public:
  segtree() : segtree(0) {}
  segtree(int n) : segtree(std::vector<S>(n, e())) {}
  segtree(const std::vector<S> &v) : _n(int(v.size())) {
    log = internal::ceil_pow2(_n);
    size = 1 << log;
    d = std::vector<S>(2 * size, e());
    for (int i = 0; i < _n; i++)
      d[size + i] = v[i];
    for (int i = size - 1; i >= 1; i--) {
      update(i);
    }
  }

  void set(int p, S x) {
    assert(0 <= p && p < _n);
    p += size;
    d[p] = x;
    for (int i = 1; i <= log; i++)
      update(p >> i);
  }

  S get(int p) {
    assert(0 <= p && p < _n);
    return d[p + size];
  }

  S prod(int l, int r) {
    assert(0 <= l && l <= r && r <= _n);
    S sml = e(), smr = e();
    l += size;
    r += size;

    while (l < r) {
      if (l & 1)
        sml = op(sml, d[l++]);
      if (r & 1)
        smr = op(d[--r], smr);
      l >>= 1;
      r >>= 1;
    }
    return op(sml, smr);
  }

  S all_prod() { return d[1]; }

  template <bool (*f)(S)> int max_right(int l) {
    return max_right(l, [](S x) { return f(x); });
  }
  template <class F> int max_right(int l, F f) {
    assert(0 <= l && l <= _n);
    assert(f(e()));
    if (l == _n)
      return _n;
    l += size;
    S sm = e();
    do {
      while (l % 2 == 0)
        l >>= 1;
      if (!f(op(sm, d[l]))) {
        while (l < size) {
          l = (2 * l);
          if (f(op(sm, d[l]))) {
            sm = op(sm, d[l]);
            l++;
          }
        }
        return l - size;
      }
      sm = op(sm, d[l]);
      l++;
    } while ((l & -l) != l);
    return _n;
  }

  template <bool (*f)(S)> int min_left(int r) {
    return min_left(r, [](S x) { return f(x); });
  }
  template <class F> int min_left(int r, F f) {
    assert(0 <= r && r <= _n);
    assert(f(e()));
    if (r == 0)
      return 0;
    r += size;
    S sm = e();
    do {
      r--;
      while (r > 1 && (r % 2))
        r >>= 1;
      if (!f(op(d[r], sm))) {
        while (r < size) {
          r = (2 * r + 1);
          if (f(op(d[r], sm))) {
            sm = op(d[r], sm);
            r--;
          }
        }
        return r + 1 - size;
      }
      sm = op(d[r], sm);
    } while ((r & -r) != r);
    return 0;
  }

private:
  int _n, size, log;
  std::vector<S> d;

  void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
};

int op(int a, int b) { return max(a, b); }

int e() { return 0; }

int main() {
  int n, k;
  cin >> n >> k;
  vector<int> a(n);
  segtree<int, op, e> d(300005);

  rep(i, n) {
    cin >> a[i];
    int l = a[i] - k;
    int r = a[i] + k + 1;
    l = max(l, 0);
    r = min(r, 300005);
    ll now = d.prod(l, r);
    d.set(a[i], now + 1);
  }
  int ans = d.prod(0, 300005);
  cout << ans;
}


Error: TLE

Fixed submission:


#include <bits/stdc++.h>
#define rep(i, n) for (ll i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
const ll INF = 1e18;

struct UnionFind {
  vector<int> d;
  UnionFind(int n) : d(n, -1) {} //-1で初期化
  int root(int x) {
    if (d[x] < 0)
      return x; // rootを負にする（構成node数x(-1))
    // root以外は親の番号
    return d[x] = root(d[x]);
    // return(root(d[x]))とするとメモできないが上の書き方だとメモができる
  }
  bool unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return false;
    if (d[x] > d[y])
      swap(x, y);
    // swapすることで小さい方を大きい方につけられ計算量減らせる
    d[x] += d[y];
    d[y] = x;
    return true;
  }
  bool same(int x, int y) { return root(x) == root(y); }
  // 同じグループ化
  int size(int x) { return -d[root(x)]; }
  // グループのnode数
  int group_num(int n) {
    set<int> s;
    for (int i = 0; i < n; ++i) {
      s.insert(root(i));
    }
    return int(s.size());
  }
};

int main() {
  ll n, k;
  cin >> n >> k;
  vector<ll> a(n);
  vector<ll> d(n + 5, 1);

  rep(i, n) cin >> a[i];
  rep(i, n - 1) {
    rep(j, i + 1) {
      if (abs(a[i + 1] - a[j]) <= k) {
        //    cout<<'i'<<i+1<<'j'<<j<<endl;
        d[i + 1] = max(d[i + 1], d[j] + 1);
      }
    }
  }
  ll ans = 0;
  rep(i, n + 1) {
    //  cout<<d[i];
    ans = max(ans, d[i]);
  }
  cout << ans;
}