51nod 1115 最大M子段和 V3
http://www.51nod.com/Challenge/Problem.html#problemId=1115
在V2的基础上,把首尾连起来
V2:https://www.cnblogs.com/TheRoadToTheGold/p/14635002.html
注意如果首尾是同符号,要合并成一个。
#include<queue>
#include<cstdio>
#include<algorithm>
using namespace std;
#define N 500003
int a[N];
long long c[N];
int l[N],r[N];
bool tra[N];
struct cmp
{
bool operator () (const int x,const int y)
{
return abs(c[x])>abs(c[y]);
}
};
priority_queue<int,vector<int>,cmp>q;
int main()
{
int n,m,k=0,p=0;
long long s=0,ans=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
bool tag=1;
for(int i=1;i<=n;++i)
if(1ll*a[i]*a[i-1]<0)
{
if(s>0)
{
ans+=s;
++p;
}
c[++k]=s;
s=a[i];
}
else s+=a[i];
if(s>0)
{
ans+=s;
if(c[1]<0) ++p;
}
if(s)
{
if(c[1]*s<0) c[++k]=s;
else c[1]+=s;
}
l[1]=k;
r[1]=2;
q.push(1);
for(int i=2;i<k;++i)
{
l[i]=i-1;
r[i]=i+1;
q.push(i);
}
l[k]=k-1;
r[k]=1;
q.push(k);
int le=p-m;
if(le<=0)
{
printf("%lld",ans);
return 0;
}
int now;
while(1)
{
now=q.top();
q.pop();
if(tra[now]) continue;
if(c[now]<=0 && (!l[now] || !r[now])) continue;
ans-=abs(c[now]);
//printf("-----%lld\n",ans);
c[now]+=c[l[now]]+c[r[now]];
tra[l[now]]=true;
l[now]=l[l[now]];
r[l[now]]=now;
tra[r[now]]=true;
r[now]=r[r[now]];
l[r[now]]=now;
q.push(now);
--le;
if(!le) break;
}
printf("%lld",ans);
}