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];;
    while(j&&chk(a,h[j])){
        h[i]=h[j];num[h[i].n]=i;i=j;j>>=;
    }
    h[i]=a;num[h[i].n]=i;
}
inline void sink(int i){
    heap a=h[i];;
    while(j<=cnt){
        ],h[j])) ++j;
        if(chk(a,h[j])) break;
        h[i]=h[j];num[h[i].n]=i;i=j;j<<=;
    }
    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);
    ;i<=n;++i){
        scanf("%lld",&a[i]);
        if(a[i]>=0LL){
            ++cnt;ans+=a[i];
        }
    }
    /*正数个数<=m*/
    if(cnt<=m){
        sort(a+,a++n,cmp);
        ;i<=m;++i)
            sum+=a[i];
        printf("%lld\n",sum);
        return;
    }
    cnt=;
    ;i<=n;++i){
        if(sum*a[i]<0LL){
            a[++cnt]=sum;sum=a[i];
        }
        else sum+=a[i];
    }
    a[++cnt]=sum;
    n=cnt;cnt=;
    ;i<=n;++i)
        ) ++cnt;
    /*正数区间数<=m*/
    if(cnt<=m){
        printf("%lld\n",ans);return;
    }
    ;i<=n;++i){
        lst[i]=i-;nxt[i]=i+;
    }
    lst[n+]=n;nxt[]=;
    m=cnt-m;cnt=;
    ;i<=n;++i){
        h[++cnt].k=abs(a[i]);h[cnt].n=i;num[i]=cnt;swim(cnt);
    }
    while(m){
        tmp=h[];h[]=h[cnt--];sink();
        )||!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);
    ;
}

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

  1. [日常训练]string

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

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

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

  3. [日常训练]mod

    Description 给定$p_1,p_2,-,p_n,b_1,b_2,...,b_m$, 求满足$x\;mod\;p_1\;\equiv\;a_1,x\;mod\;p_2\;\equiv\;a_2 ...

  4. [日常训练]training

    Description 一条线上有栋楼,第栋楼有层,每层有1个价值为的物品. 可以花费1个单位时间完成以下3种移动: 1.在同一栋楼中向上或者向下走一层; 2.如果此刻在顶楼,可以通往1楼; 3.从当 ...

  5. [日常训练]school

    Description 众所周知,家离学校很远.于是,每天算准了时间出发,以保证能在上课铃响前 秒到达学校. 不幸的是,市最近正在修路.这就导致有些路可能无法通行,因而可能导致迟到. 不打算改变他的出 ...

  6. [日常训练]article

    Description 小今天来写作文啦! 小非常善于堆砌辞藻.在洋洋洒洒写了一长篇之后,小发现作文中很多段落都似曾相识.小认为,如果一段字符在文章开头,结尾和中间都出现过,那么这段字符就可以被认为是 ...

  7. [日常训练]curves

    Description 小同学的弟弟小昨天学习了数学中的一元二次函数,但是由于学业不精,他一个晚上都在缠着小问一元二次函数的极值问题,小烦不可耐,于是,想请你帮忙弄个程序来应付小.程序要完成以下任务: ...

  8. [日常训练]常州集训day8

    T1 Description 给定一个长度为$n$的正整数序列$a$.可以将序列分成若干段,定义第$i$段的权值$x_i$为这一段中所有数的最大值,特殊地,$x_0=0$.求$\sum_{i=1}^{ ...

  9. [日常训练]常州集训day7

    T1 Description 给定一个序列,初始为空.依次将$1-n$插入序列,其中$i$插到当前第$a_i$个数的右边($a_i=0$表示插到序列最左边).求最终序列. Input 第一行一个整数$ ...

随机推荐

  1. Join 和 apply 用法

    TSQL中的join语句共有五种类型,left join,right join,inner join,full join,cross join 为了描述方便,解释一个名词"保留表" ...

  2. jeecg表单页面控件权限设置(请先看官方教程,如果能看懂就不用看这里了)

    只是把看了官方教程后,觉得不清楚地方补充说明一下: 1. 2. 3. 4.用"jeecgDemoController.do?addorupdate"这个路径测试,不出意外现在应该可 ...

  3. 移动APP的开发迭代离不开测试,你搞清楚其中的关键点了吗?

    App测试的一个要求是一个beta测试环境.为此,操作系统制造商要么提供他们自己的测试环境,比如:Testflight (iOS),要么可以使用任一商用工具,如:HockeyApp (Android) ...

  4. Python3学习(二)-递归函数、高级特性、切片

    ##import sys ##sys.setrecursionlimit(1000) ###关键字参数(**关键字参数名) ###与可变参数不同的是,关键字参数可以在调用函数时,传入带有参数名的参数, ...

  5. GAudio是一个音频播放SDK

    gaudio是一个基于C/C++混合编程的跨平台音频库,当前支持windows32/64操作系统 免费使用 - 有问题和建议请联系 谢谢 修改记录1.2013.04.01    初次发布2.2013. ...

  6. MFC CString::GetBuffer() 内存数据异常

    问题描述 在项目中的一个文件路径存储在CString的对象中,这个对象在函数间传递了几次,当传递出来的时候,因为要使用到字符指针,所以GetBuffer获取字符串的指针,但是通过调试,发现,CStri ...

  7. 《BI那点儿事》浅析十三种常用的数据挖掘的技术

    一.前沿 数据挖掘就是从大量的.不完全的.有噪声的.模糊的.随机的数据中,提取隐含在其中的.人们事先不知道的但又是潜在有用的信息和知识的过程.数据挖掘的任务是从数据集中发现模式,可以发现的模式有很多种 ...

  8. Tomcat web.xml中定义了文件扩展名到MIME类型的对应关系

    Tomcat在返回静态资源时,会根据资源文件的扩展名产生对应的content-type头(也即MIME类型)添加到response header中. 在Tomcat的web.xml规定了扩展名及相应M ...

  9. FIM 2010: Kerberos Authentication Setup

    The goal of this article is to provide some background information regarding the Kerberos related co ...

  10. CSS选择器、优先级与匹配原理(转)

    CSS选择器.优先级与匹配原理 导航 为了分析Bootstrap源码,所以的先把CSS选择器相关的东东给巩固好 废话就不多说了 CSS 2.1 selectors, Part 1 计算指定选择器的优先 ...