[NOI 2010]超级钢琴
Description
Input
Output
Sample Input
4 3 2 3
3
2
-6
8
Sample Output
11
Hint
共有5种不同的超级和弦:音符1 ~ 2,美妙度为3 + 2 = 5
音符2 ~ 3,美妙度为2 + (-6) = -4
音符3 ~ 4,美妙度为(-6) + 8 = 2
音符1 ~ 3,美妙度为3 + 2 + (-6) = -1
音符2 ~ 4,美妙度为2 + (-6) + 8 = 4
最优方案为:乐曲由和弦1,和弦3,和弦5组成,美妙度为5 + 2 + 4 = 11。
n,k<=500,000
题目大意
求长度在[L,R]之间的最大的K个子序列的和
题解
考虑每个左端点$i$,合法的区间的右端点会在$[i+L,i+R]$内。
不妨枚举所有左端点,找到以其为左端点,满足题意的最大子序列。
用贪心的思想,显然这些序列中最大的一定是满足题意的,统计后将该序列删除。
但若删除,就意味着以i为左端的序列都被排除,显然会流失掉一些有用的值。
原来的区间$[i+L,i+R]$,假设在$maxi$处取得最大值,我们不妨将其裂解成两个区间$[i+L,maxi-1]$,$[maxi+1,i+R]$并分别找出在这两个小区间内的最大值,将他们加入待选序列中。
显然维护就直接用堆,堆中记录一个5元组$(v,i,l,r,w)$分别表示该子序列的值$v$,左端点的位置$i$,右端点的区间$[l,r]$和去最值的右端点的位置$w$,以$v$为关键字,建大根堆。
最后一个问题就是查找了,我们不妨预处理出前缀和。已知$i~j$的序列的值为$sum[j]-sum[i-1]$,既然左端点固定,那么只要找右端点处的$sum$最大值即可。用$RMQ$实现查找区间最大值。
#include<map>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define LL long long
#define RE register
#define IL inline
using namespace std;
const int N=; IL int Max(int a,int b){return a>b ? a:b;}
IL int Min(int a,int b){return a<b ? a:b;} 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; int n,k,l,r,op;
LL ans;
int f[N+][],where[N+][]; int maxn,maxi;
IL void RMQ(int l,int r)//查询最值
{
int opt=log2(r-l+);
if (f[l][opt]>=f[r-(<<opt)+][opt]) maxn=f[l][opt],maxi=where[l][opt];
else maxn=f[r-(<<opt)+][opt],maxi=where[r-(<<opt)+][opt];
} int main()
{
memset(f,,sizeof(f));
f[][]=;
scanf("%d%d%d%d",&n,&k,&l,&r);
op=log2(n);
for (int i=;i<=n;i++)
{
scanf("%d",&f[i][]);
where[i][]=i;
f[i][]+=f[i-][];
}
for (int t=;t<=op;t++)
for (int i=;i<=n;i++) if (i+(<<(t-))->n) break;
else//倍增,where记录取最值的位置
{
if (f[i][t-]>=f[i+(<<(t-))][t-]) f[i][t]=f[i][t-],where[i][t]=where[i][t-];
else f[i][t]=f[i+(<<(t-))][t-],where[i][t]=where[i+(<<(t-))][t-];
}
for (int i=;i<=n-l+;i++)
{
RMQ(i+l-,i+Min(r-,n-i));
t.v=maxn-f[i-][],t.i=i,t.l=i+l-,t.r=i+Min(r-,n-i),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\n",ans);
return ;
}
[NOI 2010]超级钢琴的更多相关文章
- [BZOJ 2006] [NOI 2010]超级钢琴(贪心+ST表+堆)
[BZOJ 2006] [NOI 2010]超级钢琴(贪心+ST表+堆) 题面 给出一个长度为n的序列,选k段长度在L到R之间的区间,一个区间的值等于区间内所有元素之的和,使得k个区间的值之和最大.区 ...
- ●BZOJ 2006 NOI 2010 超级钢琴
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2006 题解: RMQ + 优先队列 (+ 前缀) 记得在一两个月前,一次考试考了这个题目的简 ...
- 解题:NOI 2010 超级钢琴
题面 WC时候写的题,补一下 做法比较巧妙:记录每个位置和它当前对应区间的左右端点,做前缀和之后重载一下小于号,用优先队列+ST表维护当前最大值.这样贡献就是区间最大值和端点左边差分一下,可以O(1) ...
- JZOJ 5409 Fantasy & NOI 2010 超级钢琴 题解
其实早在 2020-12-26 的比赛我们就做过 5409. Fantasy 这可是紫题啊 题目大意 给你一个序列,求长度在 \([L,R]\) 区间内的 \(k\) 个连续子序列的最大和 题解 如此 ...
- 题解 【NOI2010】超级钢琴
[NOI2010]超级钢琴 Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号 ...
- BZOJ 2006: [NOI2010]超级钢琴
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2613 Solved: 1297[Submit][Statu ...
- 【BZOJ-2006】超级钢琴 ST表 + 堆 (一类经典问题)
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2473 Solved: 1211[Submit][Statu ...
- bzoj2006 noi2010 超级钢琴 主席树 + 优先队列
Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2435 Solved: 1195 Description 小 Z是一个小有名气的钢琴家,最近C博士送 ...
- 2006: [NOI2010]超级钢琴 - BZOJ
Description小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度为 ...
随机推荐
- XMAN-level4
[XMAN] level4 首先checksec,信息如下 [*] '/root/Desktop/bin/pwn/xman-level4/level4' Arch: i386-32-little RE ...
- 有序的map LinkedHashMap
HashMap是无序的,HashMap在put的时候是根据key的hashcode进行hash然后放入对应的地方.所以在按照一定顺序put进HashMap中,然后遍历出HashMap的顺序跟put的顺 ...
- 获取android项目的数据库地址或者数据库名
你不需要知道该路径.只是使用数据库,你可以将它们删除的列表. for (String databaseName : context.databaseList()) { context.deleteDa ...
- PostgreSQL 配置安装
Mac 安装 http://postgresapp.com/ 创建和删除数据库用户 对应命令如下(在postgres=# 环境下):1.查看数据库用户列表: \du2.创建数据库用户: create ...
- 基于协程的Python网络库gevent
import gevent def test1(): print 12 gevent.sleep(0) print 34 def test2(): print 56 gevent.sleep(0) p ...
- Struts2之Struts2的标签库
前言: Struts2提供了大量的标签 ,用来帮助开发表现层页面,这些表现一方面解决了美观性的需求,因为它们具有html标签一样的外观,另一方面它们解决了功能性的需求, 因为它们具有jsp脚本一样的逻 ...
- 在ArcGIS中导出现有mxd的style文件
做好的地图包含许多地图符号,这是之前花了很多功夫做的,怎么把它导出来再用呢? 在ArcGIS中右键工具栏,customize,选择command选项卡,在搜索框中输入style ,选择too ...
- python之路--day13-模块
1,什么是模块 模块就是系统功能的集合体,在python中,一个py文件就是一个模块, 例如:module.py 其中module叫做模块名 2,使用模块 2.1 import导入模块 首次带入模块发 ...
- Java 持久化操作之 --io流与序列化
1)File类操作文件的属性 1.File类的常用方法 1. 文件的绝对完整路径:getAbsolutePath() 文件名:getName() 文件相对路径:getPath() 文件的上一级目录:g ...
- Ajax 调用webservice 解决跨域请求和发布到服务器后本地调用成功外网失败的问题
webservice 代码 /// <summary> /// MESService 的摘要说明 /// </summary> [WebService(Namespac ...