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 思路 最简单 ...
随机推荐
- CSS3与弹性盒布局
1.弹性盒布局对齐模式 1.1.弹性盒子 在规定弹性盒子之中的子级元素换行显示之前父级元素必须是弹性盒子模型,也就是设置 display 为 flex 代码如下: <!DOCTYPE html& ...
- 洛谷 p1141 01迷宫题解
很长时间没发博客了,今天水一下 很多dalao说染色(普通的)过不了, 我怎么就过了 其实我也是今天才知道什么是染色(由@你听风在吼 dalao指导) 然后自己打了一个,也不知道叫不叫染色,反正是过了 ...
- Bootstrap 网页乱码
问题:今天早上在实践bootstrap的时候,用EditPlus写代码,标签中包含了中文.在浏览器解析的时候中文部分生成的乱码.但是网页部分已经声明了使用utf-8的编码方式. 解决:网页字体正常显示 ...
- bzoj5469 [FJOI2018]领导集团问题
题目描述: bz luogu 题解: 相当于树上$LIS$问题. 考虑一维情况下的贪心,我们可以用multiset启发式合并搞. 代码: #include<set> #include< ...
- Web框架之Django_05 模型层了解(单表查询、多表查询、聚合查询、分组查询)
摘要: 单表查询 多表查询 聚合查询 分组查询 一.Django ORM 常用字段和参数: 常用字段:#AutoFieldint自增列,必须填入参数primary_key = True,当model中 ...
- Python中单元测试出错了,会怎么样?
在上一篇中,我们看到了单元测试正常通过时的情况,如果我们边修改一下要测试的函数,然后再运行单元测试,会出现什么情况. 原say_hello_name.py def hello_name(name): ...
- Python编程快速上手--实践项目11.11.1
from selenium import webdriver from selenium.webdriver.common.keys import Keys import time def messa ...
- Python9-装饰器进阶-day12
wapers方法 def wahaha(): ''' sljfldsjflds :return: ''' print('娃哈哈') print(wahaha.__name__) #查看字符串格式的函数 ...
- I2C驱动框架(一)
参考:I2C子系统之内核中I2C子系统的结构 结合vmlinux.lds和Makefile可确定i2c初始化函数的执行顺序如下: 1./dricer/i2c/i2c-core.c中的函数:i2c_in ...
- 和为s的两个数字 和为s的连续正数序列
输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s,如果有多对数字的和等于s,输出任意一对即可. #include <iostream> using namesp ...