Submission #659389

#TimeUsernameProblemLanguageResultExecution timeMemory
659389600MihneaThe short shank; Redemption (BOI21_prison)C++17
35 / 100
2083 ms65112 KiB
#include <bits/stdc++.h>

using namespace std;

const int N = 2000000 + 7;
const int INF = (int) 1e9 + 7;
int n;
int d;
int t;
int trebel[N];
bool block[N];
int gain[N];
int ant[N];
bool valid[N];
set<int> valids;

pair<int, int> tree_min_valid[4 * N];

void st_valid(int v, int tl, int tr, int i, int x) {
  if (tr < i || i < tl) {
    return;
  }
  if (tl == tr) {
    assert(tl == i);
    assert(tr == i);
    tree_min_valid[v] = {x, i};
    return;
  }
  int tm = (tl + tr) / 2;
  st_valid(2 * v, tl, tm, i, x);
  st_valid(2 * v + 1, tm + 1, tr, i, x);
  tree_min_valid[v] = min(tree_min_valid[2 * v], tree_min_valid[2 * v + 1]);
}

pair<int, int> get_min_valid(int v, int tl, int tr, int l, int r) {
  if (tr < l || r < tl) {
    return {INF, -1};
  }
  if (l <= tl && tr <= r) {
    return tree_min_valid[v];
  }
  int tm = (tl + tr) / 2;
  return min(get_min_valid(2 * v, tl, tm, l, r), get_min_valid(2 * v + 1, tm + 1, tr, l, r));
}

int main() {
  ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

  //freopen ("input.txt", "r", stdin);

  for (int i = 0; i < 4 * N; i++) {
    tree_min_valid[i] = {INF, -1};
  }

  cin >> n >> d >> t;
  for (int i = 1; i <= n; i++) {
    cin >> trebel[i];
  }

  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= i; j++) {
      if (trebel[j] + i - j <= t) {
        ant[i] = j;
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    valid[i] = (ant[i] > 0);
    if (valid[i]) {
      st_valid(1, 1, n, i, ant[i]);
    }
  }
  for (int j = 1; j <= n; j++) {
    if (valid[j]) {
      gain[ant[j]]++;
      gain[j]--;
    }
  }
  for (int i = 1; i <= n; i++) {
    gain[i] += gain[i - 1];
  }

  for (int iqd = 1; iqd <= d; iqd++) {
    for (int i = 1; i < n; i++) {
      gain[i] = 0;
    }
    for (int j = 1; j <= n; j++) {
      if (valid[j]) {
        gain[ant[j]]++;
        gain[j]--;
      }
    }
    for (int i = 1; i <= n; i++) {
      gain[i] += gain[i - 1];
    }
    int mx = -1, jj = -1;
    for (int i = 1; i < n; i++) {
      if (!block[i]) {
        if (gain[i] >= mx) {
          mx = gain[i];
          jj = i;
        }
      }
    }
    assert(1 <= jj && jj < n);
    block[jj] = 1;
    while (1) {
      auto it = get_min_valid(1, 1, n, jj + 1, n);
      int j = it.second;
      if (it.first <= jj) {
        assert(it.first == ant[j]);
        valid[j] = 0;
        st_valid(1, 1, n, j, INF);
      } else {
        break;
      }
    }
    for (int j = 1; j <= n; j++) {
      if (ant[j] <= jj && jj < j) {
        if (valid[j] == 1) {
          cout << "error!\n";
          cout << j << " needs to be invalid\n";
          exit(0);
        }
        assert(valid[j] == 0);
      }
    }
  }
  int sol = 0;
  for (int i = 1; i <= n; i++) {
    sol += valid[i];
  }
  cout << sol << "\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...