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

#include <algorithm>
#include <complex>
#include <functional>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
#include <time.h>
#include <vector>
using namespace std;
#define rep(i, a, n) for (llint i = (a); i < (n); i++)
#define ll long long
#define llint long long int
#define reverse(v) reverse(v.begin(), v.end());
#define Yes(ans)                                                               \\
  if (ans)                                                                     \\
    cout << "Yes" << endl;                                                     \\
  else                                                                         \\
    cout << "No" << endl;
#define YES(ans)                                                               \\
  if (ans)                                                                     \\
    cout << "YES" << endl;                                                     \\
  else                                                                         \\
    cout << "NO" << endl;
#define hei(a) vector<a>
#define whei(a) vector<vector<a>>
#define UF UnionFind
#define Pint pair<int, int>
#define Pll pair<llint, llint>
#define keta(a) fixed << setprecision(a)
const ll mod = 1000000007;
// 辞書順はnext_permutation( begin( v ), end( v ) );やで！
const ll INF = 1000000000;

class UnionFind {
public:
  // 親の番号を格納する
  vector<int> par;

  // 最初は全てが根であるとして初期化
  UnionFind(int N) {
    par.resize(N);
    for (int i = 0; i < N; i++)
      par[i] = i;
  }

  // Aがどのグループに属しているか調べる
  int root(int A) {
    if (par[A] == A)
      return A;
    return par[A] = root(par[A]);
  }

  // AとBをくっ付ける
  bool unite(int A, int B) {
    // AとBを直接つなぐのではなく、root(A)にroot(B)をくっつける
    A = root(A);
    B = root(B);
    if (A == B) {
      // すでにくっついてるからくっ付けない
      return false;
    }

    // Bの親をAに変更する
    par[B] = A;

    return true;
  }
  bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す
    int rx = root(x);
    int ry = root(y);
    return rx == ry;
  }
};

template <class T> class SegTree {
public:
  int size;
  vector<T> seg;                             // 配列
  T e;                                       // 単位元
  function<T(T, T)> f;                       // 演算
  SegTree(T n, T _e, function<T(T, T)> _f) { // コンストラクタ(初期化)
    f = _f;
    e = _e;
    size = 1;
    while (size < n)
      size *= 2;
    seg.resize(size * 2 - 1, e);
  }

  void updata(int n, int k) { // 一点更新
    n += size - 1;
    seg[n] = k;
    while (n > 0) {
      n = (n - 1) / 2;
      seg[n] = f(seg[n * 2 + 1], seg[n * 2 + 2]);
    }
  }
  T query(int a, int b, int l, int r, int k) {
    if (b <= l || r <= a)
      return e;
    if (a <= l && r <= b)
      return seg[k];
    T v1 = query(a, b, l, (l + r) / 2, k * 2 + 1);
    T v2 = query(a, b, (l + r) / 2, r, k * 2 + 2);
    return f(v1, v2);
  }
};

int main() {
  int n, k;
  cin >> n >> k;
  SegTree<int> tree(300001, 0, [](int a, int b) { return max(a, b); });
  hei(int) a(n);
  rep(i, 0, n) { cin >> a[i]; }
  int ans = 0;
  rep(i, 0, n) {
    int l = max(0, a[i] - k);
    int r = min(a[i] + k, tree.size);
    int sum = tree.query(l, r + 1, 0, tree.size, 0) + 1;
    ans = max(ans, sum);
    tree.updata(a[i], sum);
  }
  cout << ans << endl;
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <complex>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
#include <time.h>
#include <vector>
using namespace std;
#define rep(i, a, n) for (llint i = (a); i < (n); i++)
#define ll long long
#define llint long long int
#define reverse(v) reverse(v.begin(), v.end());
#define Yes(ans)                                                               \\
  if (ans)                                                                     \\
    cout << "Yes" << endl;                                                     \\
  else                                                                         \\
    cout << "No" << endl;
#define YES(ans)                                                               \\
  if (ans)                                                                     \\
    cout << "YES" << endl;                                                     \\
  else                                                                         \\
    cout << "NO" << endl;
#define hei(a) vector<a>
#define whei(a) vector<vector<a>>
#define UF UnionFind
#define Pint pair<int, int>
#define Pll pair<llint, llint>
#define keta(a) fixed << setprecision(a)
const ll mod = 1000000007;
// 辞書順はnext_permutation( begin( v ), end( v ) );やで！
const ll INF = 1000000000;

class UnionFind {
public:
  // 親の番号を格納する
  vector<int> par;

  // 最初は全てが根であるとして初期化
  UnionFind(int N) {
    par.resize(N);
    for (int i = 0; i < N; i++)
      par[i] = i;
  }

  // Aがどのグループに属しているか調べる
  int root(int A) {
    if (par[A] == A)
      return A;
    return par[A] = root(par[A]);
  }

  // AとBをくっ付ける
  bool unite(int A, int B) {
    // AとBを直接つなぐのではなく、root(A)にroot(B)をくっつける
    A = root(A);
    B = root(B);
    if (A == B) {
      // すでにくっついてるからくっ付けない
      return false;
    }

    // Bの親をAに変更する
    par[B] = A;

    return true;
  }
  bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す
    int rx = root(x);
    int ry = root(y);
    return rx == ry;
  }
};

int main() {
  int n, k;
  cin >> n >> k;
  hei(int) a(n);
  rep(i, 0, n) cin >> a[i];
  hei(int) dp(n, 1);
  rep(i, 0, n) {
    rep(j, i + 1, n) {
      if (abs(a[i] - a[j]) <= k) {
        dp[j] = max(dp[i] + 1, dp[j]);
      }
    }
  }
  cout << dp[n - 1] << endl;
  return 0;
}