【bzoj2006】[NOI2010]超级钢琴 倍增RMQ+STL-堆
题目描述
输入
输出
只有一个整数,表示乐曲美妙度的最大值。
样例输入
4 3 2 3
3
2
-6
8
样例输出
11
题解
倍增RMQ(貌似这个叫做ST表)+STL-堆
首先我们将连续子序列和转化为前缀和相减,那么对于每个左端点,找它的右端点,就转变为求某范围内前缀和的最大值、次大值、...
但是直接拿出整个序列显然会TLE+MLE。
我们考虑,如果左端点t,右端点[l,r],我们找出属于[l,r]的位置p,使得sum[p]最大。那么很显然,当且仅当p被选择之后,[l,p-1]和[p+1,r]内的右端点才可能会被选择。
所以我们可以维护一个结构体,储存t、l、r、p、v,分别表示左端点、右端点区间的左位置、右端点区间的右位置、右端点区间最大值的位置、右端点区间最大值,显然v=sum[p]-sum[t-1]。我们优先选择v较大的区间把它拿出来,把它的v加入到答案中。然后考虑剩下的[l,p-1]和[p+1,r],如果存在这些区间的话,采取相同的方式处理即可。这个过程显然可以使用堆来维护。
维护区间最大值即位置。可以使用倍增RMQ来解决,时间复杂度更低一些。
因此总的时间复杂度为$O((n+k)\log n)$
另外需要注意的是priority_queue需要重载<运算符,而不是>(尽管它是大根堆)
#include <cstdio>
#include <queue>
#define N 500010
using namespace std;
struct data
{
int t , b , e , v , p;
data() {}
data(int t0 , int b0 , int e0 , int v0 , int p0) {t = t0 , b = b0 , e = e0 , v = v0 , p = p0;}
bool operator<(const data a)const {return v < a.v;}
}tmp;
priority_queue<data> q;
int sum[N] , maxn[N][20] , maxp[N][20] , log[N];
int getmaxn(int x , int y)
{
int k = log[y - x + 1];
return max(maxn[x][k] , maxn[y - (1 << k) + 1][k]);
}
int getmaxp(int x , int y)
{
int k = log[y - x + 1];
return maxn[x][k] > maxn[y - (1 << k) + 1][k] ? maxp[x][k] : maxp[y - (1 << k) + 1][k];
}
int main()
{
int n , k , l , r , i , j , x , y;
long long ans = 0;
scanf("%d%d%d%d" , &n , &k , &l , &r);
for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &x) , sum[i] = sum[i - 1] + x , maxn[i][0] = sum[i] , maxp[i][0] = i;
for(i = 2 ; i <= n ; i ++ ) log[i] = log[i >> 1] + 1;
for(i = 1 ; i <= log[n] ; i ++ )
{
for(j = 1 ; j <= n - (1 << i) + 1 ; j ++ )
{
if(maxn[j][i - 1] > maxn[j + (1 << (i - 1))][i - 1]) maxn[j][i] = maxn[j][i - 1] , maxp[j][i] = maxp[j][i - 1];
else maxn[j][i] = maxn[j + (1 << (i - 1))][i - 1] , maxp[j][i] = maxp[j + (1 << (i - 1))][i - 1];
}
}
for(i = 1 ; i <= n - l + 1 ; i ++ ) x = i + l - 1 , y = min(i + r - 1 , n) , q.push(data(i , x , y , getmaxn(x , y) - sum[i - 1] , getmaxp(x , y)));
while(k -- )
{
tmp = q.top() , q.pop() , ans += tmp.v;
if(tmp.p > tmp.b) x = tmp.b , y = tmp.p - 1 , q.push(data(tmp.t , x , y , getmaxn(x , y) - sum[tmp.t - 1] , getmaxp(x , y)));
if(tmp.p < tmp.e) x = tmp.p + 1 , y = tmp.e , q.push(data(tmp.t , x , y , getmaxn(x , y) - sum[tmp.t - 1] , getmaxp(x , y)));
}
printf("%lld\n" , ans);
return 0;
}
【bzoj2006】[NOI2010]超级钢琴 倍增RMQ+STL-堆的更多相关文章
- [NOI2010]超级钢琴 倍增
[NOI2010]超级钢琴 倍增 题面 暴力:枚举区间丢入堆\(O(n^2logn)\) 正解:考虑每次枚举和弦起点\(s\),那么以\(s\)为起点的和弦为\(sum[t]-sum[s](s+L-1 ...
- bzoj2006 [NOI2010]超级钢琴 (及其拓展)
bzoj2006 [NOI2010]超级钢琴 给定一个序列,求长度在 \([L,\ R]\) 之间的区间和的前 \(k\) 大之和 \(n\leq5\times10^5,\ k\leq2\times1 ...
- BZOJ2006 [NOI2010]超级钢琴 【堆 + RMQ】
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MB Submit: 3446 Solved: 1692 [Submit][Sta ...
- P2048 [NOI2010]超级钢琴(RMQ+堆+贪心)
P2048 [NOI2010]超级钢琴 区间和--->前缀和做差 多次查询区间和最大--->前缀和RMQ 每次取出最大的区间和--->堆 于是我们设个3元组$(o,l,r)$,表示左 ...
- [BZOJ2006][NOI2010]超级钢琴(ST表+堆)
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 3679 Solved: 1828[Submit][Statu ...
- 【BZOJ 2006】2006: [NOI2010]超级钢琴(RMQ+优先队列)
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2792 Solved: 1388 Description 小 ...
- bzoj千题计划162:bzoj2006: [NOI2010]超级钢琴
http://www.lydsy.com/JudgeOnline/problem.php?id=2006 输出最大的k个 sum[r]-sum[l-1] (L<=r-l+1<=R) 之和 ...
- [BZOJ2006] [NOI2010]超级钢琴 主席树+贪心+优先队列
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 3591 Solved: 1780[Submit][Statu ...
- [NOI2010]超级钢琴(RMQ+堆)
小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度为Ai,其中Ai可正可负 ...
随机推荐
- 转:Zookeeper客户端Curator使用详解
原文:https://www.jianshu.com/p/70151fc0ef5d Zookeeper客户端Curator使用详解 前提 最近刚好用到了zookeeper,做了一个基于SpringBo ...
- Java基础题:集合、String、性能、线程
转载自:Java基础题 https://yq.aliyun.com/articles/601786?utm_content=m_1000001149
- IDEA中使用插件添加更多可选择的主题,使代码高亮,缓解视觉疲劳
1.点击 File-->settings(或Ctrl+Shift+S)打开IDE设置面板 点击plugins-->右侧选择Marketplace-->搜索框中输入Material-- ...
- 来自一枚初生牛犊不怕虎的小菜鸟的Mock.js使用,不足之处欢迎读者的指出 谢谢
本文章写的是基于require的mock.js的几种常用生成随机数据和ajax模拟前后端的交互信息 <script src="./app/libs/require.js"&g ...
- 常见的Dom操作
1.什么是DOM? DOM又称文档对象模型( DOM, Document Object Model )主要用于对HTML和XML文档的内容进行操作.DOM描绘了一个层次化的节点树,通过对节点进行操作, ...
- MySQL wait_timeout参数修改
MySQL wait_timeout参数修改问题,可能经常会有DBA遇到过,下面就试验一下并看看会有什么现象. wait_timeout分为global级及session级别,如未进行配置,默认值为2 ...
- git push之后回滚(撤销)代码
问题描述:首先,先说明一下,为什么会引发这次的话题,是这样的,我做完功能Agit push之后,2个月后需求部门要求不要功能A了,然后需要在没有功能A的基础上开发,怎么办?赶紧回滚代码呀. 然后我用g ...
- scala映射和元组
scala映射,是一对键值对,相当于java中的Map 对偶:由两个值构成的组,形式 : 值1->值2,值1和值2类型不一定要相同,可以理解为对偶就是一个key/value 映射就是对偶的集合 ...
- JavaScript实现判断图片是否加载完成的3种方法整理
JavaScript实现判断图片是否加载完成的3种方法整理 有时候我们在前端开发工作中为了获取图片的信息,需要在图片加载完成后才可以正确的获取到图片的大小尺寸,并且执行相应的回调函数使图片产生某种显示 ...
- 复位自动ID的问题有兩種方法
复位自动ID的问题 有兩種方法: 方法1: truncate table 你的表名 --這樣不但將數據刪除,而且可以重新置位identity屬性的字段. ...