CF314A 题解

前言

题目传送门!

更好的阅读体验?

这翻译明显错误,建议大家去原题面看。

简要题意

有一个序列 a1,a2,,an,每次按照公式 di=j=1i1[aj(j1)(ni)ai] 计算。每次再找到最小的 x 满足 dx<k

ax 删除,然后再来一轮。找不到 x 时停止。依次输出所有被删除的数原本的编号

思路

我们想让 di 有承接关系,即,知道 di1 能快速算出 di

这一点还是比较容易的,把 ai 的计算部分提出来即可。di=[j=1i1aj(j1)][(i1)(ni)ai]

也就是说,我们可以计算:xi=j=1i1aj(j1),当前的 di 显然就是 xi(i1)(ni)ai

这样,对于删除操作,我们就不必重新计算榜单了,如果删除掉 i,只需要计算 xi 时忽略掉它

那么代码就十分容易了,直接模拟就行。时间复杂度显然是 O(n)

实际可以直接用一个变量代替 xi,扫一遍就做完了。

完整代码

/*为了代码更通俗,使用了不关同步的 cin 与 cout。不保证在输入输出上会被卡常。*/
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
	int n, k, nowi = 0; //nowi是真正的i
        cin >> n >> k;
	long long d = 0; //由于每个di可以承接地算,所以直接扫一遍即可。删除就是不计算i的贡献入内 
	for (int i = 1; i <= n; i++)
	{
		nowi++;
		int ai; cin >> ai;
		if (d - 1ll * (i - 1) * (n - i) * ai < k) {write(nowi), endl; n--, i--;}
		else d += 1ll * ai * (i - 1);
	}
	return 0;
}

希望能帮助到大家!

posted @   liangbowen  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示