题解 【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)$,表示左 ...
随机推荐
- dev控件学习笔记之----CxGrid
本人总结的DEV学习:希望对大家有所帮助. 一.是否显示分组工具: 二.表格左边记录信息显示的宽度: 三.设置表格行高: 四.表头文件的水平和垂直设置:多个设置用按住SHIFT后进行多选,然后就可以设 ...
- 【LOJ】#3046. 「ZJOI2019」语言
LOJ#3046. 「ZJOI2019」语言 先orz zsy吧 有一个\(n\log^3n\)的做法是把树链剖分后,形成logn个区间,这些区间两两搭配可以获得一个矩形,求矩形面积并 然后就是对于一 ...
- _variant_t 与其他数据类型的转换
在COM中使用的标准类Class如下所示: _bstr_t:对BSTR类型进行打包,并提供有用的操作方法: _com_error:定义抛出的error对象; _com_ptr_t:封装COM接口指针 ...
- MySQL之主键
一.主键 primary key (唯一标识 .不能重复.不能为空) 1.主键-----是表中的字段,这个字段能唯一标识一条记录.例如 学生表(学号.姓名,年级)里的学号,不能重复.不能为空: 课程 ...
- Codeforces 1238F. The Maximum Subtree
传送门 考虑构造一些区间使得树尽可能的 "大" 发现这棵树最多就是一条链加上链上出去的其他边连接的点 构造的区间大概长这样(图比较丑请谅解..$qwq$,图中每一个 "└ ...
- nodejs+gulp+webpack基础知识
nodejs+gulp+webpack基础知识 2019年08月22日 11:49:40 天府云创 阅读数 22 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文 ...
- .net get set用法
在早期学习c#的过程中,经常遇到这样的语句: public string StudentName{ get{return stuName;} set{stuNa ...
- AutoCAD2013 以上利用AccoreConsole+ c# NetApi Windows Froms 封装
1# 封装类 public static class CmdHelper { /// <summary> /// 调用AutoCAD 安装目录下的AccoreConsole.exe来实现批 ...
- Java并发编程——线程池
本文的目录大纲: 一.Java中的ThreadPoolExecutor类 二.深入剖析线程池实现原理 三.使用示例 四.如何合理配置线程池的大小 一.Java中的ThreadPoolExecutor类 ...
- 用最少的JS代码写出贪吃蛇游戏---迷你版
游戏进行页面展示 GAME OVER 页面展示 代码如下: <!doctype html> <html> <body> <canvas id=&q ...