This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
using ld = long double;
ld eps = 0.000001d;
int n, d, t, v[2000005], k[2000005];
int bad;
struct copacel
{
ld val = 0;
int cate = 0;
};
copacel dp[2000005];
int sz[2000005];
vector<int> f[2000005];
ld c;
void dfs(int nod)
{
for (auto fiu : f[nod])
dfs(fiu);
copacel var1, var2;
var1.cate = 1;
var1.val = c;
for (auto fiu : f[nod])
{
if (dp[fiu].val < sz[fiu])
{
var1.cate += dp[fiu].cate;
var1.val += dp[fiu].val;
}
else
var1.val += sz[fiu];
}
if (f[nod].empty())
{
dp[nod] = var1;
return;
}
var2.val = var2.cate = 0;
ld mindif = 1e9;
for (auto fiu : f[nod])
mindif = min(mindif, dp[fiu].val - min(dp[fiu].val, (ld)sz[fiu]));
bool tkn = false;
for (auto fiu : f[nod])
{
if (!tkn and dp[fiu].val - min(dp[fiu].val, (ld)sz[fiu]) == mindif)
{
tkn = true;
var2.cate += dp[fiu].cate;
var2.val += dp[fiu].val;
}
else
{
if (dp[fiu].val < sz[fiu])
{
var2.cate += dp[fiu].cate;
var2.val += dp[fiu].val;
}
else
var2.val += sz[fiu];
}
}
if (var1.val <= var2.val)
dp[nod] = var1;
else
dp[nod] = var2;
}
void solve(ld cost)
{
c = cost;
memset(dp, 0, sizeof(dp));
dfs(1);
}
void ufuf(int nod)
{
sz[nod] = 1;
for (auto fiu : f[nod])
{
ufuf(fiu);
sz[nod] += sz[fiu];
}
}
void build_tree()
{
vector<pair<int,int>> ranges;
for (int i = 1; i <= n; i++)
{
int j;
for (j = i; j >= 1; j--)
{
if (v[j] + i - j <= t)
break;
}
if (j == i)
bad++;
else if (j != 0)
ranges.push_back({j, i - 1});
}
if (ranges.empty())
{
n = 0;
return;
}
ranges.push_back({1, n});
sort(ranges.begin(), ranges.end(), [](pair<int,int> A, pair<int,int> B){
if (A.first != B.first)
return A.first < B.first;
return A.second > B.second;
});
n = ranges.size();
stack<int> stk;
stk.push(1);
for (int i = 1; i < n; i++)
{
while (ranges[stk.top() - 1].second < ranges[i].first)
stk.pop();
f[stk.top()].push_back(i + 1);
stk.push(i + 1);
}
ufuf(1);
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> n >> d >> t;
for (int i = 1; i <= n; i++)
cin >> v[i];
for (int i = 1; i <= n; i++)
k[i] = v[i] - i;
build_tree();
if (n - 1 <= d)
{
cout << bad;
return 0;
}
ld st = n, pas = (ld)(1 << 20);
while (pas >= eps)
{
if (st - pas >= 1)
{
solve(st - pas);
if (dp[1].val > sz[1] or dp[1].cate <= d)
st -= pas;
}
pas /= 2.0d;
}
solve(st);
ld ans = (ld)n - (dp[1].val + (ld)d * st);
int aa = ans;
if (ans - (ld)aa >= 0.5d)
aa++;
cout << aa + bad;
return 0;
}
/**
yeah so aliens pe fata
pentru i, imi fac un interval de tipul: "daca pun aici un gate nu o sa se mai revolte i"
in fine, astea au structura de arbore din fericire, deci dupa ce imi fac arborele si aliens, e doar un dp[nod][0/1]
**/
Compilation message (stderr)
prison.cpp: In function 'void solve(ld)':
prison.cpp:78:29: warning: 'void* memset(void*, int, size_t)' clearing an object of non-trivial type 'struct copacel'; use assignment or value-initialization instead [-Wclass-memaccess]
78 | memset(dp, 0, sizeof(dp));
| ^
prison.cpp:12:8: note: 'struct copacel' declared here
12 | struct copacel
| ^~~~~~~
# | 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... |