题链:

http://www.lydsy.com/JudgeOnline/problem.php?id=2006

题解:

RMQ + 优先队列 (+ 前缀)

记得在一两个月前,一次考试考了这个题目的简化版:序列中只有正整数。
当时我们曰 :有负数的话就怕是莫得解法哦。
然后,有负数的情况居然是NOI题。。。
难哭。

1).首先尝试固定区间的右端点R。
那么可取的左端点的范围就已经确定。
所以对于右端点为 R的权和最大的区间就能够求出来了:
先求出前缀序列 pre[],
由于 sum = pre[R]-pre[L-1],且 pre[R] 固定,
即我们需要求出合法范围内的最小的 pre[L-1],
这个就可以用 RMQ实现。

2).用优先队列维护。
初始化时,把每个右端点R的最大权和区间的相关信息放入队列:
保存这些信息 :
{sum(该区间的和),R(固定的区间右端点是谁),p(区间和为sum时对应的左端点),l(左端点的左界),r(左端点的右界)}
那么直接取堆顶,即是当前的最大权和区间。
然后接下呢,为了以后不重复取到当前区间,我们把 [l,r] 剖成 [l,p-1] 和 [p+1,r]
并计算出相应的信息,继续放入优先队列,即把
{sum1,R,p1,l,p-1} 和  {sum2,R,p2,p+1,r} 加入进去。
重复操作 K次即可。

代码:

  1. #include<queue>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<iostream>
  5. #define MAXN 500005
  6. #define ll long long
  7. using namespace std;
  8. struct info{
  9. ll sum,R,p,l,r;
  10. bool operator <(const info & rtm) const{
  11. return sum<rtm.sum;
  12. }
  13. };
  14. ll stv[MAXN][20],stp[MAXN][20],log2[MAXN];
  15. ll pre[MAXN],N,K,A,B,ans;
  16. priority_queue<info>q;
  17. ll query(ll l,ll r){
  18. static ll k,mini;
  19. k=log2[r-l+1];
  20. mini=min(stv[l+(1<<k)-1][k],stv[r][k]);
  21. if(stv[l+(1<<k)-1][k]==mini) return stp[l+(1<<k)-1][k];
  22. else return stp[r][k];
  23. }
  24. int main()
  25. {
  26. freopen("piano.in","r",stdin);
  27. freopen("piano.out","w",stdout);
  28. log2[1]=0; ll pos; info now;
  29. for(ll i=2;i<=MAXN-5;i++) log2[i]=log2[i>>1]+1;
  30. scanf("%lld%lld%lld%lld",&N,&K,&A,&B);
  31. for(ll i=1;i<=N;i++)
  32. scanf("%lld",&pre[i]),pre[i]+=pre[i-1],stv[i][0]=pre[i],stp[i][0]=i;
  33. for(ll k=1;k<=log2[N];k++)
  34. for(ll i=(1<<k)-1;i<=N;i++){
  35. stv[i][k]=min(stv[i][k-1],stv[i-(1<<(k-1))][k-1]);
  36. if(stv[i][k-1]==stv[i][k]) stp[i][k]=stp[i][k-1];
  37. else stp[i][k]=stp[i-(1<<(k-1))][k-1];
  38. }
  39. for(ll i=1,lmin,lmax;i<=N;i++){
  40. lmin=max(1ll,i-B+1); lmax=max(0ll,i-A+1);
  41. if(lmax==0) continue;
  42. pos=query(lmin-1,lmax-1)+1;
  43. q.push((info){pre[i]-pre[pos-1],i,pos,lmin,lmax});
  44. }
  45. while(K--){
  46. now=q.top(); q.pop();
  47. ans+=now.sum;
  48. if(now.p-1>=now.l){
  49. pos=query(now.l-1,now.p-1-1)+1;
  50. q.push((info){pre[now.R]-pre[pos-1],now.R,pos,now.l,now.p-1});
  51. }
  52. if(now.r>=now.p+1){
  53. pos=query(now.p+1-1,now.r-1)+1;
  54. q.push((info){pre[now.R]-pre[pos-1],now.R,pos,now.p+1,now.r});
  55. }
  56. }
  57. printf("%lld",ans);
  58. return 0;
  59. }

