https://codeforces.com/gym/104128/problem/D
要解决这道题目需要使用到二分答案,二分第k大元素值,首先分析如何二分答案的可行性
while (l + 1 < r) {
//l越大,res越小,能够凑成
ll mid = (l + r) / 2;
if (check(mid)>=k)l = mid;
else r = mid;
}
mid是我们假设的最大的数组中的第k大元素,我们先不考虑选择哪个长为m的子数组并给他对应的元素加上一个排列,我们假设已经通过某些方式得到了已经处理好的数组(最优处理),我们暂且把它称为数组{b},然后很容易知道数组{b}中至少有tmp(tmp用来表示数组中大于等于mid的元素个数)个元素大于等于mid,而最后实际的第k大元素,在数组{b}中刚好有k个元素大于等于第k大元素,这时就可以判断如果tmp>=k说明mid选小了或者刚好相等,因为数组{b}中的每个元素大小是不会变的,你选的mid越小,那么tmp的大小就越大,所以让l=mid,反之如果tmp<k,那么说明选大了,让r=mid.
到此二分的可行性就分析完了,我们该考虑如何才能够在On的时间复杂度内找到这个tmp.接下来我会先把check的代码贴出来来然后逐步分析.
ll n, k, m, c, d;
std::cin >> n >> k >> m >> c >> d;
std::vector<ll>a(n+2);
for (int i = 1; i <= n; i++)std::cin >> a[i];
ll l = -1, r = 1e18;
st

最低0.47元/天 解锁文章
1450

被折叠的 条评论
为什么被折叠?



