集合操作(双指针,贪心)
题意
给定一个由正整数(最初为空)组成的多重集。多重集表示可能存在重复元素的集合。
请你对该集合执行次操作,操作分为两种:
- 增加操作,格式为
1 x
,将一个正整数加入到集合中。数据保证,不小于当前中的任何元素。 - 询问操作,格式为
2
,找到一个当前的子集,要求的值应尽可能大,输出的最大可能值。表示中最大元素的值,表示中所有元素的平均值。
题目链接:https://www.acwing.com/problem/content/4505/
数据范围
思路
这里给出三条结论,不进行详细证明了(好像也不难证):
-
集合中的元素一定包含新加入的元素,以及最小的个元素
-
最终答案关于的函数一定是先增后减的
-
新加入元素之后,最优的是不减的。
因此,用一个指针指向,维护使得均值最小的。
详细证明见:https://www.acwing.com/solution/content/128919/
代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
typedef long long ll;
const int N = 500010;
int n;
ll a[N];
int cnt;
int main()
{
scanf("%d", &n);
double s = 0;
int k = 0, op;
while(n --) {
scanf("%d", &op);
if(op == 1) {
int x;
scanf("%d", &x);
cnt ++, a[cnt] = x;
}
else {
while(k + 1 <= cnt && (s + a[cnt]) / (k + 1) > a[k + 1]) {
k ++;
s += a[k];
}
printf("%.6f\n", a[cnt] - (s + a[cnt]) / (k + 1));
}
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通