【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】超级钢琴的更多相关文章

  1. 【题解】P2048 [NOI2010]超级钢琴

    [题解][P2048 NOI2010]超级钢琴 一道非常套路的题目.是堆的套路题. 考虑前缀和,我们要是确定了左端点,就只需要在右端区间查询最大的那个加进来就好了.\(sum_j-sum_{i-1}​ ...

  2. BZOJ 2006: [NOI2010]超级钢琴

    2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 2613  Solved: 1297[Submit][Statu ...

  3. Bzoj 2006: [NOI2010]超级钢琴 堆,ST表

    2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 2222  Solved: 1082[Submit][Statu ...

  4. NOI2010超级钢琴 2

    2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 1296  Solved: 606[Submit][Status ...

  5. [洛谷P2048] [NOI2010] 超级钢琴

    洛谷题目链接:[NOI2010]超级钢琴 题目描述 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号 ...

  6. 【BZOJ2006】[NOI2010]超级钢琴 ST表+堆

    [BZOJ2006][NOI2010]超级钢琴 Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以 ...

  7. BZOJ 2006: [NOI2010]超级钢琴( RMQ + 堆 )

    取最大的K个, 用堆和RMQ来加速... ----------------------------------------------------------------- #include<c ...

  8. BZOJ_2006_[NOI2010]超级钢琴_贪心+堆+ST表

    BZOJ_2006_[NOI2010]超级钢琴_贪心+堆+ST表 Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的 音乐 ...

  9. bzoj2006 [NOI2010]超级钢琴 (及其拓展)

    bzoj2006 [NOI2010]超级钢琴 给定一个序列,求长度在 \([L,\ R]\) 之间的区间和的前 \(k\) 大之和 \(n\leq5\times10^5,\ k\leq2\times1 ...

  10. P2048 [NOI2010]超级钢琴(RMQ+堆+贪心)

    P2048 [NOI2010]超级钢琴 区间和--->前缀和做差 多次查询区间和最大--->前缀和RMQ 每次取出最大的区间和--->堆 于是我们设个3元组$(o,l,r)$,表示左 ...

随机推荐

  1. SQL 查看某个表被哪些存储过程或者视图使用

    --查询某个表被哪些视图/存储过程使用(type='P':表示存储过程,type='V':表示视图) SELECT OBJECT_NAME(id) FROM syscomments WHERE id ...

  2. redis5.0 数据结构与命令

    1.redis 支持如下5种数据结构 数据结构 说明 简介 String 字符串 key-val Hash 哈希 filed-val 映射表 List 列表 双向链表 Set 集合 element(元 ...

  3. F. 汤圆防漏理论

    ghc很喜欢吃汤圆,但是汤圆很容易被粘(zhān)漏. 根据多年吃汤圆经验,ghc总结出了一套汤圆防漏理论: 互相接触的汤圆容易粘(zhān)在一起,并且接触面积不同,粘(zhān)在一起的粘(niá ...

  4. hdu4706

    #include<string.h> #include<stdio.h> int main() { int a,b,c,d,i,j,n,m; ][]; ,j=; a<=; ...

  5. Windows 安装和配置 WSL

    Windows 安装和配置 WSL 什么是 WSL 引用百度百科的一段话: Windows Subsystem for Linux(简称WSL)是一个为在Windows 10上能够原生运行Linux二 ...

  6. C#进阶之泛型(Generic)

    1.泛型 泛型是framwork2.0推出的新语法,具有延迟声明的特点:把参数类型的声明推迟到调用的时候.泛型不是一个语法糖,是框架升级提供的功能.需要编辑器和JIT(just-in-time com ...

  7. 移动端真机debug调试神器 vConsole学习(一)之基础

    参考 使用方法 移动端真机debug调试神器 vConsole的引入说明(原生态与WebPack) 移动端使用vconsole调试console vConsole ——开源的前端 console 调试 ...

  8. JS基础_while循环

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  9. svn安装方法

    1.下载site-1.6.5svn插件 2.

  10. canva绘制圆角矩形

    在做组态的时候,需要支持矩形圆角格式,但是因为canvas本身不带有圆角矩形,需要自行算出坐标进行绘制 方案一.统一圆角 <!DOCTYPE html> <html> < ...