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

【样例说明】
共有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。

HINT

N<=500,000
k<=500,000
-1000<=Ai<=1000,1<=L<=R<=N且保证一定存在满足条件的乐曲

题意:求前K大的连续区间和的和。

思路:之前遇到过,和堆有关,但是当时太弱,没敢做。所以回来参考了一下别人的代码,学习一下发现也没那么难。

(前辈已经写得很清楚了,我就不重复了。如下:

【转】一类经典的问题:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5783868.html

我们发现,固定左端点ii,能够得到长度满足条件的右端点区间

那么我们定义一个五元组(i,L,R,val,pos),其中,ii表示固定下的左端点,L,R表示右端点存在的区间,val表示右端点存在在这个区间的时候最大的价值,pos表示右端点此时的位置

那么我把这个五元组放到堆中,每次取出val最大的,把这个区间裂解,得到的符合条件的两个新的五元组再加入新的区间

具体就是(i,L,R,val,pos)−−>(i,L,pos−1,val′,pos′)+(i,pos+1,R,val′′,pos′′)

至于如何求val和pos,用ST表记录一下前缀和就可以了。

(自己写起来感觉还是蛮简单的。

#include<bits/stdc++.h>
using namespace std;
const int maxn=;
struct in{
int i,L,R,val,pos;
in(){}
in(int ii,int LL,int RR,int vv,int pp):i(ii),L(LL),R(RR),val(vv),pos(pp){}
bool operator<(const in &a) const{ return val<a.val; }
};
priority_queue<in>q;
int dp[maxn][],pos[maxn][];long long ans;
int getmax(int L,int R) //区间最大的位置
{
int t=log2(R-L+);
if(dp[L][t]>dp[R-(<<t)+][t]) return pos[L][t];
return pos[R-(<<t)+][t];
}
int main()
{
int N,K,LL,RR,i,j;
scanf("%d%d%d%d",&N,&K,&LL,&RR);
for(i=;i<=N;i++) scanf("%d",&dp[i][]);
for(i=;i<=N;i++) dp[i][]+=dp[i-][],pos[i][]=i;
for(i=;i<=;i++) //ST表 。
for(j=;j+(<<i)-<=N;j++){
if(dp[j][i-]>dp[j+(<<(i-))][i-]) dp[j][i]=dp[j][i-],pos[j][i]=pos[j][i-];
else dp[j][i]=dp[j+(<<(i-))][i-],pos[j][i]=pos[j+(<<(i-))][i-];
}
for(i=;i+LL-<=N;i++){ //最开始最大个N个数。
int p=getmax(i+LL-,min(N,i+RR-));
q.push(in(i,i+LL-,min(N,i+RR-),dp[p][]-dp[i-][],p));
}
while(K&&!q.empty()){
in now=q.top(); q.pop();
ans+=now.val;
if(now.L<now.pos) {
int p=getmax(now.L,now.pos-);
q.push(in(now.i,now.L,now.pos-,dp[p][]-dp[now.i-][],p));
}
if(now.R>now.pos){
int p=getmax(now.pos+,now.R);
q.push(in(now.i,now.pos+,now.R,dp[p][]-dp[now.i-][],p));
}
K--;
}
printf("%lld\n",ans);
return ;
}

BZOJ2006:超级钢琴(ST表+堆求前K大区间和)的更多相关文章

  1. [BZOJ2006][NOI2010]超级钢琴(ST表+堆)

    2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 3679  Solved: 1828[Submit][Statu ...

  2. BZOJ 2006: [NOI2010]超级钢琴 ST表+堆

    开始想到了一个二分+主席树的 $O(n\log^2 n)$ 的做法. 能过,但是太无脑了. 看了一下题解,有一个 ST 表+堆的优美解法. 你发现肯定是选取前 k 大最优. 然后第一次选的话直接选固定 ...

  3. 【BZOJ-2006】超级钢琴 ST表 + 堆 (一类经典问题)

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

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

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

  5. bzoj 2006 [NOI2010]超级钢琴——ST表+堆

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2006 每个右端点的左端点在一个区间内:用堆记录端点位置.可选区间,按价值排序:拿出一个后也许 ...

  6. BZOJ 2006: [NOI2010]超级钢琴 [ST表+堆 | 主席树]

    题意: 一个序列,求k个不相同的长度属于\([L,R]\)的区间使得和最大 前缀和,对于每个r找最小的a[l] 然后我yy了一个可持久化线段树做法...也许会T 实际上主席树就可以了,区间k小值 然后 ...

  7. 算法导论学习之线性时间求第k小元素+堆思想求前k大元素

    对于曾经,假设要我求第k小元素.或者是求前k大元素,我可能会将元素先排序,然后就直接求出来了,可是如今有了更好的思路. 一.线性时间内求第k小元素 这个算法又是一个基于分治思想的算法. 其详细的分治思 ...

  8. 牛客第六场 J.Heritage of skywalkert(On求前k大)

    题目传送门:https://www.nowcoder.com/acm/contest/144/J 题意:给一个function,构造n个数,求出其中任意两个的lcm的最大值. 分析:要求最大的lcm, ...

  9. HDU 6041 I Curse Myself(点双联通加集合合并求前K大) 2017多校第一场

    题意: 给出一个仙人掌图,然后求他的前K小生成树. 思路: 先给出官方题解 由于图是一个仙人掌,所以显然对于图上的每一个环都需要从环上取出一条边删掉.所以问题就变为有 M 个集合,每个集合里面都有一堆 ...

随机推荐

  1. 实机桌面上给虚拟机安装系统(分区,恢复GHO)

    在虚拟机里安装系统大家都会了.我这里介绍一种方法无须进入虚拟机里操作.全部在实机里完成对虚拟机安装系统(分区.恢复GHO).这里要使用到的工具如下1分区工具DISKGENIUS2虚拟光驱3Ghost镜 ...

  2. 基于HTML5的PACS--HTML5图像处理

    在此之前,此系统是结合DICOM的WADO标准,在浏览器里通过javascript操作返回的JPG图片.这种服务器端解析,客户端展现的方式,对实现图像的移动.缩放.旋转.测量等图像操作能够实现实时的交 ...

  3. Proftpd快速搭建FTP服务器

    前言 在Linux系统中,FTP服务器软件有很多,都已经成熟,像vsftpd, wu-ftp, Pure-FTPd等.但这些软件安装配置起来都比较麻烦,搭建个人的FTP服务器,还是Proftpd比较简 ...

  4. linux中断子系统:中断号的映射与维护初始化mmap过程

    本文均属自己阅读源代码的点滴总结.转账请注明出处谢谢. 欢迎和大家交流.qq:1037701636 email:gzzaigcn2009@163.com 写在前沿: 好久好久没有静下心来整理一些东西了 ...

  5. 【转载】聊一聊C#的Equals()和GetHashCode()方法

    首先先谈一下Equals()这个方法: Equals()方法,来自于Object,是我们经常需要重写的方法.此方法的默认实现大概是这样的: public virtual bool Equals(obj ...

  6. Android实战简易教程-第二十三枪(基于Baas的用户注冊和登录模块实现!)

    接着上两篇文章.我们基于Bmob提供的API实现用户登录功能.总体看一下代码. 1.注冊页面xml: <RelativeLayout xmlns:android="http://sch ...

  7. ARP协议(1)什么是ARP协议

    这是最近在看<TCP/IP具体解释>系列书总结出来的,之后会陆续把其它协议部分分享出来. 我尽量以简单易读.易懂的方式呈现出来,可是,因为文笔和水平有限.有些地方或许存在描写叙述上的不足或 ...

  8. WPF简单计算器

  9. 关于 ++x 和 x++ 比较难的一个例子

    public class testMain { static{ int x = 5;//如果后面有static int x, 前面的定义就没有用x会被重新定义为0 } static int y; st ...

  10. 华为OJ 名字美丽度

    这是一道坑爹的题目,为什么这么说,且看我慢慢分析-- 题目例如以下: 给出一个名字,该名字有26个字符串组成,定义这个字符串的"美丽度"是其全部字母"美丽度"的 ...