Description

在长度为的序列中选出段互不相交的子段,求最大字段和.

Input

第一行两个整数.

第二行个整数.

Output

一行一个整数表示最大值.

Sample Input

5 2

10 -1 10 -1 10

Sample Output

29

HINT

Solution

如果序列中正整数个数,直接取最大的个数的和即可.

将序列合并成若干个交错的正负段和,如-1,-2,3,4,-5,-6可以合并成-1-2,3+4,-5-6.

记录所有正数段之和,设正数段个数为,则需要把k段正数段合并成段.

对于每一段正数段有两种操作:

1.舍弃;

2.与相邻串合并.

可以用堆来实现:将所有段的绝对值扔入堆中,每次取最小的元素(如果在当前序列中是左或右没有元素的负数段就跳过),,将与在当前序列中的左右元素合并即可.

#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 100005
#define M -100000000000001LL
using namespace std;
typedef long long ll;
struct heap{
ll k;int n;
}h[N],tmp;
ll a[N],num[N],sum,ans;
int lst[N],nxt[N],n,m,cnt;
inline bool cmp(ll x,ll y){
return x>y;
}
inline bool chk(heap x,heap y){
if(x.k!=y.k) return x.k<y.k;
return x.n<y.n;
}
inline void swim(int i){
heap a=h[i];int j=i>>1;
while(j&&chk(a,h[j])){
h[i]=h[j];num[h[i].n]=i;i=j;j>>=1;
}
h[i]=a;num[h[i].n]=i;
}
inline void sink(int i){
heap a=h[i];int j=i<<1;
while(j<=cnt){
if(j<cnt&&chk(h[j+1],h[j])) ++j;
if(chk(a,h[j])) break;
h[i]=h[j];num[h[i].n]=i;i=j;j<<=1;
}
h[i]=a;num[h[i].n]=i;
}
inline void del(int u){
if(!u||u>n) return;
if(num[u]){
if(num[u]==cnt) --cnt;
else{
h[num[u]]=h[cnt--];sink(num[u]);swim(num[u]);
}
}
lst[nxt[u]]=lst[u];nxt[lst[u]]=nxt[u];
}
inline void init(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i){
scanf("%lld",&a[i]);
if(a[i]>=0LL){
++cnt;ans+=a[i];
}
}
/*正数个数<=m*/
if(cnt<=m){
sort(a+1,a+1+n,cmp);
for(int i=1;i<=m;++i)
sum+=a[i];
printf("%lld\n",sum);
return;
}
cnt=0;
for(int i=1;i<=n;++i){
if(sum*a[i]<0LL){
a[++cnt]=sum;sum=a[i];
}
else sum+=a[i];
}
a[++cnt]=sum;
n=cnt;cnt=0;
for(int i=1;i<=n;++i)
if(a[i]>0) ++cnt;
/*正数区间数<=m*/
if(cnt<=m){
printf("%lld\n",ans);return;
}
for(int i=1;i<=n;++i){
lst[i]=i-1;nxt[i]=i+1;
}
lst[n+1]=n;nxt[0]=1;
m=cnt-m;cnt=0;
for(int i=1;i<=n;++i){
h[++cnt].k=abs(a[i]);h[cnt].n=i;num[i]=cnt;swim(cnt);
}
while(m){
tmp=h[1];h[1]=h[cnt--];sink(1);
if(((!lst[tmp.n]||nxt[tmp.n]>n)&&a[tmp.n]<0)||!a[tmp.n]) continue;
ans-=tmp.k;a[tmp.n]+=a[lst[tmp.n]]+a[nxt[tmp.n]];
del(lst[tmp.n]);del(nxt[tmp.n]);
h[++cnt].k=abs(a[tmp.n]);h[cnt].n=tmp.n;swim(cnt);
--m;
}
printf("%lld\n",ans);
}
int main(){
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
init();
fclose(stdin);
fclose(stdout);
return 0;
}

