分析
1.其实是道“简单”的模拟题~
2.要点:
(1)找到最小数并删除
(2)每次删除时,将其左右两侧数加上它
(3)求经过k次操作后,剩余的数
代码
#include<bits/stdc++.h> //要加的头文件太多了,直接万能
using namespace std;
typedef pair<long long,int> PII; //第一个数表示元素,根据数据范围,用longlong;第二个数表示下标
const int N = 500010;
priority_queue<PII,vector<PII>,greater<PII> > q; //优先队列(小根堆)
int pre[N],ne[N]; //记录元素前后下标
long long cnt[N],a[N];
int n,k;
int main()
{
scanf("%d %d",&n,&k);
for(int i = 1;i <= n;i ++)
{
long long x;
scanf("%lld",&x);
q.push({x,i});
pre[i] = i - 1;
ne[i] = i + 1;
}
while(q.size() > n - k)
{
PII t = q.top();
long long x = t.first;
int id = t.second;
if(cnt[id])
{
q.pop();
q.push({x+cnt[id],id});
cnt[id] = 0;
}
else
{
q.pop();
int l = pre[id],r = ne[id];
cnt[l] += x;
cnt[r] += x;
ne[l] = r;
pre[r] = l;
}
}
while(q.size()){
long long x=q.top().first;
int id=q.top().second;
q.pop();
a[id]=x+cnt[id];
}
for(int i=1;i<=n;i++){
if(a[i]) cout<<a[i]<<" ";
}
return 0;
}