题意

描述

ftiasch 18岁生日的时候,lqp18_31给她看了一个神奇的序列 A1, A2, ..., AN. 她被允许选择不超过 M 个连续的部分作为自己的生日礼物。ftiasch想要知道选择元素之和的最大值。你能帮助她吗?

输入格式

第一行两个整数N,M。

第二行N个整数A1~AN。

输出格式

一个整数,表示答案。

样例输入

5 2

2 -3 2 -1 2

样例输出

5

数据范围与约定

对于100%的数据: N,M<=10^5, |Ai|<=10^4

来源

北京大学

分析

参照solider98的题解。

设输入序列为A[1...n], 将A的首尾的连续的非正数去除的序列B[1...m], 将序列B所有相邻的正数合并, 所有相邻的非正数合并.得到序列C[1...p], C[1...p]为正, 非正交替的序列且C[1] > 0, C[p] > 0, C[1...p]中正数的个数大于M, 设C[i]为C[1...p]中绝对值最小的数, 那么有如下结论成立:

结论1: 如果i = 1或i = p那么一定存在不包含C[i]和与C[i]相邻的元素的最优选择方案(所选则的至多M个连续的部分的和最大的选择方案, 根据C[i]的绝对值最小, 且与C[i]相邻的元素必为绝对值不小于C[i]的负数较易证明此结论)

结论2: 如果1 < i < p, 那么存在最优的选择方案同时包含C[i - 1], C[i], C[i + 1]

证明:

(1)当C[i] > 0时, 假设存在最优方案R只包含三者中的一个, 显然不可能只包含Ci - 1或Ci + 1, 即只包含C[i], 由于C中正数的个数大于M, 故可使用任意未被选择的整数C[j]替换C[i], 替换之后所有选择的数的和不会减小.假设存在最优方案R只包含三者中的两个, 显然不能为C[i - 1]和C[i + 1], 不妨设包含C[i]和C[i + 1], 此时去掉C[i]和C[i + 1]剩余选择的元素之和不会减小. 故C[i] > 0时, 存在最优方案同时包含C[i - 1], C[i]和C[i + 1]或同时不包含.

(2)当C[i] <= 0时, 假设存在最优方案R只包含三者中的一个, 显然不可能只包含C[i], 不妨设包含C[i - 1], 此时将C[i]和C[i - 1]包含进来, 同时选择的元素之和不会减小, 假设最优方案R只包含三者中的两个, 显然不可能包含C[i - 1]和C[i]或C[i + 1]和C[i], 即只能包含C[i - 1]和C[i + 1], 此时可包含进C[i]使得选择的连续的部分个数减少1, 因此可在C中选择任意一个之前R中未被选择的正数, 且所选择的元素之和不会减小, 故C[i] <= 0时, 存在最优方案同时包含C[i - 1], C[i]和C[i + 1]或同时不包含.

基于结论2, 可不断减少序列中正数的个数, 直至正数的个数不超过M(此时最优方案选择所有的正数)

时间复杂度\(O(N \log N)\)

代码

#include<bits/stdc++.h>
#define co const
#define il inline
#define rg register
#define fi first
#define se second
#define mp make_pair
template<class T>il T read(){
rg T data=0,w=1;
rg char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') w=-1;
ch=getchar();
}
while(isdigit(ch))
data=data*10+ch-'0',ch=getchar();
return data*w;
}
template<class T>il T read(rg T&x){
return x=read<T>();
}
typedef long long LL;
using namespace std; co int MAX=1e5+5;
int A[MAX],N,M;
pair<int,int> he[MAX];int size;
pair<int,int> li[MAX<<1];int head,tot,nex[MAX<<1],pre[MAX<<1]; bool cmp(int a,int b){
return abs(he[a].fi)<abs(he[b].fi);
}
void hswap(int a,int b){
swap(li[he[a].se].se,li[he[b].se].se),swap(he[a],he[b]);
}
void up(int a){
for(int q=a,p=q>>1;p&&cmp(q,p);hswap(q,p),q=p,p=q>>1);
}
void down(int a){
for(int p=a,l=p<<1,r=l+1,t;
l<=size&&(cmp(l,p)||r<=size&&cmp(r,p));
t=r>size||min(l,r,cmp)==l?l:r,hswap(p,t),p=t,l=p<<1,r=l+1);
}
void hins(pair<int,int> pa){
he[++size]=pa,up(size);
}
void hdel(int a){
hswap(a,size--);if(a!=size+1) up(a),down(a);
} void lins(int a,pair<int,int> b){
li[++tot]=b;
if(!a) nex[tot]=head,pre[head]=tot,head=tot;
else nex[tot]=nex[a],pre[tot]=a,pre[nex[a]]=tot,nex[a]=tot;
}
void ldel(int a){
if(a==head) head=nex[head],pre[head]=0;
else nex[pre[a]]=nex[a],pre[nex[a]]=pre[a];
} int main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
read(N),read(M);
for(int i=1;i<=N;++i) read(A[i]);
int be=1,end=N;
while(be<=end&&A[be]<=0) ++be; while(end>=be&&A[end]<=0) --end;
if(be>end){
puts("0"); return 0;
}
A[1]=A[be];int len=1;
for(int i=be+1;i<=end;++i)
if(A[i-1]>0&&A[i]>0||A[i-1]<=0&&A[i]<=0) A[len]+=A[i];
else A[++len]=A[i];
for(int i=1;i<=len;++i)
li[i].fi=A[i],nex[i]=i+1,pre[i]=i-1;
nex[len]=0,pre[1]=0,head=1,tot=len;
for(int i=1;i<=len;++i) li[i].se=size+1,hins(mp(li[i].fi,i));
while(size/2+1>M){
int u=he[1].fi,v=he[1].se;
if(!pre[v]) hdel(li[nex[v]].se),hdel(1),ldel(nex[v]),ldel(v);
else if(!nex[v]) hdel(li[pre[v]].se),hdel(1),ldel(pre[v]),ldel(v);
else{
int t=u+li[pre[v]].fi+li[nex[v]].fi,pp=pre[pre[v]];
hdel(li[pre[v]].se),hdel(li[nex[v]].se),hdel(1),
ldel(pre[v]),ldel(nex[v]),ldel(v),
lins(pp,mp(t,size+1)),hins(mp(t,tot));
}
}
int ans=0;
for(int i=head;i;i=nex[i]) if(li[i].fi>0) ans+=li[i].fi;
printf("%d\n",ans);
return 0;
}

