我的想法:每次贪心求出当前最优后,删除当前点,并插入一个新点,点权就是题解的那样,以此用来反悔。当优先队列中的最大值已经是负数了,就没有必要选点了,就break掉
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=5e5+5;
int n,k,a[N<<1],cnt,ans;
int l[N<<1],r[N<<1],vis[N<<1];
struct IloveCCF{
int id,val;
bool operator <(const IloveCCF &x) const{
return val<x.val;
}
}node[N<<1];
priority_queue<IloveCCF> q;
inline int read(){
int ans=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-f;ch=getchar();}
while(isdigit(ch)){ans=(ans<<3)+(ans<<1)+ch-'0';ch=getchar();}
return ans*f;
}
signed main(){
cnt=n=read(),k=read();
for(int i=1;i<=n;i++){
a[i]=read();
l[i]=i-1,r[i]=i+1;
q.push((IloveCCF){i,a[i]});
}
r[n]=1;l[1]=n;
for(int i=1;i<=k;i++){
while(vis[q.top().id]) q.pop();
int id=q.top().id,val=q.top().val;
q.pop();
if(val<0) break;
ans+=val;
++cnt;
vis[l[id]]=vis[r[id]]=1;
l[r[r[id]]]=cnt,r[l[l[id]]]=cnt;
l[cnt]=l[l[id]],r[cnt]=r[r[id]];
a[cnt]=a[l[id]]+a[r[id]]-val;
q.push((IloveCCF){cnt,a[cnt]});
}
printf("%lld",ans);
return 0;
}
n=3e5,k=8e4的点挂掉了
我输出66833080378
标程输出66833112691