【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排序,每次取出一个,然后把这个取过的五元组分成两个( ...
随机推荐
- yii 验证码 CCaptcha的总结(转)
今天用到yii的验证码 ccaptcha,经过在网上搜寻 找到以下例子: 1.在controller中加入代码 (1)启用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 &l ...
- yaf windows安装
1.需要先下载 php_yaf模块.地址(http://pecl.php.net/package/yaf/2.3.2/windows) 看清你的php版本,然后在phpinfo中看Achitectur ...
- 电脑CPU开机上电后的第一条指令
结合上面的文章,CPU上电后第一条指令是通过CS:IP来指定的,CPU厂家会给其初始值,对于386处理器来说,CPU第一条指令地址是 0xFFFFFFF0 这里会有一个问题,CPU怎么能一上来就去0x ...
- java 常见的异常大集合
算术异常类:ArithmeticExecption 空指针异常类:NullPointerException 类型强制转换异常:ClassCastException 数组负下标异常:NegativeAr ...
- Linux中Apache+Tomcat+JK实现负载均衡和群集的完整过程
人原创,一个字一个字地码的,尊重版权,转载请注明出处! http://blog.csdn.net/chaijunkun/article/details/6987443 最近在开发的项目需要承受很高的并 ...
- MySQL复制 -- 复制出错怎么办?
假如我们生产环境复制出错?该怎么办呢? 下面提供几种办法: 1. 手工处理,补回不一致数据(可以利用主库来补数据.也可以利用binlog来补数据) 2.用开源工具来解决一致性问题 3.自己造轮子,解决 ...
- java使用Cookie判断用户登录情况
1.判断是否登录 public boolean isLogin() { Set<Cookie> cookies = this.browser.getCookies(); String JS ...
- BZOJ5020 THUWC2017在美妙的数学王国中畅游(LCT)
明摆着的LCT,问题在于如何维护答案.首先注意到给出的泰勒展开式,并且所给函数求导非常方便,肯定要用上这玩意.容易想到展开好多次达到精度要求后忽略余项.因为x∈[0,1]而精度又与|x-x0|有关,当 ...
- Vue 中使用UEditor富文本编辑器-亲测可用-vue-ueditor-wrap
其中UEditor中也存在不少错误,再引用过程中. 但是UEditor相对还是比较好用的一个富文本编辑器. vue-ueditor-wrap说明 Vue + UEditor + v-model 双向绑 ...
- 学习Spring Boot:(八)Mybatis使用分页插件PageHelper
首先Mybqtis可以通过SQL 的方式实现分页很简单,只要在查询SQL 后面加上limit #{currIndex} , #{pageSize}就可以了. 本文主要介绍使用拦截器的方式实现分页. 实 ...