如题,代码如下:
#include<stdio.h>
#define max(a,b) (a>b?a:b)
int rk[500010];/*若为区间端点则保存对应节点在堆中下标*/
struct T{
long long v;//节点值
int lid;//每个节点对应左端点
int rid;//每个节点对应右端点
int siz;//选择该节点种的树的棵树
};
struct T t[500010];
void maxheapify(int o,int m)
{
int l=o<<1;
int r=o<<1|1;
int ind=o;
if(l<=m&&t[l].v>t[ind].v)ind=l;
if(r<=m&&t[r].v>t[ind].v)ind=r;
if(ind!=o){
rk[t[ind].lid]=rk[t[ind].rid]=o;
rk[t[o].lid]=rk[t[o].rid]=ind;
struct T tt=t[o];
t[o]=t[ind];
t[ind]=tt;
maxheapify(ind,m);
}
}
void update(int o)
{
int f=o>>1;
if(f>=1&&t[f].v<t[o].v){
rk[t[f].lid]=rk[t[f].rid]=o;
rk[t[o].lid]=rk[t[o].rid]=f;
struct T tt=t[o];
t[o]=t[f];
t[f]=tt;
update(o);
}
}
int del(int o,int m)
{
if(o==m)return m-1;
if(t[o].v>t[m].v){
t[o]=t[m];
rk[t[m].lid]=rk[t[m].rid]=o;
maxheapify(o,--m);
}
else{
t[o]=t[m];
rk[t[m].lid]=rk[t[m].rid]=o;
update(o);
--m;
}
return m;
}
int main()
{
//freopen("P1484_4.in","r",stdin);
int n,k;
int m;
scanf("%d%d",&n,&k);
m=n;
for(int i=1;i<=n;i++){
rk[i]=t[i].lid=t[i].rid=i;
scanf("%lld",&t[i].v);
t[i].siz=1;
}
for(int i=m>>1;i>=1;i--){
maxheapify(i,m);
}
long long ans=0,num=0,tans=0;
struct T tt1,tt2;
while(1){
if(m<=1)break;
ans+=t[1].v;
num+=t[1].siz;
if(num<=k)tans=max(ans,tans);
if(t[1].lid-1>=1){
tt1=t[rk[t[1].lid-1]];
m=del(rk[t[1].lid-1],m);
}
else tt1=t[0];
if(t[1].rid+1<=n){
tt2=t[rk[t[1].rid+1]];
m=del(rk[t[1].rid+1],m);
}
else tt2=t[0];
t[1].siz*=-1;
t[1].v*=-1;
if(tt1.lid){
t[1].siz+=tt1.siz;
t[1].v+=tt1.v;
t[1].lid=tt1.lid;
rk[t[1].lid]=1;
}
if(tt2.lid){
t[1].siz+=tt2.siz;
t[1].v+=tt2.v;
t[1].rid=tt2.rid;
rk[t[1].rid]=1;
}
maxheapify(1,m);
}
printf("%lld",tans);
}