题解 【NOI2010】超级钢琴
【NOI2010】超级钢琴
Description
小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐。
这架超级钢琴可以弹奏出n个音符,编号为1至n。第i个音符的美妙度为Ai,其中Ai可正可负。
一个“超级和弦”由若干个编号连续的音符组成,包含的音符个数不少于L且不多于R。我们定义超级和弦的美妙度为其包含的所有音符的美妙度之和。两个超级和弦被认为是相同的,当且仅当这两个超级和弦所包含的音符集合是相同的。
小Z决定创作一首由k个超级和弦组成的乐曲,为了使得乐曲更加动听,小Z要求该乐曲由k个不同的超级和弦组成。我们定义一首乐曲的美妙度为其所包含的所有超级和弦的美妙度之和。小Z想知道他能够创作出来的乐曲美妙度最大值是多少。
Input
第一行包含四个正整数n, k, L, R。其中n为音符的个数,k为乐曲所包含的超级和弦个数,L和R分别是超级和弦所包含音符个数的下限和上限。
接下来n行,每行包含一个整数Ai,表示按编号从小到大每个音符的美妙度。
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。
数据规模:

所有数据满足:-1000 ≤ Ai ≤ 1000,1 ≤ L ≤ R ≤ n且保证一定存在满足要求的乐曲。
Source
NOI, RMQ, 堆 ,线段树
这应该是道NOI的水题了吧(连我都能做)。。
首先,这题用线段树似乎会被卡掉。。
但这题不需要修改!
因此,我们可以用O(logn)预处理,O(1)询问的ST表。
至于ST表,请移步百度。。。
对于每个节点x,首先求出在区间(x-R,x-L)中与x组成超级和弦的美妙度最大的点p。
然后将x,p,l,r,以及美妙度sum放入一个结构体。
以sum的值维护一个大根堆(可以用优先队列)
接下来,每取出一个美妙度,就再求出在区间(l,p-1)和区间(p+1,r)中与x组成超级和弦的美妙度最大的点p2。
再把他们放入结构体,再放进优先队列就行了!
具体方式请看代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std; inline int gi(){
ll sum=,f=;char ch=getchar();
while(ch>'' || ch<''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){sum=sum*+ch-'';ch=getchar();}
return f*sum;
} struct node{
ll sum,now;
int x,l,r;
friend bool operator < (node a,node b){
return a.sum<b.sum;
}
};
int n,k,l,r,len;
int a[],s[]/*前缀和*/;
int f[][]/*从i开始长度为power(2,j)(包括i)的区间的前缀和最小值*/;
int p[][]/*从i开始长度为power(2,j)(包括i)的区间的前缀和最小值的位置*/;
int t[]/*2的i次方*/,v[]/*满足power(2,p)<=i的最大的p*/;
ll ans=;
priority_queue <node> que; int power(int a,int b){
int r=;
while(b){
if((b&)) r*=a;
a*=a;
b>>=;
}
return r;
} void pre(){
v[]=-;
for(int i=;i<=n;i++){
v[i]=v[i>>]+;
}
for(int j=;j<=;j++){
t[j]=power(,j);
}
for(int i=;i<=n;i++){
f[i][]=s[i];
p[i][]=i;
}
for(int j=;j<=;j++){
for(int i=;i<=n;i++){
int o=j-;
if(i+t[j]>n+) break;
if(f[i][o]<f[i+t[o]][o]){
p[i][j]=p[i][o];
f[i][j]=f[i][o];
}
else{
p[i][j]=p[i+t[o]][o];
f[i][j]=f[i+t[o]][o];
}
}
}
} void add(int i,int l,int r){
if(r<||r<l) return ;
if(l<) l=;
int kk;
int q=v[r-l+];
if(f[l][q]<f[r-t[q]+][q]){
kk=p[l][q];
}
else kk=p[r-t[q]+][q];
node a;
a.x=kk;a.sum=s[i]-s[kk];
a.l=l;a.r=r;
a.now=i;
que.push(a);
} void work(){
for(int i=;i<=n;i++){
add(i,i-r,i-l);
}
for(int i=;i<=k;i++){
node a=que.top();
que.pop();
ans+=a.sum;
add(a.now,a.l,a.x-);
add(a.now,a.x+,a.r);
}
} int main()
{
n=gi();k=gi();l=gi();r=gi();
len=r-l+;
for(int i=;i<=n;i++){
a[i]=gi();
s[i]=s[i-]+a[i];
}
pre();
work();
printf("%lld\n",ans);
return ;
}
题解 【NOI2010】超级钢琴的更多相关文章
- 【题解】P2048 [NOI2010]超级钢琴
[题解][P2048 NOI2010]超级钢琴 一道非常套路的题目.是堆的套路题. 考虑前缀和,我们要是确定了左端点,就只需要在右端区间查询最大的那个加进来就好了.\(sum_j-sum_{i-1} ...
- BZOJ 2006: [NOI2010]超级钢琴
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2613 Solved: 1297[Submit][Statu ...
- Bzoj 2006: [NOI2010]超级钢琴 堆,ST表
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2222 Solved: 1082[Submit][Statu ...
- NOI2010超级钢琴 2
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 1296 Solved: 606[Submit][Status ...
- [洛谷P2048] [NOI2010] 超级钢琴
洛谷题目链接:[NOI2010]超级钢琴 题目描述 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号 ...
- 【BZOJ2006】[NOI2010]超级钢琴 ST表+堆
[BZOJ2006][NOI2010]超级钢琴 Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以 ...
- BZOJ 2006: [NOI2010]超级钢琴( RMQ + 堆 )
取最大的K个, 用堆和RMQ来加速... ----------------------------------------------------------------- #include<c ...
- BZOJ_2006_[NOI2010]超级钢琴_贪心+堆+ST表
BZOJ_2006_[NOI2010]超级钢琴_贪心+堆+ST表 Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的 音乐 ...
- bzoj2006 [NOI2010]超级钢琴 (及其拓展)
bzoj2006 [NOI2010]超级钢琴 给定一个序列,求长度在 \([L,\ R]\) 之间的区间和的前 \(k\) 大之和 \(n\leq5\times10^5,\ k\leq2\times1 ...
- P2048 [NOI2010]超级钢琴(RMQ+堆+贪心)
P2048 [NOI2010]超级钢琴 区间和--->前缀和做差 多次查询区间和最大--->前缀和RMQ 每次取出最大的区间和--->堆 于是我们设个3元组$(o,l,r)$,表示左 ...
随机推荐
- 洛谷 P4198 楼房重建 题解
题面 首先你要知道题问的是什么:使用一种数据结构,动态地维护以1为起点地最长上升子序列(把楼房的高度转化成斜率地序列)的长度: 怎么做?线段树! 我们在线段树上维护两个东西:1.这个区间内斜率的最大值 ...
- 通过using声明改变个别成员的可访问性
C++的语法中通过在派生类中使用using声明可以忽略继承方式 , 而让派生类对于基类的私有和保护成员具有特殊的访问权限 , 甚至可以改变派生类对象对于基类成员的访问权限 . 个人认为这种语法很容易让 ...
- 剑指offer8:青蛙跳台阶
1. 题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果). 2. 思路和方法 青蛙每一次跳跃只有两种选择:一是再跳1级阶梯到 ...
- PDO简单的DB类封装
<?php class DB{ private $dbs = ""; private $fields = "*"; private $tables = n ...
- 解决Spring Boot集成Shiro,配置类使用Autowired无法注入Bean问题
如题,最近使用spring boot集成shiro,在shiroFilter要使用数据库动态给URL赋权限的时候,发现 @Autowired 注入的bean都是null,无法注入mapper.搜了半天 ...
- jdbc插入mysql时间差14个小时的解决方案
在java中new Date()输出的时间是没错的,插入到mysql后少了14个小时,原因是新版jdbc驱动的时区设置问题. 在jdbc连接url最后加上serverTimezone=GMT%2B8即 ...
- 项目实践 hrm项目的设计过程
人事管理系统的设计过程 一.数据库表和持久化类 1.1 进行需求分析,根据功能模块设计数据库表 1.2 设计持久化实体 面向对象分析,即根据系统需求提取出应用中的对象,将这些对象抽象成类,再抽 ...
- Zend 3.3.0安装 ZendOptimizer 3.3.0 for Windows 稳定版 下载
用的某php网站系统今天打开时乱码了(zend 200407...),但phpmyadmin能正常使用: 搜索下,重新安装zend可以解决,系统上原来的版本是Zend 3.3.0:下了个,安装后果然把 ...
- PMP - 风险识别之风险登记册
目录 PMP - 风险识别之风险登记册 1. 风险登记册 1.1 已识别风险的清单 1.2 潜在风险责任人 1.3 潜在风险应对措施清单 2. 相关习题 2.1 风险发生的时候,要实施 风险登记册 上 ...
- 【原创】大叔经验分享(65)spark读取不到hive表
spark 2.4.3 spark读取hive表,步骤: 1)hive-site.xml hive-site.xml放到$SPARK_HOME/conf下 2)enableHiveSupport Sp ...