CH1812 生日礼物的更多相关文章

  1. 【BZOJ】【1293】【SCOI2009】生日礼物

    二分/堆 求一个最小的区间使得包含所有的颜色(并不一定只出现一次)$n\leq 10^6$ 我想的做法是:二分这个最小的长度(满足单调性……好久才想到QAQ),然后O(n)判断是否有可行的区间,这一步 ...

  2. 华为上机:Tom的生日礼物

    Tom的生日礼物 描述: 四月一日快到了,Tom想了个愚人的好办法——送礼物.嘿嘿,不要想的太好,这礼物可没那么简单,Tom为了愚人,准备了一堆盒子,其中有一个盒子里面装了礼物.盒子里面可以再放零个或 ...

  3. 【链表】BZOJ 2288: 【POJ Challenge】生日礼物

    2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 382  Solved: 111[Submit][S ...

  4. BZOJ2288: 【POJ Challenge】生日礼物

    2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 284  Solved: 82[Submit][St ...

  5. 1293: [SCOI2009]生日礼物

    1293: [SCOI2009]生日礼物 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1096  Solved: 584[Submit][Statu ...

  6. CJOJ 2485 UVa 11991 生日礼物 / UVa 11991 Easy Problem from Rujia Liu?

    CJOJ 2485 UVa 11991 生日礼物 / UVa 11991 Easy Problem from Rujia Liu? Description (原题来自刘汝佳<训练指南>Pa ...

  7. TurnipBit:和孩子一起动手DIY“滚动”的生日礼物

    当孩子的生日来临之时,做父母的总是会为该为孩子准备什么礼物而烦恼.下面就教家长朋友们利用TurnipBit开发板DIY一份"特殊"的生日礼物,不仅能增加与孩子的互动性还能提升孩子在 ...

  8. BZOJ 1293: [SCOI2009]生日礼物【单调队列】

    1293: [SCOI2009]生日礼物 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2534  Solved: 1383[Submit][Stat ...

  9. bzoj 2288 【POJ Challenge】生日礼物 双向链表+堆优化

    2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1003  Solved: 317[Submit][ ...

随机推荐

  1. 系统管理命令之whoami

    whoami命令用于打印当前有效的用户名称,相当于执行id  --un命令. 1.显示该命令帮助信息: # whoami --help 2.显示该命令的版本信息: # whoami --version ...

  2. 2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018) Solution

    A. Altruistic Amphibians Upsolved. 题意: $有n只青蛙,其属性用三元组表示 <l_i, w_i, h_i> l_i是它能跳的高度,w_i是它的体重,h_ ...

  3. jQuery中的prop和attr区别

    最近在做一个项目用jq时发现一个问题  在谷歌中可以正常出效果  但是在火狐中就是不行 就是这个prop和attr   之前用的是attr方法   但是在火狐中不出效果  于是特意看了两者的区别 主要 ...

  4. c++第二十一天

    p115~p118: 1.区分int *p[4];和int (*p)[4];.前者是整型指针的数组,后者是指向含有4个整数的数组. 2.规避上述问题的方法就是:使用 auto和 decltype. 3 ...

  5. 20135320赵瀚青LINUX第四章读书笔记

    概述 什么是进程调度 进程调度:在可运行态进程之间分配有限处理器时间资源的内核子系统. 一.调度策略 4.1进程类型 I/O消耗型进程:大部分时间用来提交I/O请求或是等待I/O请求,经常处于可运行状 ...

  6. Linux内核分析04

    扒开系统调用的三层皮(上) 一,用户态.内核态和中断 用户态.内核态和中断的处理过程 用户态和内核态的区分 内核态:代码可以执行特权指令,访问任意的物理地址,CPU的这种执行级别就对应着~ 相对的用户 ...

  7. Tensorflow源码编译,解决tf提示未使用SSE4.1 SSE4.2 AVX警告【转】

    本文转载自:https://blog.csdn.net/iTaacy/article/details/72799833 版权声明:欢迎转载,转载请注明出处! https://blog.csdn.net ...

  8. 安装Git【转】

    本文转载自:http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000 最早Git是在Linu ...

  9. CPA定律——一致性,可用性和分区容错性

    按照美国著名科学家 Eric Brewer 在 2000 年提出的理论,当技术架构从集中式架构向分布式架构演进,会遇到 “CAP 定律”的瓶颈. CAP 说明一个数据处理系统不能同时满足一致性,可用性 ...

  10. 解决 "OperationalError: (sqlite3.OperationalError) no such table: ..."问题

    参考:flask/sqlalchemy - OperationalError: (sqlite3.OperationalError) no such table 在用Flask写一个简单的py文件,做 ...