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][ ...
随机推荐
- 记录-阿里云Oss文件上传
public class OssUtil { /** * 上传图片 * @param file * @param request * @return */ public static Map<S ...
- oracle 如何完全删除干净
在安装oracle的时候如果出现了,指定的SID在本机上已经存在.这样的报错的话.这边你肯定是第二次在安装你的oracle了,这里出现这样的错误是你没有吧原先的那些关于oracle的东西给清理干净,这 ...
- 九度OJ 1339:ACM (排序)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:712 解决:379 题目描述: 今年的ACM世界总决赛快要开始了,需要有一个排名算法来对每支队伍进行现场排名.ACM组委会把这个任务交给了你 ...
- React-Native 安装改变镜像
3.安装完node后建议设置npm镜像以加速后面的过程,否则后面插件安装巨慢 npm config set registry https://registry.npm.taobao.org --glo ...
- Python读属性文件
# coding:utf-8 class Properties: def __init__(self, file_name): self.file_name = file_name self.prop ...
- 数据库存储I/O类型分析与配置
存储设备作为数据的容器,为应用提供数据存取服务,而存储系统将数据展现给不同的应用后,应用程序对数据访问不尽相同.简要来说,就是读和写,更加细分的话是以不同的传输单元(I/O大小)进行顺序和随机类型的读 ...
- Django——auth用户认证
之前我们在进行用户校验的时候,总是从数据库中获取数据,然后再进行对比,就像如下这样: def login(request): if request.method == "POST" ...
- Linux expect介绍和用法
expect时用与提供自动交互的工具.比如如果想要用ssh登陆服务器,每次都输入密码你觉得麻烦,那你就可以使用expect来做自动交互,这样的话就不用每次都输入密码了. 先看例子: #!/usr/bi ...
- ubuntu安装pip和python
安装pip2sudo apt-get install pip 这样安装的是pip2不支持Python3.x,可以使用如下命令安装pip3 sudo apt-get install python3-pi ...
- Please install Android target
今天在执行ionic build android时出现以下错误: [Error: Please install Android target: "android-22". Hint ...