【NOI2010】超级钢琴 题解(贪心+堆+ST表)
题目大意:求序列内长度在$[L,R]$范围内前$k$大子序列之和。
----------------------
考略每个左端点$i$,合法的区间右端点在$[i+L,i+R]$内。
不妨暴力枚举所有左端点,找到以其为左端点满足条件的最大子序列。
用贪心的思想,这些序列一定是满足题意的。统计后将该序列删除。
但这样直接删除肯定会丢失一部分有用的序列。一些也在前$k$大范围内的序列可能跟删除部分有交集。
所以我们不妨设$maxi$指以$i$为左端点的子序列,以$maxi$为右端点时能取得最大值。从此处将原先的大区间$[i+L,i+R]$裂解成两个区间$[i+L,maxi-1]$和$[maxi+1,i+R]$。从这两个区间中再找较大的满足条件的序列。
维护显然用堆。设一个五元组$(v,i,l,r,w)$表示以$i$为左端点,右端点在$[i+L,i+R]$内时,能找出以$w$为右端点的最大值为$v$的子序列。以$v$作为关键字,建立大根堆维护即可。
最后一个问题就是查找。我们不妨预处理出前缀和,用前缀和查找子序列的和。最大值用$ST$表维护。
代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=;
int f[N][],pos[N][];
int n,k,l,r,op;
long long ans;
int maxn,maxi;
struct node
{
int v,i,l,r,w;
}t,tmp;
bool operator <(const node &a,const node &b)
{
return a.v<b.v;
}
priority_queue<node> q;
inline void RMQ(int l,int r)
{
int opt=log2(r-l+);
if (f[l][opt]>=f[r-(<<opt)+][opt]) maxn=f[l][opt],maxi=pos[l][opt];
else maxn=f[r-(<<opt)+][opt],maxi=pos[r-(<<opt)+][opt];
}
signed main()
{
memset(f,,sizeof(f));
f[][]=;
scanf("%lld%lld%lld%lld",&n,&k,&l,&r);
op=log2(n);
for (int i=;i<=n;i++)
{
scanf("%lld",&f[i][]);
pos[i][]=i;
f[i][]+=f[i-][];
}
for (int t=;t<=op;t++)
for (int i=;i<=n;i++) if (i+(<<(t-))->n) break;
else
{
if (f[i][t-]>=f[i+(<<(t-))][t-]) f[i][t]=f[i][t-],pos[i][t]=pos[i][t-];
else f[i][t]=f[i+(<<(t-))][t-],pos[i][t]=pos[i+(<<(t-))][t-];
}
for (int i=;i<=n-l+;i++)
{
RMQ(i+l-,i+min(n-i,r-));
t.v=maxn-f[i-][],t.i=i,t.l=i+l-,t.r=i+min(n-i,r-),t.w=maxi;
q.push(t);
}
while(k--)
{
t=q.top();
q.pop();
ans+=t.v;
if (t.w>t.l)
{
RMQ(t.l,t.w-);
tmp.v=maxn-f[t.i-][],tmp.i=t.i,tmp.l=t.l,tmp.r=t.w-,tmp.w=maxi;
q.push(tmp);
}
if (t.w<t.r)
{
RMQ(t.w+,t.r);
tmp.v=maxn-f[t.i-][],tmp.i=t.i,tmp.l=t.w+,tmp.r=t.r,tmp.w=maxi;
q.push(tmp);
}
}
printf("%lld",ans);
return ;
}
【NOI2010】超级钢琴 题解(贪心+堆+ST表)的更多相关文章
- BZOJ_2006_[NOI2010]超级钢琴_贪心+堆+ST表
BZOJ_2006_[NOI2010]超级钢琴_贪心+堆+ST表 Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的 音乐 ...
- P2048 [NOI2010]超级钢琴(RMQ+堆+贪心)
P2048 [NOI2010]超级钢琴 区间和--->前缀和做差 多次查询区间和最大--->前缀和RMQ 每次取出最大的区间和--->堆 于是我们设个3元组$(o,l,r)$,表示左 ...
- BZOJ2006:[NOI2010]超级钢琴——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=2006 https://www.luogu.org/problemnew/show/P2048#su ...
- [NOI2010]超级钢琴(RMQ+堆)
小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度为Ai,其中Ai可正可负 ...
- [NOI2010] 超级钢琴 - 贪心,堆,ST表
这也算是第K大问题的套路题了(虽然我一开始还想了个假算法),大体想法就是先弄出最优的一批解,然后每次从中提出一个最优解并转移到一个次优解,用优先队列维护这个过程即可. 类似的问题很多,放在序列上的,放 ...
- 洛谷P2048 [NOI2010]超级钢琴 题解
2019/11/14 更新日志: 近期发现这篇题解有点烂,更新一下,删繁就简,详细重点.代码多加了注释.就酱紫啦! 正解步骤 我们需要先算美妙度的前缀和,并初始化RMQ. 循环 \(i\) 从 \(1 ...
- BZOJ 2006 NOI2010 超级钢琴 划分树+堆
题目大意:给定一个序列.找到k个长度在[l,r]之间的序列.使得和最大 暴力O(n^2logn),肯定过不去 看到这题的第一眼我OTZ了一下午... 后来研究了非常久别人的题解才弄明确怎么回事...蒟 ...
- Bzoj 2006: [NOI2010]超级钢琴 堆,ST表
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2222 Solved: 1082[Submit][Statu ...
- [BZOJ2006][NOI2010]超级钢琴(ST表+堆)
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 3679 Solved: 1828[Submit][Statu ...
随机推荐
- 结合SpEL使用@Value-基于配置文件或非配置的文件的值注入-Spring Boot
本文主要介绍Spring @Value 注解注入属性值的使用方法的分析,文章通过示例代码非常详细地介绍,对于每个人的学习或工作都有一定的参考学习价值 在使用spring框架的项目中,@Value是经常 ...
- web前端 javascript 兼容低版本 IE 6 7 8复合写法
1. 返回检测屏幕宽度(可视区域) function client() { if(window.innerWidth != null) // ie9 + 最新浏览器 { return { width: ...
- 02-Python运算符
一.简介 以10 - 5为例,‘10 - 5’叫做表达式,表达式可以分解成运算符和操作数.整数10和5被称为操作数.‘-’称为运算符. 二.算术运算符 运算符 描述 示例 结果 + 加 - 两个对象相 ...
- Python Ethical Hacking - Basic Concetion
What is Hacking? Gaining unauthorized access. Hackers? 1.Black-hat Hackers 2.White-hat Hackers 3.Gre ...
- MSSQL系列 (一):数据库的相关操作(增删改查)
1.创建数据库 --创建数据库 create database stuDb on primary ( --表示属于primary文件组 name='stuDb', --逻辑名称 fileName='D ...
- JVM——内存区域:运行时数据区域详解
关注微信公众号:CodingTechWork,一起学习进步. 引言 我们经常会被问到一个问题是Java和C++有何区别?我们除了能回答一个是面向对象.一个是面向过程编程以外,我们还会从底层内存管理 ...
- 2.UDP协议
UDP只在IP数据报服务之上增加了很少功能,即复用分用和差错检测功能. 应用层给UDP多长的报文,UDP就照样发送,即一次发送一个完整报文 一.UDP首部格式 这里的长度是指(首部+数据) UDP校验 ...
- 写给程序员的机器学习入门 (八) - 卷积神经网络 (CNN) - 图片分类和验证码识别
这一篇将会介绍卷积神经网络 (CNN),CNN 模型非常适合用来进行图片相关的学习,例如图片分类和验证码识别,也可以配合其他模型实现 OCR. 使用 Python 处理图片 在具体介绍 CNN 之前, ...
- win10里面怎么获取最高管理员权限
Windows10专业版 1,按下win+R键唤出“运行”窗口,输入gpedit.msc. 2,这时打开了组策略编辑器,在左边找到“计算机配置-Windows 设置”,再进入右边“安全设置”,如图. ...
- 题解 洛谷 P3825 【[NOI2017]游戏】
从题面中四元组\((i,h_i,j,h_j)\)限制选择车子型号,不难想到这题要用\(2-SAT\)解决. 考虑转化为\(2-SAT\)模型,发现除地图\(x\)外,其他地图都只有两种车子型号可以参加 ...