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);
}
posted @ 2021-04-09 19:56  TRTTG  阅读(90)  评论(0编辑  收藏  举报