博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bzoj 2288: 【POJ Challenge】生日礼物【链表+堆】
阅读量:4581 次
发布时间:2019-06-09

本文共 1422 字,大约阅读时间需要 4 分钟。

参考:

把相同符号的连续数字加起来,合并后ans先贪心的加上所有正数,如果正数个数sum>m,设计二元组(i,a[i])表示合并后序列i位置上值为a,记录前驱后继,塞进按绝对值排序的小根堆里。每次拿出来一个,减去这个x的a的绝对值,然后合并左右前驱后继,再塞回去。
如果拿出来的是正数,那么减去相当于原来选了现在不选,如果是负数,减去相当于选。
然后a值要改成a[l]+a[r]+a[x],下次再选这个区间的话,相当于对x进行逆操作。
注意边界,边界上的负数没用。

#include
#include
#include
#include
using namespace std;const int N=100005,inf=1e9;;int n,m,a[N],tot=1,ne[N],pr[N],ans,sum;bool v[N];// priority_queue
>q;struct cmp{ bool operator()(pair
a,pair
b) { return abs(a.first)>abs(b.first); }};priority_queue
,vector
>,cmp>q;int read(){ int r=0,f=1; char p=getchar(); while(p>'9'||p<'0') { if(p=='-') f=-1; p=getchar(); } while(p>='0'&&p<='9') { r=r*10+p-48; p=getchar(); } return r*f;}int main(){ n=read(),m=read(); for(int i=1;i<=n;i++) { int x=read(); if((long long)a[tot]*x>=0) a[tot]+=x; else a[++tot]=x; } for(int i=1;i<=tot;i++) {//cout<
<
0) ans+=a[i],sum++; pr[i]=i-1; ne[i]=i+1; q.push(make_pair(a[i],i)); } pr[1]=0,ne[tot]=0; while(sum>m) { sum--; while(v[q.top().second]) q.pop(); int x=q.top().second,l=pr[x],r=ne[x]; q.pop(); if(l&&r) ans-=abs(a[x]); else if(a[x]>0) ans-=a[x]; else { sum++;//边界上的负数不能取,要把减去的sum加回来 continue; } a[x]=a[l]+a[r]+a[x]; v[l]=1;v[r]=1; pr[ne[l]]=pr[l],pr[ne[r]]=pr[r]; ne[pr[l]]=ne[l],ne[pr[r]]=ne[r]; q.push(make_pair(a[x],x)); } printf("%d\n",ans); return 0;}

转载于:https://www.cnblogs.com/lokiii/p/8430181.html

你可能感兴趣的文章
Centos以rpm方式进行安装MySql
查看>>
java中使用session的一些细节
查看>>
浏览器输入服务器端口号来访问html网页
查看>>
hdu 6435 CSGO(最大曼哈顿距离)
查看>>
logback框架之——日志分割所带来的潜在问题
查看>>
链路追踪工具之Zipkin学习小记
查看>>
iOS中通讯录的开发
查看>>
怎么让table中的<td>内容向上对齐
查看>>
[Java] 遍历HashMap和HashMap转换成List的两种方式
查看>>
mongodb
查看>>
LeetCode 46. Permutations
查看>>
jmeter- 性能测试3:聚合报告(Aggregate Report )
查看>>
JavaScript高级程序设计---学习笔记(二)
查看>>
vim 插件的学习
查看>>
Uncaught SyntaxError: Unexpected token ILLEGAL
查看>>
一个预处理定义的问题
查看>>
ANDROID L——Material Design综合应用(Demo)
查看>>
自我介绍以及关于软件工程的问题
查看>>
struts (一)
查看>>
【新番推荐】工作细胞
查看>>