$n \leq 50000$的序列,问选不超过$m \leq 50000$个区间使得和最大。

如果正数区间总数比$m$小那肯定全选。否则有两种方式减少区间数量:丢掉一个正区间;补一个负区间连接两个正区间。贪心即可。

先把左右端的负数去掉,然后把正区间和负区间处理出来。优先队列维护区间值,然后开个链表模拟合并(删左右,改自己)。注意删右边时调整右端点。

 //#include<iostream>
#include<cstring>
#include<cstdio>
//#include<time.h>
//#include<complex>
//#include<set>
#include<queue>
//#include<vector>
#include<algorithm>
#include<stdlib.h>
using namespace std; #define LL long long
int qread()
{
char c; int s=,f=; while ((c=getchar())<'' || c>'') (c=='-') && (f=-);
do s=s*+c-''; while ((c=getchar())>='' && c<=''); return s*f;
} //Pay attention to '-' , LL and double of qread!!!! int n,m;
#define maxn 50011
#define LL long long LL Abs(LL x) {return x>?x:-x;} int a[maxn]; LL sum[maxn];
int b[maxn],lb,ll[maxn],rr[maxn]; bool vis[maxn];
struct qnode
{
LL v; int id;
bool operator > (const qnode &b) const {return v>b.v;}
};
priority_queue<qnode,vector<qnode>,greater<qnode> > q;
int main()
{
n=qread(); m=qread();
for (int i=;i<=n;i++) a[i]=qread();
{
int L=,R=n; while (a[L]<=) L++; while (a[R]<=) R--;
for (int i=L,j=;i<=R;i++,j++) a[j]=a[i];
n=R-L+; a[n+]=;
}
for (int i=;i<=n;i++) sum[i]=sum[i-]+a[i]; LL ans=;
int cnt=;
{
LL tmp=a[],last=;
for (int i=;i<=n+;i++)
{
if (tmp> && a[i]<=)
{
b[++lb]=last;
q.push((qnode){tmp,lb});
ans+=tmp; cnt++; tmp=a[i]; last=i;
}
else if (tmp> && a[i]>) tmp+=a[i];
else if (tmp<= && a[i]>)
{
b[++lb]=last;
q.push((qnode){-tmp,lb});
tmp=a[i]; last=i;
}
else tmp+=a[i];
}
} for (int i=;i<=lb+;i++) ll[i]=i-,rr[i]=i+; b[lb+]=n+;
if (cnt<=m) {printf("%lld\n",ans); return ;}
while (m<cnt--)
{
while (vis[q.top().id]) q.pop();
ans-=q.top().v; int now=q.top().id; q.pop(); if (ll[now]==)
{
vis[rr[now]]=;
vis[now]=;
int u=rr[now]; ll[rr[now]]=ll[now]; rr[ll[now]]=rr[now];
ll[rr[u]]=ll[u]; rr[ll[u]]=rr[u];
}
else if (rr[now]==lb+)
{
vis[ll[now]]=;
vis[now]=;
int u=ll[now]; ll[rr[now]]=ll[now]; rr[ll[now]]=rr[now];
ll[rr[u]]=ll[u]; rr[ll[u]]=rr[u]; b[lb+]=b[u];
}
else
{
int L=b[ll[now]],R=b[rr[rr[now]]]-;
vis[ll[now]]=; vis[rr[now]]=; int u=ll[now],v=rr[now];
b[now]=L; q.push((qnode){Abs(sum[R]-sum[L-]),now});
ll[rr[u]]=ll[u]; rr[ll[u]]=rr[u];
ll[rr[v]]=ll[v]; rr[ll[v]]=rr[v];
}
} printf("%lld\n",ans);
return ;
}

