제출 #1349321

#제출 시각아이디문제언어결과실행 시간메모리
1349321ramzialoulouFinancial Report (JOI21_financial)C++20
5 / 100
421 ms55620 KiB
#include <bits/stdc++.h>
 
using namespace std;

const int inf = int(1e9);

class dsu {
  public:
  int n;
  vector<int> p, sz, mn;
  dsu(int n_) : n(n_) {
    p.resize(n);
    iota(p.begin(), p.end(), 0);
    sz.assign(n, 1);
    mn.resize(n);
    iota(mn.begin(), mn.end(), 0);
  }
  int get(int x) {
    return (p[x] == x ? x : p[x] = get(p[x]));
  }
  int get_min(int x) {
    return mn[get(x)];
  }
  void unite(int x, int y) {
    x = get(x);
    y = get(y);
    if (x == y) {
      return;
    }
    if (sz[x] < sz[y]) {
      swap(x, y);
    }
    sz[x] += sz[y];
    mn[x] = min(mn[x], mn[y]);
    p[y] = x;
  }
};

class segtree {
  public:
  int n;
  vector<int> seg;
  segtree(int n_) : n(n_) {
    seg.resize(4 * n);
  }
  void upd(int nd, int l, int r, int p, int v) {
    if (l == r) {
      seg[nd] = v;
      return;
    }
    int mid = (l + r) >> 1;
    if (p <= mid) {
      upd(nd * 2, l, mid, p, v);
    } else {
      upd(nd * 2 + 1, mid + 1, r, p, v);
    }
    seg[nd] = max(seg[nd * 2], seg[nd * 2 + 1]);
  }
  void upd(int p, int v) {
    upd(1, 0, n - 1, p, v);
  }
  int get(int nd, int l, int r, int x, int y) {
    if (x <= l && r <= y) {
      return seg[nd];
    }
    if (l > y || r < x) {
      return 0;
    }
    int mid = (l + r) >> 1;
    return max(get(nd * 2, l, mid, x, y), get(nd * 2 + 1, mid + 1, r, x, y));
  }
  int get(int x, int y) {
    return get(1, 0, n - 1, x, y);
  }
};

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int n, d;
  cin >> n >> d;
  map<int, vector<int>> where;
  for (int i = 0; i < n; i++) {
    int a;
    cin >> a;
    where[a].push_back(i);
  }
  dsu D(n);
  segtree st(n);
  set<int> s;
  int ans = 0;
  for (auto [x, y] : where) {
    vector<pair<int, int>> res;
    vector<pair<int, int>> merge;
    for (int z : y) {
      auto it = s.upper_bound(z);
      int m = z;
      if (it != s.end()) {
        if (*it - z <= d) {
          m = min(m, D.get_min(*it));
          merge.emplace_back(*it, z);
        }
      }
      if (it != s.begin()) {
        it = prev(it);
        if (z - *it <= d) {
          m = min(m, D.get_min(*it));
          merge.emplace_back(*it, z);
        }
      }
      int dp = st.get(m, z) + 1;
      res.emplace_back(z, dp);
      ans = max(ans, dp);
    }
    for (int z : y) {
      s.insert(z);
    }
    while (!res.empty()) {
      st.upd(res.back().first, res.back().second);
      res.pop_back();
    }
    while (!merge.empty()) {
      D.unite(merge.back().first, merge.back().second);
      merge.pop_back();
    }
  }
  cout << ans << '\n';
  return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...