This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
// Sylwia Sapkowska
#include <bits/stdc++.h>
#pragma GCC optimize("O3", "unroll-loops")
using namespace std;
void __print(int x) { cerr << x; }
void __print(long long x) { cerr << x; }
void __print(long double x) { cerr << x; }
void __print(char x) { cerr << '\'' << x << '\''; }
void __print(const char *x) { cerr << '\"' << x << '\"'; }
void __print(const string &x) { cerr << '\"' << x << '\"'; }
void __print(bool x) { cerr << (x ? "true" : "false"); }
template <typename T, typename V>
void __print(const pair<T, V> &x)
{
cerr << '{';
__print(x.first);
cerr << ", ";
__print(x.second);
cerr << '}';
}
template <typename T>
void __print(const T &x)
{
int f = 0;
cerr << '{';
for (auto &i : x)
cerr << (f++ ? ", " : ""), __print(i);
cerr << "}";
}
void _print() { cerr << "]\n"; }
template <typename T, typename... V>
void _print(T t, V... v)
{
__print(t);
if (sizeof...(v)) cerr << ", ";
_print(v...);
}
#ifdef LOCAL
#define debug(x...) \
cerr << "[" << #x << "] = ["; \
_print(x)
#else
#define debug(x...)
#endif
typedef pair<int, int> T;
const int oo = 1e9 + 7;
struct TreeMin {
vector<T> tab;
int size = 1;
TreeMin(int n, vector<int> &a)
{
while (size < n)
size *= 2;
tab.assign(2 * size, {oo, oo});
for (int i = 1; i < (int)a.size(); i++)
tab[i + size] = {a[i], i};
for (int i = size - 1; i >= 1; i--)
tab[i] = min(tab[2 * i], tab[2 * i + 1]);
}
T query(int l, int r)
{
T ans = {oo, oo};
for (l += size - 1, r += size + 1; r - l > 1; l /= 2, r /= 2) {
if (!(l & 1)) ans = min(ans, tab[l + 1]);
if (r & 1) ans = min(ans, tab[r - 1]);
}
return ans;
}
void update(int x)
{
x += size;
tab[x] = {oo, oo};
while (x) {
x /= 2;
tab[x] = min(tab[2 * x], tab[2 * x + 1]);
}
}
};
struct Tree {
vector<int> tab, lazy;
int size = 1;
Tree(int n)
{
while (size < n)
size *= 2;
tab.assign(2 * size, 0);
lazy.assign(2 * size, 0);
}
void update(int x, int lx, int rx, int l, int r, int v)
{
if (lx > r || rx < l) return;
if (lx >= l && rx <= r) {
tab[x] += v;
lazy[x] += v;
return;
}
if (lx != rx) push(x);
int m = (lx + rx) / 2;
update(2 * x, lx, m, l, r, v);
update(2 * x + 1, m + 1, rx, l, r, v);
tab[x] = max(tab[2 * x], tab[2 * x + 1]);
}
void push(int x)
{
if (!lazy[x]) return;
tab[2 * x] += lazy[x];
tab[2 * x + 1] += lazy[x];
lazy[2 * x] += lazy[x];
lazy[2 * x + 1] += lazy[x];
lazy[x] = 0;
}
int find(int x, int lx, int rx)
{
if (lx == rx) return lx;
push(x);
int m = (lx + rx) / 2;
if (tab[2 * x] < tab[2 * x + 1]) return find(2 * x + 1, m + 1, rx);
return find(2 * x, lx, m);
}
};
namespace fastio {
static constexpr int SZ = 1 << 17;
char ibuf[SZ], obuf[SZ];
int pil = 0, pir = 0, por = 0;
struct Pre {
char num[40000];
constexpr Pre() : num()
{
for (int i = 0; i < 10000; i++) {
int n = i;
for (int j = 3; j >= 0; j--) {
num[i * 4 + j] = n % 10 + '0';
n /= 10;
}
}
}
} constexpr pre;
inline void load()
{
memcpy(ibuf, ibuf + pil, pir - pil);
pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
pil = 0;
}
inline void flush()
{
fwrite(obuf, 1, por, stdout);
por = 0;
}
inline void rd(char &c) { c = ibuf[pil++]; }
template <typename T>
inline void rd(T &x)
{
if (pil + 32 > pir) load();
char c;
do
c = ibuf[pil++];
while (c < '-');
x = 0;
while (c >= '0') {
x = x * 10 + (c & 15);
c = ibuf[pil++];
}
}
inline void rd() {}
template <typename Head, typename... Tail>
inline void rd(Head &head, Tail &...tail)
{
rd(head);
rd(tail...);
}
struct Dummy {
Dummy() { atexit(flush); }
} dummy;
} // namespace fastio
using fastio::rd;
void solve()
{
int n, d, tt;
rd(n, d, tt);
vector<int> prev(n + 1, oo);
stack<int> s;
vector<int> t(n + 1);
for (int i = 1; i <= n; i++)
rd(t[i]);
for (int i = 1; i <= n; i++) {
s.push(i);
while ((int)s.size() && s.top() - t[s.top()] < i - tt)
s.pop();
if ((int)s.size()) prev[i] = s.top();
}
debug(prev);
TreeMin tmin(n + 2, prev);
Tree tans(n + 1);
for (int i = 1; i <= n; i++) {
if (prev[i] <= i) {
debug(prev[i], i);
tans.update(1, 0, tans.size - 1, prev[i], i, 1);
}
}
while (d--) {
int x = tans.find(1, 0, tans.size - 1);
debug(x);
bool any = 0;
while (1) {
T now = tmin.query(x + 1, n + 1);
if (now.first > x) break;
debug(now);
tans.update(1, 0, tans.size - 1, now.first, now.second, -1);
tmin.update(now.second);
prev[now.second] = oo;
any = 1;
}
if (!any) break;
}
int ans = 0;
debug(prev);
for (int i = 1; i <= n; i++)
if (prev[i] != oo) ans++;
cout << ans << "\n";
}
int32_t main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
solve();
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |