제출 #589421

#제출 시각아이디문제언어결과실행 시간메모리
589421waynetuinforFinancial Report (JOI21_financial)C++17
100 / 100
608 ms26820 KiB
#include <bits/stdc++.h>
using namespace std;

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  int N, D;
  cin >> N >> D;
  vector<int> A(N);
  for (int i = 0; i < N; ++i) {
    cin >> A[i];
  }
  vector<int> order(N);
  iota(order.begin(), order.end(), 0);
  sort(order.begin(), order.end(), [&](int i, int j) { return A[i] < A[j]; });

  vector<int> uf(N);
  iota(uf.begin(), uf.end(), 0);

  function<int(int)> Find = [&](int x) {
    if (x == uf[x]) return x;
    return uf[x] = Find(uf[x]);
  };

  auto Merge = [&](int x, int y) {
    x = Find(x);
    y = Find(y);
    if (x != y) {
      if (x > y) {
        swap(x, y);
      }
      uf[y] = x;
    }
  };

  set<int> points;
  vector<int> dp(N);

  vector<int> tree(N * 4);

  auto Query = [&](int ql, int qr) {
    auto dfs = [&](auto dfs, int l, int r, int o = 0) -> int {
      if (l >= qr || ql >= r) {
        return 0;
      }
      if (l >= ql && r <= qr) {
        return tree[o];
      }
      int m = (l + r) >> 1;
      return max(dfs(dfs, l, m, o * 2 + 1), dfs(dfs, m, r, o * 2 + 2));
    };

    return dfs(dfs, 0, N);
  };

  auto Update = [&](int p, int v) {
    auto dfs = [&](auto dfs, int l, int r, int o = 0) -> void {
      if (r - l == 1) {
        tree[o] = max(tree[o], v);
        return;
      }
      int m = (l + r) >> 1;
      if (p < m) {
        dfs(dfs, l, m, o * 2 + 1);
      } else {
        dfs(dfs, m, r, o * 2 + 2);
      }
      tree[o] = max(tree[o * 2 + 1], tree[o * 2 + 2]);
    };

    return dfs(dfs, 0, N);
  };

  for (int i = 0, j = 0; i < N; ++i) {
    while (j < N && A[order[j]] < A[order[i]]) {
      auto iter = points.lower_bound(order[j]);
      if (iter != points.end() && *iter - order[j] <= D) {
        Merge(order[j], *iter);
      }
      if (iter != points.begin() && order[j] - *prev(iter) <= D) {
        Merge(*prev(iter), order[j]);
      }
      points.insert(order[j]);
      Update(order[j], dp[j]);
      j++;
    }
    int x = order[i];
    auto iter = points.lower_bound(x);
    if (iter != points.begin() && x - *prev(iter) <= D) {
      x = *prev(iter);
    }
    x = Find(x);
    dp[i] = Query(x, order[i] + 1) + 1;
  }
  cout << *max_element(dp.begin(), dp.end()) << "\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...