L. *【链表+堆】序列m个连续和最大[CH1812]生日礼物

    传统题 1000ms 64MiB

*【链表+堆】序列m个连续和最大[CH1812]生日礼物

该比赛已结束,您无法在比赛模式下递交该题目。您可以点击“在题库中打开”以普通模式查看和递交本题。

Description

0x10基本数据结构(练习)13:生日礼物[CH1812] ## 【题意】 从 $N$ 个元素的序列 $A_i$ 中选择不超过 $M$ 个连续的部分,使得所选元素之和最大。

【输入格式】

第一行两个整数 N,M(0 \le N,M \le 10^5)

第二行 NN 个整数 Ai(Ai104)A_i(|A_i| \le 10^4)

【输出格式】

输出一个整数,表示答案。

【输入样例】

5 2
2 -3 2 -1 2

【输出样例】

5

Hint

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,int> PLI;
const int N=1e5+100;
LL a[N];
int L[N],R[N],del[N];
priority_queue<PLI,vector<PLI>,greater<PLI>> q;
void remove(int x)
{
    L[R[x]]=L[x];
    R[L[x]]=R[x];
    del[x]=1;
}
int main()
{
    int n,m;scanf("%d%d",&n,&m);
    int k=0;
    for(int i=1;i<=n;i++)
	{
        LL x;scanf("%lld",&x);
        if(x!=0)
		{
            if(!k||a[k]*x<0)a[++k]=x;
            else a[k]+=x;
        }
    }
    n=k;
    LL ans=0,cnt=0;
    for(int i=1;i<=n;i++)
	{
        L[i]=i-1,R[i]=i+1;
        q.push({abs(a[i]),i});
        if(a[i]>0)ans+=a[i],cnt++;
    }
    memset(del,0,sizeof(del));
    while(cnt>m)
	{
        while(del[q.top().second])q.pop();
        PLI no=q.top();q.pop();
        int x=no.second;
        if(a[x]>0||(L[x]!=0&&R[x]!=n+1))
		{
            ans-=abs(a[x]);
            a[x]+=a[L[x]]+a[R[x]];
            q.push({abs(a[x]),x});
			remove(L[x]);
			remove(R[x]);
            cnt--;
        }
    }
    printf("%d",ans);
    return 0;
}

Source

J9

入门8.5(进制转换+链表模拟+队列模拟)

未参加
状态
已结束
规则
XCPC
题目
14
开始于
2024-8-1 0:00
结束于
2024-8-10 4:00
持续时间
220 小时
主持人
参赛人数
25