51nod1053 最大M子段和 V2
$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的更多相关文章
- 51Nod1053 最大M子段和V2 二分+DP
传送门 直接DP的话最多也只能做到\(O(nm)\),对于\(5\times 10^4\)的数据范围实在无能为力 夹克老爷提供的做法是贪心,思想大概是在调整的同时,合理构造每个选择对应的新状态,使得新 ...
- 最大M子段和 V2
51nod1053 这题还是我们熟悉的M子段和,只不过N,M<=50000. 这题似乎是一个堆+链表的题目啊 开始考虑把所有正数负数锁在一起. 比如: 1 2 3 -1 –2 -3 666 缩成 ...
- 51nod 1053 最大M子段和 V2
N个整数组成的序列a[1],a[2],a[3],…,a[n],将这N个数划分为互不相交的M个子段,并且这M个子段的和是最大的.如果M >= N个数中正数的个数,那么输出所有正数的和. 例如:-2 ...
- [51nod1254]最大子段和 V2
N个整数组成的序列a[1],a[2],a[3],-,a[n],你可以对数组中的一对元素进行交换,并且交换后求a[1]至a[n]的最大子段和,所能得到的结果是所有交换中最大的.当所给的整数均为负数时和为 ...
- 51nod 1254 最大子段和 V2 ——单调栈
N个整数组成的序列a[1],a[2],a[3],…,a[n],你可以对数组中的一对元素进行交换,并且交换后求a[1]至a[n]的最大子段和,所能得到的结果是所有交换中最大的.当所给的整数均为负数时和为 ...
- 51nod 1254 最大子段和 V2
N个整数组成的序列a[1],a[2],a[3],…,a[n],你可以对数组中的一对元素进行交换,并且交换后求a[1]至a[n]的最大子段和,所能得到的结果是所有交换中最大的.当所给的整数均为负数时和为 ...
- 51nod1524 最大子段和V2
题干 N个整数组成的序列a[1],a[2],a[3],-,a[n],你可以对数组中的一对元素进行交换,并且交换后求a[1]至a[n]的最大子段和,所能得到的结果是所有交换中最大的.当所给的整数均为负数 ...
- 51nod1254 最大子段和 V2 DP
---题面--- 题解: 表示今天做题一点都不顺.... 这题也是看了题解思路然后自己想转移的. 看的题解其实不是这道题,但是是这道题的加强版,因为那道题允许交换k对数. 因为我们选出的是连续的一段, ...
- 51Nod 最大M子段和系列 V1 V2 V3
前言 \(HE\)沾\(BJ\)的光成功滚回家里了...这堆最大子段和的题抠了半天,然而各位\(dalao\)们都已经去做概率了...先%为敬. 引流之主:老姚的博客 最大M子段和 V1 思路 最简单 ...
随机推荐
- poj2104 K大数 划分树
题意:给定一个数列,求一个区间的第K大数 模板题, 其中的newl, newr 有点不明白. #include <iostream> #include <algorithm> ...
- python基础一 day13 复习
# 函数 —— 2天 # 函数的定义和调用 # def 函数名(形参): #函数体 #return 返回值 #调用 函数名(实参) # 站在形参的角度上 : 位置参数,*args,默认参数(陷阱),* ...
- python基础一 day10(1)
要背的:
- Spring对注解(Annotation)处理【转】
1.从Spring2.0以后的版本中,spring也引入了基于注解(Annotation)方式的配置,注解(Annotation)是JDK1.5中引入的一个新特性,用于简化Bean的配置,某些场合可以 ...
- PAT (Basic Level) Practise (中文)-1030. 完美数列(25)
PAT (Basic Level) Practise (中文)-1030. 完美数列(25) http://www.patest.cn/contests/pat-b-practise/1030 给 ...
- OpenCV Haar AdaBoost源码改进据说是比EMCV快6倍
<pre name="code" class="cpp">#include "Haar.h" #include "lo ...
- 目录扫描工具DirBuster
DirBuster是用来探测web服务器上的目录和隐藏文件的.因为DirBuster是采用java编写的,所以运行前要安装上java的环境. 来看一下基本的使用: ①:TargetURL下输入要探测网 ...
- PWA介绍
https://codelabs.developers.google.com/codelabs/your-first-pwapp/#0 PWA是一些技术的集合.用于消除web与其他客户端之间的差距,最 ...
- centos 7.3 快速安装ceph
Ceph的部署手册(Centos7.3) Ceph简介 Ceph是一种为优秀的性能.可靠性和可扩展性而设计的统一的.分布式文件系统. 部署逻辑架构 准备3台主机,并且修改主机名(hostnam ...
- The North American Invitational Programming Contest 2018 H. Recovery
Consider an n \times mn×m matrix of ones and zeros. For example, this 4 \times 44×4: \displaystyle \ ...