用双向链表维护可反悔贪心。
当堆顶<0后直接break。
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e5+5;
int n,m,ans;
int a[N],l[N],r[N];
bool vis[N];
struct node
{
int id,v;
inline bool operator < (const node &x) const
{
return x.v>v;
}
};
priority_queue<node>q;
signed main(){
scanf("%lld%lld",&n,&m);
for (register int i=1; i<=n; ++i) scanf("%lld",&a[i]);
for (register int i=1; i<=n; ++i) l[i]=i-1,r[i]=i+1;
for (register int i=1; i<=n; ++i) q.push((node){i,a[i]});
while (m--)
{
while (vis[q.top().id]) q.pop();
if (q.top().v<0) break;
node u=q.top(); q.pop();
ans+=u.v;
a[u.id]=a[l[u.id]]+a[r[u.id]]-u.v;
q.push((node){u.id,a[u.id]});
vis[l[u.id]]=vis[r[u.id]]=true;
l[u.id]=l[l[u.id]]; r[u.id]=r[r[u.id]];
r[l[u.id]]=u.id; l[r[u.id]]=u.id;
}
printf("%lld\n",ans);
return 0;
}