●BZOJ 2006 NOI 2010 超级钢琴的更多相关文章

  1. [BZOJ 2006] [NOI 2010]超级钢琴(贪心+ST表+堆)

    [BZOJ 2006] [NOI 2010]超级钢琴(贪心+ST表+堆) 题面 给出一个长度为n的序列,选k段长度在L到R之间的区间,一个区间的值等于区间内所有元素之的和,使得k个区间的值之和最大.区 ...

  2. [NOI 2010]超级钢琴

    Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙 的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙 ...

  3. 解题:NOI 2010 超级钢琴

    题面 WC时候写的题,补一下 做法比较巧妙:记录每个位置和它当前对应区间的左右端点,做前缀和之后重载一下小于号,用优先队列+ST表维护当前最大值.这样贡献就是区间最大值和端点左边差分一下,可以O(1) ...

  4. 【BZOJ 2006】[NOI2010]超级钢琴 ST

    我们先把所有最左端对应的最优右端入堆,eg: z  在[l,r](由题目给出的L,R决定)之间的最优解 y,然后出堆以后,再入堆z,y-1,z,y+1,那么我们只需要用st找最大前缀和就好了(ST是一 ...

  5. JZOJ 5409 Fantasy & NOI 2010 超级钢琴 题解

    其实早在 2020-12-26 的比赛我们就做过 5409. Fantasy 这可是紫题啊 题目大意 给你一个序列,求长度在 \([L,R]\) 区间内的 \(k\) 个连续子序列的最大和 题解 如此 ...

  6. [bzoj 2005][NOI 2010]能量采集(容斥原理+递推)

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2005 分析:首先易得ans=∑gcd(x,y)*2+1 然后我就布吉岛了…… 上网搜了下题解, ...

  7. ●BZOJ 2007 NOI 2010 海拔

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2007 题解: 网络流.最小割.对偶图 奇妙的题 ~ 种种原因导致了高度要么为 0,要么为 1 ...

  8. ●BZOJ 2005 NOI 2010 能量采集

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2005 题解: 一个带有容斥思想的递推.%%% 首先,对于一个点 (x,y) 在路径 (0,0 ...

  9. bzoj 2005 NOI 2010 能量采集

    我们发现对于一个点(x,y),与(0,0)连线上的点数是gcd(x,y)-1 那么这个点的答案就是2*gcd(x,y)-1,那么最后的答案就是所有点 的gcd值*2-n*m,那么问题转化成了求每个点的 ...

随机推荐

  1. python中使用flask时遇到的markupsafe._compat包缺失的问题与解决

    环境:windows7 + python3.6.0 在尝试使用python的flask时,按照flask的tutorial操作,装好flask.venv后,对tutorial中的hello.py进行运 ...

  2. 初谈Git(本机克隆项目远程仓库)

    1. 码云注册与新建项目 注册并新建项目 2. Git安装并配置 安装 配置 3. clone项目 附:一些Git命令 git clone 拷贝并跟踪远程的master分支 git add 跟踪新文件 ...

  3. 视图和URL配置

    视图和URL配置 实验简介 上一章里我们介绍了如何创建一个Django项目并启动Django的开发服务器.本章你将学到用Django创建动态网页的基本知识. 同时,也教会大家怎么在本地机器上建立一个独 ...

  4. IOS UITextView自适应高度

    LOFTER app需要实现了一个类似iPhone短信输入框的功能,它的功能其实蛮简单,就是:[UITextView的高度随着内容高度的变化而变化].实现思路应该是: 在UITextView的text ...

  5. 从数据恢复角度解析RAID6结构原理

    [什么是RAID]    RAID的概念描述在互联网上比比皆是,用最简单的原理描述,就是在定义存储方式时允许在一部分数据缺失的情况下不影响全部数据,类似于通讯领域的纠错码.不同的冗余模式形成了不同的R ...

  6. thinkphp中的常见静态常亮

    thinkphp __PUBLIC__的定义 __ROOT__等常量的定义 1 2 3 4 5 6 7 8 9 '__TMPL__'      =>  APP_TMPL_PATH,  // 项目 ...

  7. 点开GitHub之后,瑟瑟发抖...的我

    我说句实在话啊,GitHub这个网址真的很能勾起人学习的欲望,一进入GitHub的注册页面真的让我这个英语学渣瑟瑟发抖,瞬间立下个flag:好好学习英语..... 我对python的求知欲怎么能被英语 ...

  8. webpack你值得拥有-从四个核心配置谈起

    很久没有发文章了,但是强调一点,大-熊同学最近可没闲着.学习算法,复习计算机网络,也顺便学习了一下webpack,看了看操作系统(没办法,都没学,要是不学连实习笔试都过不了,伤心--).本来比较纠结是 ...

  9. Python内置函数(31)——object

    英文文档: class objectReturn a new featureless object. object is a base for all classes. It has the meth ...

  10. java程序员最不愿意看到的十件事

     0.遍历结果集并构造对象如果你是个时髦的开发者而不是专业人员,显然你从某篇博客中读过有开发者遇到Hibernate的“性能问题”,因而认为ORM都不好,觉得手动编码“明显更好”.喜欢的话你当然可以用 ...