BZOJ2288:[POJ Challenge]生日礼物
浅谈堆:https://www.cnblogs.com/AKMer/p/10284629.html
题目传送门:https://lydsy.com/JudgeOnline/problem.php?id=2288
首先我们可以把同符号的全部合成一个数,第一个如果是负数就扔了,最后一个也是。
然后把所有的正数都加起来,记段数为\(x\),若\(x<=m\)则这就是正确答案,否则我们需要使用一些手段让\(x\)降低为\(m\)。比如扔掉某些权值很小的正整数,或者加上某些绝对值很小的负数,这样都会使\(x--\)。但是如果我同时扔掉某个权值很小的正整数又加上这个数两边的负数显然是很蠢的,又或者我加上了某个绝对值很小的负数又扔掉这个负数两边的正数,显然也是很蠢的。
于是,我们往堆里扔所有数的绝对值,做一遍数据备份,不过每次是减去堆顶的值就行了。
时间复杂度:\(O(nlogn)\)
空间复杂度:\(O(n)\)
代码如下:
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=1e5+5;
int a[maxn];
int n,m,ans,cnt;
int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
}
struct Linked_List {
int lst,nxt,val,in_heap;
Linked_List() {}
Linked_List(int _lst,int _nxt,int _val) {
lst=_lst,nxt=_nxt,val=_val;
}
}L[maxn];
struct Heap {
int tot;
int tree[maxn];
bool less(int id1,int id2) {return L[id1].val<L[id2].val;}
void up(int pos) {
while(pos>1) {
if(less(tree[pos],tree[pos>>1])) {
swap(tree[pos],tree[pos>>1]);
swap(L[tree[pos]].in_heap,L[tree[pos>>1]].in_heap);
pos>>=1;
}
else break;
}
}
void down(int pos) {
int son=pos<<1;
while(son<=tot) {
if(son<tot&&less(tree[son|1],tree[son]))son|=1;
if(less(tree[son],tree[pos])) {
swap(tree[son],tree[pos]);
swap(L[tree[son]].in_heap,L[tree[pos]].in_heap);
pos=son,son=pos<<1;
}
else break;
}
}
void ins(int v) {tree[++tot]=v,L[v].in_heap=tot,up(tot);}
int pop() {
int res=tree[1];
tree[1]=tree[tot--];
L[tree[1]].in_heap=1;
down(1);return res;
}
void del(int id) {
if(id==tot) {tot--;return;}
tree[id]=tree[tot--];
L[tree[id]].in_heap=id;
if(id==1)down(id);
else if(id==tot)up(id);
else up(id),down(id);
}
}T;
void work() {
for(int i=1;i<=n;i+=2)
ans+=a[i],m--;
for(int i=1;i<=n;i++) {
L[i]=Linked_List(i-1,i+1,abs(a[i]));
T.ins(i);
}
while(m<0) {
int id=T.pop(),lst=L[id].lst,nxt=L[id].nxt;ans-=L[id].val;
if(!lst) {
T.del(L[nxt].in_heap);m++;
L[L[nxt].nxt].lst=0;continue;
}
if(nxt==n+1) {
T.del(L[lst].in_heap);m++;
L[L[lst].lst].nxt=n+1;continue;
}
T.del(L[lst].in_heap),T.del(L[nxt].in_heap);
L[lst].val=L[lst].val+L[nxt].val-L[id].val;T.ins(lst);
L[lst].nxt=L[nxt].nxt,L[L[nxt].nxt].lst=lst;m++;
}
printf("%d\n",ans);
}
int main() {
n=read(),m=read();
if(!m) {puts("0");return 0;}
for(int i=1;i<=n;i++) {
int x=read();
if(!x)continue;
if(!cnt&&x<0)continue;
if(!cnt)a[++cnt]=x;
else {
if((a[cnt]<0)==(x<0))a[cnt]+=x;
else a[++cnt]=x;
}
}
if(a[cnt]<0)cnt--;
n=cnt;work();
}
BZOJ2288:[POJ Challenge]生日礼物的更多相关文章
- [bzoj2288][POJ Challenge]生日礼物
用堆维护双向链表来贪心... 数据范围显然不容许O(nm)的傻逼dp>_<..而且dp光是状态就n*m个了..显然没法优化 大概就会想到贪心乱搞了吧...一开始想贪心地通过几段小的负数把正 ...
- BZOJ3502PA2012Tanie linie&BZOJ2288[POJ Challenge]生日礼物——模拟费用流+链表+堆
题目描述 n个数字,求不相交的总和最大的最多k个连续子序列. 1<= k<= N<= 1000000. 输入 输出 样例输入 5 2 7 -3 4 -9 5 样例输出 13 根据 ...
- BZOJ2288:[POJ Challenge]生日礼物——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=2288 ftiasch 18岁生日的时候,lqp18_31给她看了一个神奇的序列 A1, A2, . ...
- bzoj2288【POJ Challenge】生日礼物*
bzoj2288[POJ Challenge]生日礼物 题意: 给一个序列,求不超过m个连续的部分,使元素和最大.序列大小≤100000 题解: 先把连续的正数和负数合并起来,接着如果正数个数小于m则 ...
- BZOJ2288: 【POJ Challenge】生日礼物
2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 284 Solved: 82[Submit][St ...
- [bzoj2288]【POJ Challenge】生日礼物_贪心_堆
[POJ Challenge]生日礼物 题目大意:给定一个长度为$n$的序列,允许选择不超过$m$个连续的部分,求元素之和的最大值. 数据范围:$1\le n, m\le 10^5$. 题解: 显然的 ...
- 2288.【POJ Challenge】生日礼物 链表+堆+贪心
BZOJ2288 [POJ Challenge]生日礼物 题意: 给一个长度为\(n\)的数组,最多可以选\(m\)个连续段,问选取的最大值是多少 题解: 先把连续的符号相同的值合并,头和尾的负数去掉 ...
- 【链表】BZOJ 2288: 【POJ Challenge】生日礼物
2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 382 Solved: 111[Submit][S ...
- bzoj 2288 【POJ Challenge】生日礼物 双向链表+堆优化
2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1003 Solved: 317[Submit][ ...
随机推荐
- js的new到底干了啥 -
javascript通过new操作符构建一个对象的步骤 <Javascript高级程序设计>的解释: 创建一个对象 将构造函数的作用域赋给新对象(把新对象作为构造函数的调用上下文,也就是t ...
- PhotoKit详解
Photokit介绍 这篇主要介绍如何通过 Photokit获取数据 photokit.jpg 1,基类 PHObject Photos 框架中的根类PHObject只有一个公开接口 localIde ...
- 【python】-- Redis简介、命令、示例
Redis简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的持久化 ...
- PHP的依赖管理工具----composer
安装Composer 参考:https://getcomposer.org/doc/01-basic-usage.md composer 是PHP依赖管理工具 PHP最低版本要求5.3.2,需要允许o ...
- $.ajax()方法详解(转)
转: http://www.cnblogs.com/tylerdonet/p/3520862.html 1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type: ...
- Windows下重置MySQL密码(最开始是因为Access denied for user 'root'@'localhost'这个原因,无法登陆 'root'@'localhost')
本人使用的MySQL5.5,其他版本未测试过. 方法一: 更改密码: mysql -u root -p Enter password:*** mysql>use mysql; 选择数据库 Dat ...
- rtmp播放器
rtmp测试地址: rtmp://live.hkstv.hk.lxdns.com/live 有的时候连接不上,不是很流畅 参考: 1,simplest flashmedia example http: ...
- vs2008 发布网站时丢失文件问题
右键指定的文件->属性, 将生成操作更改成为"内容"就可以了.
- LRC歌词文件读取代码
/**************************************************/ /*******************-main文件-******************* ...
- 每天一个Linux命令(28)df命令
报告文件系统磁盘空间的使用情况.获取硬盘被占用了多少空间,目前还剩下多少空间等信息. (1)用法: 用法: df [选项] [文件] (2)功能: 功能: 显示 ...