题链:

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次即可。

代码:

#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#define MAXN 500005
#define ll long long
using namespace std;
struct info{
ll sum,R,p,l,r;
bool operator <(const info & rtm) const{
return sum<rtm.sum;
}
};
ll stv[MAXN][20],stp[MAXN][20],log2[MAXN];
ll pre[MAXN],N,K,A,B,ans;
priority_queue<info>q;
ll query(ll l,ll r){
static ll k,mini;
k=log2[r-l+1];
mini=min(stv[l+(1<<k)-1][k],stv[r][k]);
if(stv[l+(1<<k)-1][k]==mini) return stp[l+(1<<k)-1][k];
else return stp[r][k];
}
int main()
{
freopen("piano.in","r",stdin);
freopen("piano.out","w",stdout);
log2[1]=0; ll pos; info now;
for(ll i=2;i<=MAXN-5;i++) log2[i]=log2[i>>1]+1;
scanf("%lld%lld%lld%lld",&N,&K,&A,&B);
for(ll i=1;i<=N;i++)
scanf("%lld",&pre[i]),pre[i]+=pre[i-1],stv[i][0]=pre[i],stp[i][0]=i;
for(ll k=1;k<=log2[N];k++)
for(ll i=(1<<k)-1;i<=N;i++){
stv[i][k]=min(stv[i][k-1],stv[i-(1<<(k-1))][k-1]);
if(stv[i][k-1]==stv[i][k]) stp[i][k]=stp[i][k-1];
else stp[i][k]=stp[i-(1<<(k-1))][k-1];
}
for(ll i=1,lmin,lmax;i<=N;i++){
lmin=max(1ll,i-B+1); lmax=max(0ll,i-A+1);
if(lmax==0) continue;
pos=query(lmin-1,lmax-1)+1;
q.push((info){pre[i]-pre[pos-1],i,pos,lmin,lmax});
}
while(K--){
now=q.top(); q.pop();
ans+=now.sum;
if(now.p-1>=now.l){
pos=query(now.l-1,now.p-1-1)+1;
q.push((info){pre[now.R]-pre[pos-1],now.R,pos,now.l,now.p-1});
}
if(now.r>=now.p+1){
pos=query(now.p+1-1,now.r-1)+1;
q.push((info){pre[now.R]-pre[pos-1],now.R,pos,now.p+1,now.r});
}
}
printf("%lld",ans);
return 0;
}

●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. 单向链表在O(1)时间内删除一个节点

    说删链表节点,第一时间想到就是遍历整个链表,找到删除节点的前驱,改变节点指向,删除节点,但是,这样删除单链表的某一节点,时间复杂度就是O(n),不符合要求: 时间复杂度是O(n)的做法就不说了,看看O ...

  2. Beta冲刺Day7

    项目进展 李明皇 今天解决的进度 部分数据传递和使用逻辑测试 林翔 今天解决的进度 服务器端查看个人发布的action,修改已发布消息状态的action,仍在尝试使用第三方云存储功能保存图片 孙敏铭 ...

  3. pandas 使用

    ss = [['xx','m',22],['cc','w',33],['jj','w',44],['qq','m',11]] import pandas as pd df = pd.DataFrame ...

  4. JAVA_SE基础——59.权限访问修饰符

    了解了包的概念,就可以系统的介绍Java中的访问控制级别.在Java中,针对类.成员方法和属性提供了四种访问级别,分别是private.default.protected和public. 权限访问修饰 ...

  5. 使用JDBC中的出现的乱码和查询无结果问题

    使用JDBC中的问题 连接的后出现查询结果是乱码. 1.可能是代码的编码与数据库的编码不同 ​ 有可以将二者都设置为UTF-8 2.如果比较懒得话可以只设代码为UTF-8 mysql 连接url中us ...

  6. 基于ssm的poi反射bean实例

    一:该例子是笔者在实际项目应用过程中,针对项目完成的一套基于poi的导入导出例子,其中一些与项目有关的代码大家直接替换成自己的需求即可. 二:笔者在项目中使用的是poi的XSSF,对应maven的po ...

  7. JAVA工程师面试题【来自并发编程网】

    基础题: Java线程的状态 进程和线程的区别,进程间如何通讯,线程间如何通讯 HashMap的数据结构是什么?如何实现的.和HashTable,ConcurrentHashMap的区别 Cookie ...

  8. GIT入门笔记(9)- git的add和commit机制原理

    工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库. Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支mas ...

  9. H5的canvas绘图技术

    canvas元素是HTML5中新添加的一个元素,该元素是HTML5中的一个亮点.Canvas元素就像一块画布,通过该元素自带的API结合JavaScript代码可以绘制各种图形和图像以及动画效果. 1 ...

  10. [洛谷P1198/BZOJ1012][JSOI2008] 最大数 - 树状数组/线段树?

    其实已经学了树状数组和线段树,然而懒得做题,所以至今没写多少博客 Description 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数 ...