题面
分析
首先,本题数据量较大(1
⩽
\leqslant
⩽
n
,
k
n,k
n,k
⩽
\leqslant
⩽
1
0
5
10^{5}
105),暴力是不可能暴力的。
不难看出,
k
k
k次操作无法避免,因此要减少找出
x
x
x并将所有元素减去
x
x
x的时间。具体的方式:
- c n t cnt cnt数组记录 x x x的总和,用 a i a_{i} ai原本的值减去当前 c n t cnt cnt的值就是当前操作后 a i a_{i} ai的值,省去全部减 x x x的时间。
- 用一个从小到大的优先队列 q q q储存 a a a,当 a i − c n t ⩽ 0 a_{i}-cnt\leqslant0 ai−cnt⩽0直接 p o p pop pop, x x x就是q.top(),省去查找时间。
代码
#include <iostream>
#include <queue>
using namespace std;
const int N=10010;
int n,k,x,cnt;
priority_queue<int, vector<int>, greater<int> >q;//注意要加空格,不然会被报错
int main()
{
cin>>n>>k;
for(int i=0;i<n;i++)
{
cin>>x;
if(x!=0) q.push(x);//已经是0了就不用管了
}
while(k--)
{
if(q.empty()) cout<<0<<endl;//没有非零的了就输出0
else//注意下面三行的顺序,不能颠倒
{
cout<<q.top()-cnt<<endl;//注意是q.top()不是q.front(),因为优先队列的原理是堆,堆顶“顶”就是top
cnt+=q.top()-cnt;
while(q.top()-cnt<=0&&!q.empty()) q.pop();//一定要记得判断q为不为空,不然会死循环
}
}
return 0;
}