洛谷 2048 BZOJ 2006 [NOI2010]超级钢琴
【题解】
贪心题。设五元组(mx,pos,l,r1,r2)表示最大值为mx,取得最大值的区间右端点为pos,区间左端点为l,区间右端点的可选区间为[r1,r2]. 每次从堆里拎出最大值,然后把这个区间拆了,因为选了[l,pos]这个区间之后就不能再选它了。我们得往堆了丢俩新的五元组(mx',pos',l,r1,pos-1)以及(mx'',pos'',l,pos+1,r2),至于mx',mx'',pos',pos''的获得,用ST表即可。
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define N 1000010
#define rg register
#define LL long long
using namespace std;
int n,k,L,R,tot,pos[][N],f[][N];
LL ans;
struct heap{
LL d,p,l,r1,r2;
}h[N];
struct rec{
LL d,p;
};
inline int read(){
int k=,f=; char c=getchar();
while(c<''||c>'')c=='-'&&(f=-),c=getchar();
while(''<=c&&c<='')k=k*+c-'',c=getchar();
return k*f;
} inline void up(int x){
int fa;
while((fa=x>>)&&h[fa].d<h[x].d) swap(h[fa],h[x]),x=fa;
}
inline void down(int x){
int son;
while((son=x<<)<=tot){
if(son<tot&&h[son+].d>h[son].d) son++;
if(h[son].d>h[x].d) swap(h[son],h[x]),x=son;
else return;
}
}
inline rec query(int l,int r){
r=min(r,n); l=max(,l);
int k=log2(r-l+); rec tmp; tmp.d=tmp.p=;
if(l>r) return tmp;
if(f[k][l]>f[k][r-(<<k)+]){
tmp.d=f[k][l]; tmp.p=pos[k][l];
return tmp;
}
else{
tmp.d=f[k][r-(<<k)+]; tmp.p=pos[k][r-(<<k)+];
return tmp;
}
}
int main(){
memset(f,,sizeof(f)); f[][]=;
n=read(); k=read(); L=read()-; R=read()-;
for(rg int i=;i<=n;i++) f[][i]=read()+f[][i-],pos[][i]=i;
for(rg int i=;i<=log2(n);i++)
for(rg int j=;j<=n-(<<i)+;j++)
if(f[i-][j]>f[i-][j+(<<(i-))])
f[i][j]=f[i-][j],pos[i][j]=pos[i-][j];
else f[i][j]=f[i-][j+(<<(i-))],pos[i][j]=pos[i-][j+(<<(i-))];
for(rg int i=;i<=n-L;i++){
rec tmp=query(i+L,i+R);
h[++tot]=(heap){tmp.d-f[][i-],tmp.p,i,i+L,min(n,i+R)};
up(tot);
}
for(rg int i=;i<=k;i++){
heap now=h[];
ans+=now.d;
h[]=h[tot--]; if(tot) down();
if(now.p->=now.r1){
rec tmp=query(now.r1,now.p-);
h[++tot]=(heap){tmp.d-f[][now.l-],tmp.p,now.l,now.r1,now.p-};
up(tot);
}
if(now.r2>=now.p+){
rec tmp=query(now.p+,now.r2);
h[++tot]=(heap){tmp.d-f[][now.l-],tmp.p,now.l,now.p+,now.r2};
up(tot);
}
}
printf("%lld\n",ans);
return ;
}
洛谷 2048 BZOJ 2006 [NOI2010]超级钢琴的更多相关文章
- 洛谷 P2048 BZOJ 2006 [NOI2010]超级钢琴
题目描述 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度为Ai,其中A ...
- 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 ...
- BZOJ.2006.[NOI2010]超级钢琴(贪心 堆)
BZOJ 洛谷 思路和BZOJ3784一样,用前缀和+堆维护.做那题吧,不赘述啦. (没错我就是水一个AC) //54620kb 1060ms #include <queue> #incl ...
- BZOJ 2006 [NOI2010]超级钢琴 (堆+主席树)
题面:BZOJ传送门 洛谷传送门 让你求前$K$大的子序列和,$n\leq 5*10^{5}$ 只想到了个$nlog^{2}n$的做法,似乎要被卡常就看题解了.. 好神奇的操作啊,我傻了 我们把序列和 ...
- bzoj 2006 [NOI2010]超级钢琴——ST表+堆
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2006 每个右端点的左端点在一个区间内:用堆记录端点位置.可选区间,按价值排序:拿出一个后也许 ...
- BZOJ 2006 NOI2010 超级钢琴 划分树+堆
题目大意:给定一个序列.找到k个长度在[l,r]之间的序列.使得和最大 暴力O(n^2logn),肯定过不去 看到这题的第一眼我OTZ了一下午... 后来研究了非常久别人的题解才弄明确怎么回事...蒟 ...
- BZOJ 2006: [NOI2010]超级钢琴 [ST表+堆 | 主席树]
题意: 一个序列,求k个不相同的长度属于\([L,R]\)的区间使得和最大 前缀和,对于每个r找最小的a[l] 然后我yy了一个可持久化线段树做法...也许会T 实际上主席树就可以了,区间k小值 然后 ...
随机推荐
- Ural 1382 2SAT
ural1382 直接套用 2SAT模板 缩点 拓扑排序... #include<iostream> #include<cstdio> #include<cstdlib& ...
- ubuntu 16.04 Python Anaconda 安装
Python Anaconda 不同版本在官网上的位置:https://www.anaconda.com/download/#linux 进入官网=>Changelog=>Product ...
- java笔记线程方式1优先级
* 我们的线程没有设置优先级,肯定有默认优先级. * 那么,默认优先级是多少呢? * 如何获取线程对象的优先级? * public final int getPriority():返回线程对象的优 ...
- mysql workbench的简单使用
注意:即使server没有开启,也可以通过workbench进来编辑页面. 1.再开始程序找到mysql workbench,点击运行 2.t添加管理员链接mysql-------------前提是你 ...
- IDEA UI版本取消Output窗口打印消息的条数的限制
打开IDEA的安装目录-->进入bin文件夹-->编辑idea.properties文件::修改idea.cycle.buffer.size=1024为idea.cycle.buffer. ...
- 浙江省CIO协会钱塘江论坛近日在网易云创沙龙宣布成立
本文来自网易云社区 9月19日,由网易云与浙江省首席信息官协会共同主办的“网易云创CIO沙龙”在杭州举行,本次活动以“瞩目钱塘,赋能企业数字化创新”为主题,网易云企业服务部总经理岳峥辉,浙江省首席信息 ...
- vue学习笔记(1)
1.检测变化 <ul> <li v-for="item in list">{{item}}</li> </ul> <scrip ...
- ECMA里面的一元符
只能操作一个值的叫做一元操作符.一元操作符是ECMAScript中最简单的操作符 1.递增和递减操作符 递增和递减操作符直接借鉴自c,而且各有俩个版本,前置型和后置型.顾名思义,前置型就是位于要操作的 ...
- SeasLog的日志
https://github.com/Neeke/SeasLog/blob/master/README_zh.md 中文文档地址, 这是一个很好用的记录日志扩展,可以用于项目之中
- codechef: ADAROKS2 ,Ada Rooks 2
又是道原题... (HDU 6313 Hack It , 多校 ACM 里面的题) 题目说构造一个 n * n 矩阵,染色点不得构成矩形...然后染色点个数至少 8 * n 然后我们生成一个数 m , ...