【BZOJ】2006: [NOI2010]超级钢琴
【题意】给定长度为n的整数序列,求长度为[L,R]的前k大区间和的和。n,k<=500000。
【算法】堆+贪心+RMQ
【题解】考虑暴力是取所有长度为[L,R]的子串的前k大求和,复杂度O(n^2)。
发现左端点相同的区间[l,r]中,最大的区间和就是最大的sum[r](sum是前缀和数组)。
然后将所以左端点放进堆中,每次取出堆顶之后把第二大的r扔进去,重复k次。
现在的问题是取区间最大的r,第二大的r……区间第k大?用主席树维护即可,复杂度O(n log n)。
还可以用ST表(RMQ)维护,定义三元组(x,l,r)表示取左端点为x,右端点为[l,r]的区间最大sum[r]。
假设对于(x,l,r),取出元素y,就在堆中加入两个三元组(x,l,y-1)和(x,y+1,r)。
复杂度O(n log n)。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int maxn=;
int n,k,L,R,d[maxn][],sum[maxn],p[maxn][],logs[maxn];
struct cyc{
int x,l,r,y;
bool operator < (const cyc &a) const
{return sum[y]-sum[x-]<sum[a.y]-sum[a.x-];}
}qp;
priority_queue<cyc>q;
void RMQ_init()
{
logs[]=-;for(int i=;i<=n;i++)logs[i]=logs[i>>]+;
for(int i=;i<=n;i++){d[i][]=sum[i];p[i][]=i;}
for(int j=;(<<j)<=n;j++)
for(int i=;i+(<<j)-<=n;i++)
{
d[i][j]=max(d[i][j-],d[i+(<<(j-))][j-]);
p[i][j]=d[i][j-]>d[i+(<<(j-))][j-]?p[i][j-]:p[i+(<<(j-))][j-];
}
}
int RMQ(int l,int r)
{
int K=logs[r-l+];
return d[l][K]>d[r-(<<K)+][K]?p[l][K]:p[r-(<<K)+][K];
}
int main()
{
scanf("%d%d%d%d",&n,&k,&L,&R);
sum[]=;
for(int i=;i<=n;i++){scanf("%d",&sum[i]);sum[i]+=sum[i-];}
RMQ_init();
for(int i=;i<=n;i++){
if(i+L-<=n)q.push((cyc){i,i+L-,min(n,i+R-),RMQ(i+L-,min(n,i+R-))});
}
long long ans=;
for(int i=;i<=k;i++)
{
qp=q.top();q.pop();
ans+=sum[qp.y]-sum[qp.x-];
if(qp.y>qp.l)q.push((cyc){qp.x,qp.l,qp.y-,RMQ(qp.l,qp.y-)});
if(qp.y<qp.r)q.push((cyc){qp.x,qp.y+,qp.r,RMQ(qp.y+,qp.r)});
}
printf("%lld",ans);
return ;
}
【BZOJ】2006: [NOI2010]超级钢琴的更多相关文章
- 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 ...
- BZOJ 2006: [NOI2010]超级钢琴( RMQ + 堆 )
取最大的K个, 用堆和RMQ来加速... ----------------------------------------------------------------- #include<c ...
- 洛谷 P2048 BZOJ 2006 [NOI2010]超级钢琴
题目描述 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度为Ai,其中A ...
- BZOJ.2006.[NOI2010]超级钢琴(贪心 堆)
BZOJ 洛谷 思路和BZOJ3784一样,用前缀和+堆维护.做那题吧,不赘述啦. (没错我就是水一个AC) //54620kb 1060ms #include <queue> #incl ...
- bzoj 2006 [NOI2010]超级钢琴——ST表+堆
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2006 每个右端点的左端点在一个区间内:用堆记录端点位置.可选区间,按价值排序:拿出一个后也许 ...
- BZOJ 2006 [NOI2010]超级钢琴 (堆+主席树)
题面:BZOJ传送门 洛谷传送门 让你求前$K$大的子序列和,$n\leq 5*10^{5}$ 只想到了个$nlog^{2}n$的做法,似乎要被卡常就看题解了.. 好神奇的操作啊,我傻了 我们把序列和 ...
- BZOJ 2006 NOI2010 超级钢琴 划分树+堆
题目大意:给定一个序列.找到k个长度在[l,r]之间的序列.使得和最大 暴力O(n^2logn),肯定过不去 看到这题的第一眼我OTZ了一下午... 后来研究了非常久别人的题解才弄明确怎么回事...蒟 ...
- BZOJ 2006: [NOI2010]超级钢琴 [ST表+堆 | 主席树]
题意: 一个序列,求k个不相同的长度属于\([L,R]\)的区间使得和最大 前缀和,对于每个r找最小的a[l] 然后我yy了一个可持久化线段树做法...也许会T 实际上主席树就可以了,区间k小值 然后 ...
- bzoj 2006: [NOI2010]超级钢琴【st表+堆】
设计一个五元组(i,l,r,p,v),表示在以i为左端点,右端点落在(l,r)中的情况下,取最大值v时右端点落在p.把这个五元组塞到优先队列里,以v排序,每次取出一个,然后把这个取过的五元组分成两个( ...
随机推荐
- 个人作业-week3案例分析
第一部分 软件调研测评(必应词典移动端) 找到的bug: 在词汇量测试中每个单词给用户思考的时间太短,只有五秒钟.导致很多似曾相识的单词还没来得及想起就已经过了.如果说测的是用户记忆深刻的单词,那些记 ...
- es6 javascript对象方法Object.assign()
es6 javascript对象方法Object.assign() 2016年12月01日 16:42:34 阅读数:38583 1 基本用法 Object.assign方法用于对象的合并,将源对象 ...
- ubuntu 中安装memcache,并给出一个简单的实例·
Memcache分为两部分,Memcache服务端和客户端.Memcache服务端是作为服务来运行的,所有数据缓存的建立,存储,删除实际上都是在这里完成的.客户端,在这里我们指的是PHP的可以调用的扩 ...
- PHP学习心得1
php是动态网站开发的优秀语言,在学习的时候万万不能冒进.在系统的学习前,我认为不应该只是追求实现某种效果,因为即使你复制他人的代码调试成功,实现了你所期望的效果,你也不了解其中的原理,这样你很难利用 ...
- EasyUseCase 一款脑图转化 Excel 测试用例工具 (1.2 版本升级)
EasyUseCase 本工具由本人自主开发.经过内部实践有效提升测试用例编写效率200% 覆盖率可度量.利用读取xmind软件图表转换符合国人基本需求的测试用例,让手动写Excel用例的日子过去,发 ...
- 删除log日志中包含某个字符的行
sed -i '/{Str}/d' abc.txt 假如你的log日志中某行有sleep字符,直接输入命令: sed -i '/sleep/d' log.log 如果删除的是一个变量的值,假如是var ...
- yii2 查询数据库语法
$query0 = ImGroupUser::find()->where(['gid'=>'56680dfc60b215d62104a4d8'])->select('user_cli ...
- C#基础-代码部署数据库及IIS站点
一.前言 最近忙里偷闲,做了一个部署数据库及IIS网站站点的WPF应用程序工具. 二.内容 此工具的目的是: 根据.sql文件在本机上部署数据库 在本机部署IIS站点,包括 ...
- BZOJ 2243 染色 | 树链剖分模板题进阶版
BZOJ 2243 染色 | 树链剖分模板题进阶版 这道题呢~就是个带区间修改的树链剖分~ 如何区间修改?跟树链剖分的区间询问一个道理,再加上线段树的区间修改就好了. 这道题要注意的是,无论是线段树上 ...
- bzoj4035【HAOI2015】数组游戏
题目描述 有一个长度为N的数组,甲乙两人在上面进行这样一个游戏:首先,数组上有一些格子是白的,有一些是黑的.然 后两人轮流进行操作.每次操作选择一个白色的格子,假设它的下标为x.接着,选择一个大小在1 ...