[日常训练]最大M子段和的更多相关文章

  1. 「日常训练」ZgukistringZ(Codeforces Round #307 Div. 2 B)

    题意与分析(CodeForces 551B) 这他妈哪里是日常训练,这是日常弟中弟. 题意是这样的,给出一个字符串A,再给出两个字符串B,C,求A中任意量字符交换后(不限制次数)能够得到的使B,C作为 ...

  2. 「日常训练」 Fire!(UVA-11624)

    与其说是训练不如说是重温.重新写了Java版本的代码. import java.util.*; import java.math.*; import java.io.BufferedInputStre ...

  3. 「知识学习&日常训练」莫队算法(一)(Codeforce Round #340 Div.2 E)

    题意 (CodeForces 617E) 已知一个长度为\(n\)的整数数列\(a[1],a[2],-,a[n]\),给定查询参数\(l,r\),问\([l,r]\)内,有多少连续子段满足异或和等于\ ...

  4. 「日常训练」COMMON 约数研究(HYSBZ-1968)

    题意与分析 感谢https://www.cnblogs.com/Leohh/p/7512960.html的题解.这题话说原来不在我的训练范围,正好有个同学问我,我就拿来做做.数学果然不是我擅长的啊,这 ...

  5. 「日常训练」 Mike and Fun (CFR305D2B)

    题意(CodeForces 548B) 每次对01矩阵中的一位取反,问每次操作后,单列中最长连续1的长度. 分析 非常非常简单,但是我当时训练的时候WA了四次...无力吐槽了,人间 不值得.jpg 代 ...

  6. 「日常训练」Common Subexpression Elimination(UVa-12219)

    今天做的题目就是抱佛脚2333 懂的都懂. 这条题目干了好几天,最后还是参考别人的代码敲出来了,但是自己独立思考了两天多,还是有收获的. 思路分析 做这条题我是先按照之前的那条题目(The SetSt ...

  7. 集训队日常训练20181117 DIV2

    大佬们一顿操作猛如虎,拼命AC强啊 4262: 区间异或  Time Limit(Common/Java):1000MS/3000MS     Memory Limit:65536KByteTotal ...

  8. [日常训练]string

    Description 给定一个长度为$n$的字符串,串中的字符保证是前$k$个小写字母.你可以在字符串后再添加$m$个字符,使得新字符串所包含的不同的子序列数量尽量多.当然,前提是只能添加前$k$个 ...

  9. [日常训练]yayamao的神题

    Description $yayamao$是数学神犇,一天他在纸上计算起了$1/P$, 我们知道按照模拟除法可以得到准确解,例如$1/7=0.(142857),1/10=0.1(0)$.$yayama ...

随机推荐

  1. removeNode is not defined removeNode is not a function

    在javascript操作dom树的时候可能会经常遇到增加,删除节点的事情,比如一个输入框后一个增加按钮,一个删除按钮,点击增加就增加 个输入框,点击删除就删除对应的输入框.在一些js框架,如Prot ...

  2. How To Create an IE-Only Stylesheet

    https://css-tricks.com/how-to-create-an-ie-only-stylesheet/ https://css-tricks.com/snippets/css/css- ...

  3. 利用ThinkPHP自带的七牛云驱动上传文件到七牛云以及删除七牛云文件方法

    一.准备工作 1.注册七牛云账号 2.选择对象储存->创建空间->设置为公开 3.在config配置文件中添加以下代码 'UPLOAD_FILE_QINIU' => array ( ...

  4. mac OS X Yosemite 上编译hadoop 2.6.0/2.7.0及TEZ 0.5.2/0.7.0 注意事项

    1.jdk 1.7问题 hadoop 2.7.0必须要求jdk 1.7.0,而oracle官网已经声明,jdk 1.7 以后不准备再提供更新了,所以趁现在还能下载,赶紧去down一个mac版吧 htt ...

  5. stack overflow错误分析

    stack overflow(堆栈溢出)就是不顾堆栈中分配的局部数据块大小,向该数据块写入了过多的数据,导致数据越界,结果覆盖了老的堆栈数据. 或者解释为 在长字符串中嵌入一段代码,并将过程的返回地址 ...

  6. iOS搜索附近的位置(类似微博朋友圈位置)

    说什么都是苍白的,直接上图~ 在某些情况下,我们需要获取用户周边的位置,来让用户选取.例如微信的朋友圈,在发一条朋友圈时可以选择地点,就是使用这样的功能. 基于以上的情况(其实也就是为了模仿微信),有 ...

  7. centos7 安装nginx和php5.6.25遇到 无法访问php页面 报错file not found 问题解决

    php-fpm安装完成,nginx安装完成 netstap -ntl| 发下端口正常开启 iptables -L 返现9000端口已经开放 ps -aux|grep nginx 发下nginx进程正常 ...

  8. jaccard similarity coefficient 相似度计算

    Jaccard index From Wikipedia, the free encyclopedia     The Jaccard index, also known as the Jaccard ...

  9. android之服务

    android中的进程优先级 前台进程 拥有一个正在与用户交互的Activity(onResume方法被调用) 与一个前台Activity绑定的服务 服务调用了startForeground onCr ...

  10. 前端框架——BootStrap学习

    BootStrap简单总结下:1.栅格系统,能够很好的同时适应手机端和PC端(及传说中的响应式布局) 2.兼容性好 接下来是对BootStrap学习的一些基础案例总结和回顾: 首先引入:bootstr ...