51nod1053 最大M子段和 V2的更多相关文章

  1. 51Nod1053 最大M子段和V2 二分+DP

    传送门 直接DP的话最多也只能做到\(O(nm)\),对于\(5\times 10^4\)的数据范围实在无能为力 夹克老爷提供的做法是贪心,思想大概是在调整的同时,合理构造每个选择对应的新状态,使得新 ...

  2. 最大M子段和 V2

    51nod1053 这题还是我们熟悉的M子段和,只不过N,M<=50000. 这题似乎是一个堆+链表的题目啊 开始考虑把所有正数负数锁在一起. 比如: 1 2 3 -1 –2 -3 666 缩成 ...

  3. 51nod 1053 最大M子段和 V2

    N个整数组成的序列a[1],a[2],a[3],…,a[n],将这N个数划分为互不相交的M个子段,并且这M个子段的和是最大的.如果M >= N个数中正数的个数,那么输出所有正数的和. 例如:-2 ...

  4. [51nod1254]最大子段和 V2

    N个整数组成的序列a[1],a[2],a[3],-,a[n],你可以对数组中的一对元素进行交换,并且交换后求a[1]至a[n]的最大子段和,所能得到的结果是所有交换中最大的.当所给的整数均为负数时和为 ...

  5. 51nod 1254 最大子段和 V2 ——单调栈

    N个整数组成的序列a[1],a[2],a[3],…,a[n],你可以对数组中的一对元素进行交换,并且交换后求a[1]至a[n]的最大子段和,所能得到的结果是所有交换中最大的.当所给的整数均为负数时和为 ...

  6. 51nod 1254 最大子段和 V2

    N个整数组成的序列a[1],a[2],a[3],…,a[n],你可以对数组中的一对元素进行交换,并且交换后求a[1]至a[n]的最大子段和,所能得到的结果是所有交换中最大的.当所给的整数均为负数时和为 ...

  7. 51nod1524 最大子段和V2

    题干 N个整数组成的序列a[1],a[2],a[3],-,a[n],你可以对数组中的一对元素进行交换,并且交换后求a[1]至a[n]的最大子段和,所能得到的结果是所有交换中最大的.当所给的整数均为负数 ...

  8. 51nod1254 最大子段和 V2 DP

    ---题面--- 题解: 表示今天做题一点都不顺.... 这题也是看了题解思路然后自己想转移的. 看的题解其实不是这道题,但是是这道题的加强版,因为那道题允许交换k对数. 因为我们选出的是连续的一段, ...

  9. 51Nod 最大M子段和系列 V1 V2 V3

    前言 \(HE\)沾\(BJ\)的光成功滚回家里了...这堆最大子段和的题抠了半天,然而各位\(dalao\)们都已经去做概率了...先%为敬. 引流之主:老姚的博客 最大M子段和 V1 思路 最简单 ...

随机推荐

  1. CSS声明各个浏览器私有属性的命名前缀

    -moz代表firefox浏览器私有属性-ms代表IE浏览器私有属性-webkit代表chrome.safari私有属性-o代表opera私有属性

  2. Objective-C分类 (category)和扩展(Extension) 的区别

    http://blog.csdn.net/yhawaii/article/details/6992094 http://blog.163.com/wangy_0223/blog/static/4501 ...

  3. 团队作业-Beta冲刺第三天

    这个作业属于哪个课程 <https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass1> 这个作业要求在哪里 <https ...

  4. 项目中多条数据保存的json实例

    //js代码function checkCode(num){ var typeid = $("#typeid").val(); if(typeid == "") ...

  5. What is the difference between try/except and assert?

    assert only check if a condition is true or not and throw an exception. A try/except block can run a ...

  6. 使用Microsoft Hadoop(一)

    To run this program, stage some data in HDFS: 1. create a text file called input.txt that has one in ...

  7. java第九次作业:第九章例题3个

    作业1: 例题9.1 制作圆类,根据圆的半径求出周长及面积 package com.swift; //抽象的方法构成类,把属性和方法进行封装 public class Circle { // 两个方面 ...

  8. mysql5.7.22-log 修改远程访问

    正常的设置账号远程访问依然访问不了的情况,可以看一下服务器 my.cnf配置文件下 [client] #password = your_password 把上面的#去掉就行了.

  9. Flask 系列之 构建 Swagger UI 风格的 WebAPI

    说明 操作系统:Windows 10 Python 版本:3.7x 虚拟环境管理器:virtualenv 代码编辑器:VS Code 实验 环境初始化 # 创建项目目录 mkdir helloworl ...

  10. lombok安装、配置、使用

    eclipse安装Lombok 运行安装: java -jar ${path}\lombok.jar 选择IDE所在路径点击Install/Update即可使用. 手动安装1. 将lombok.jar ...