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 思路 最简单 ...
随机推荐
- 程序windows上可以上传附件,部署到 linux服务器后出现 “上传目录 不可写” 怎么解决?
这样的问题一般都是linux 下文件读写权限引起的,用 shell 命名到上传附件的目录(如 cd /data/www/project/upload/),然后执行 shell 文件权限设置: 例如 ...
- mvc的model验证,ajaxhelper,验证机制语法
ajaxhelper: onsuccess是调用成功后显示方法,还有一个方法是调用前显示 model验证: 控件前端验证: 需要引入的JS 其中第二个是ajaxhelper的必须验证 后台的两个同名不 ...
- 如何启动Intel VT-x
如何启动Intel VT-x 5 在64bit win7系统下安装了Vmware10,然后安装64位的UbuntuKylin 14.04,想要打开UbuntuKylin,弹出如下对话框: 请问该如何启 ...
- python基础一 day10(2)
复习: # 三元运算符# 接收结果的变量 = 条件为真的结果 if 条件 else 条件为假的结果# 接收结果的变量 = “真结果” if 条件 else “假结果”## 命名空间 和 作用域# 三种 ...
- Python字符编码及字符串
字符编码 字符串是一种数据类型,但是字符串比较特殊的是编码问题,计算机只能处理数字,处理文本就需要将文本转换成数字. 计算机设计时8bit作为一个字节byte,一个字节能表示的最大整数就是(2^8)- ...
- WINDOWS-API:取得系统语言种类-GetOEMCP
GetOEMCP VB声明 Declare Function GetOEMCP Lib "kernel32" Alias "GetOEMCP" () As Lo ...
- 用Kotlin开发android平台语音识别,语义理解应用(olamisdk)
Kotlin是由JetBrains创建的基于JVM的编程语言,IntelliJ正是JetBrains的杰作,而android Studio是 基于IntelliJ修改而来的.Kotlin是一门包含很多 ...
- Mac OS 终端强化美化:iterm2 + zsh + oh~my~zsh 设置教程
为了获得更好的排版效果,文章改用markdown撰写,故重发一次. 前言 mac自带的terminal终端没有文件名高亮等功能,而且界面不是很好看,故今晚学舍友折腾了终端,可以让自己使用起来更加方便, ...
- 文件操作-mkdir
Linux mkdir命令 主要用来创建目录,也可以直接创建多层目录,本文就为大家介绍下 Linux mkdir命令 . 转载自https://www.linuxdaxue.com/linux-com ...
- Python列表,元组,字典,集合详细操作
菜鸟学Python第五天 数据类型常用操作及内置方法 列表(list) ======================================基本使用====================== ...