D2. Red-Blue Operations (Hard Version)

题意

给定一个长度为n的数列和q次询问,初始所有数的颜色都是红色,每次询问给一个k,要求你做恰好k次操作,对于第i次操作,你可以任选数列中的一个数

  1. 如果它是红色,则将它的值加上i,并将它变成蓝色
  2. 如果它是蓝色,则将它的值减去i,并将它变为红色

对于每个询问,求k次操作后数列最小值的最大值,1n,q1e51ai1e91ki1e9

题解

如果kn,显然,此时我们可以只加不减,且最优策略显然是把最大的数加到最小的数身上,次大的数加到次小的数身上,以此类推

如果k>n

我们不妨先考虑kn是偶数的情况

首先证明这k次操作一定是++++...+++++这样的序列(加减在哪一个数上还不一定)

证明:我们交换序列中的任一对+,合法的交换一定是减法后移,加法前移(因为一开始所有数都是红色,所以对于序列的任一前缀,加法的数量必须不少于减法),在任一种分配策略下,我们这样交换一定会导致某些数减的更多或加的更少了,一定是不更优的

现在我们考虑这些操作分配给了哪些数,对于目前的最优序列,可以将k次操作分为两部分,后n次全为加法,前kn次可以打包成(kn)/2次操作,每次操作相当于给任意一个数减去1,由于操作的顺序不影响最后答案,我们不妨先做后n次操作

之前已经说明,如果kn,贪心即可,现在我们考虑后面还有若干次减法时,还能不能这样贪心

证明:考虑减法操作结束后,答案为min(),如果我们在n次加法中不按最优策略来,原数列最小值一定不会更大,无论采取什么操作,新数列和的平均值一定,所以其它方案不会比贪心更优

所以,答案为min(n,),直接计算单组询问复杂度是O(n)的,会TLE,考虑如何优化

首先考虑kn时,将原数列从小到大排序,我们本质上求的是min(min1ikai+k+1i,mink+1inai)

显然mink+1inai=ak+1,这里我们可以令bi=aii+1,令mii=min1jibi,可以把上述式子变成求min(mik+k,ak+1),通过O(n)的预处理,我们可以O(1)的回答每组询问

求新数列的和,通过求和公式,显然也可以做到O(1),一点小细节时要注意kn分奇偶讨论,具体公式见代码

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF = 1e18;
const int N = 2e5 + 7;
ll n, q, sum, a[N], mi[N];
ll solve(ll k) {
	if (k <= n) {
		return min(mi[k] + k, a[k + 1]);
	}
	else if ((k - n) % 2) {
		ll op = (k - n + 1) / 2, presum = (k - n + 2 + k) * (n - 1) / 2;
		return min(min(mi[n - 1] + k, a[n]), (sum + presum - op) / n);
	}
	else {
		ll op = (k - n) / 2, presum = (k - n + 1 + k) * n / 2;
		return min(mi[n] + k, (sum + presum - op) / n);
	}
}
int main() {
	scanf("%lld%lld", &n, &q);
	for (ll i = 1; i <= n; ++i) {
		scanf("%lld", &a[i]);
		sum += a[i];
	}
	sort(a + 1, a + 1 + n);
	a[n + 1] = mi[0] = INF;
	for (ll i = 1; i <= n; ++i) {
		mi[i] = min(mi[i - 1], a[i] - i + 1);
	}
	while (q--) {
		ll k;
		scanf("%lld", &k);
		printf("%lld ", solve(k));
	}
	return 0;
}
posted @   DGJG  阅读(41)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示