BZOJ2006:[NOI2010]超级钢琴
浅谈\(RMQ\):https://www.cnblogs.com/AKMer/p/10128219.html
题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=2006
首先,序列\([l,r]\)的和可以转化成前缀和相减:\(sum[r]-sum[l-1]\)。
其次,对于每个右端点\(pos\),有效左端点都是一段区间\([pos-r,pos-l]\)。而这里面前缀和最小的则是最优左端点。
一开始我们将所有的四元组\((v,pos,l,r)\)丢到大根堆里。这个四元组表示以\(pos\)为右端点,有效左端点区间在\([l,r]\)内,最大值为\(v\)。假设最优左端点是\(pos'\),那么对于最优解,我们只需要执行如下步骤\(k\)次即可:
取出堆顶,\(ans+=v\)。
将\((sum[pos]-query(l,pos'-1),pos,l,pos'-1)\)与\((sum[pos]-query(pos'+1,r),pos,pos'+1,r)\)放回堆里。这样可以保证\([pos',pos]\)不会再被取出。
\(query(l,r)\)表示求区间\([l,r]\)的前缀和最小值。这样,问题就得到了完美解决。
时间复杂度:\(O(nlogn)\)
空间复杂度:\(O(nlogn)\)
代码如下:
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=5e5+5;
ll ans;
int n,limit,L,R;
int a[maxn],Log[maxn],f[20][maxn];
int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
}
struct node {
int v,pos,l,r;
node() {}
node(int _v,int _pos,int _l,int _r) {
v=_v,pos=_pos,l=_l,r=_r;
}
bool operator<(const node &a)const {
return v<a.v;
}
};
struct Heap {
int tot;
node tree[maxn<<1];
void ins(node a) {
tree[++tot]=a;
int pos=tot;
while(pos>1) {
if(tree[pos>>1]<tree[pos])
swap(tree[pos>>1],tree[pos]),pos>>=1;
else break;
}
}
node pop() {
node res=tree[1];
tree[1]=tree[tot--];
int pos=1,son=2;
while(son<=tot) {
if(son<tot&&tree[son]<tree[son|1])son|=1;
if(tree[pos]<tree[son])
swap(tree[pos],tree[son]),pos=son,son=pos<<1;
else break;
}
return res;
}
}T;//手写堆carry你进第一版,值得拥有!
int fake(int num1,int num2) {
if(a[num1]<a[num2])return num1;
return num2;
}
int query(int l,int r) {
int x=Log[r-l+1];
return fake(f[x][l],f[x][r-(1<<x)+1]);
}
int main() {
n=read(),limit=read();
L=read(),R=read();Log[0]=-1;
for(int i=1;i<=n;i++) {
f[0][i]=i;
Log[i]=Log[i>>1]+1;
a[i]=read()+a[i-1];
}
for(int i=1;i<=19;i++)
for(int j=0;j+(1<<i)-1<=n;j++)
f[i][j]=fake(f[i-1][j],f[i-1][j+(1<<(i-1))]);
for(int i=L;i<=n;i++) {
int l=max(0,i-R),r=i-L;
T.ins(node(a[i]-a[query(l,r)],i,l,r));
}
for(int i=1;i<=limit;i++) {
node tmp=T.pop();
ans+=tmp.v;
int pos=query(tmp.l,tmp.r);
if(pos-1>=tmp.l)
T.ins(node(a[tmp.pos]-a[query(tmp.l,pos-1)],tmp.pos,tmp.l,pos-1));
if(pos+1<=tmp.r)
T.ins(node(a[tmp.pos]-a[query(pos+1,tmp.r)],tmp.pos,pos+1,tmp.r));
}
printf("%lld\n",ans);
return 0;
}
BZOJ2006:[NOI2010]超级钢琴的更多相关文章
- bzoj2006 [NOI2010]超级钢琴 (及其拓展)
bzoj2006 [NOI2010]超级钢琴 给定一个序列,求长度在 \([L,\ R]\) 之间的区间和的前 \(k\) 大之和 \(n\leq5\times10^5,\ k\leq2\times1 ...
- bzoj千题计划162:bzoj2006: [NOI2010]超级钢琴
http://www.lydsy.com/JudgeOnline/problem.php?id=2006 输出最大的k个 sum[r]-sum[l-1] (L<=r-l+1<=R) 之和 ...
- BZOJ2006 [NOI2010]超级钢琴 【堆 + RMQ】
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MB Submit: 3446 Solved: 1692 [Submit][Sta ...
- [BZOJ2006][NOI2010]超级钢琴(ST表+堆)
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 3679 Solved: 1828[Submit][Statu ...
- [BZOJ2006] [NOI2010]超级钢琴 主席树+贪心+优先队列
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 3591 Solved: 1780[Submit][Statu ...
- bzoj2006 noi2010 超级钢琴 主席树 + 优先队列
Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2435 Solved: 1195 Description 小 Z是一个小有名气的钢琴家,最近C博士送 ...
- BZOJ2006[NOI2010]超级钢琴——堆+主席树
题目描述 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的 音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度为Ai,其中 ...
- 【贪心 计数】bzoj2006: [NOI2010]超级钢琴
这么经典的贪心我怎么现在才做啊…… Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的 音乐. 这架超级钢琴可以弹奏出n个 ...
- BZOJ2006——[NOI2010]超级钢琴
1.题意:给一个序列,让你取出k个不同的区间,要求长度在之间,问所有区间和的最大值 2.分析:这道题拿过来就能知道是要拿出前k个最大的区间,我们思考最暴力的做法,就是把这个所有的区间枚举出来算,取出前 ...
- bzoj2006: [NOI2010]超级钢琴
题意:给一个序列(n<=500000),要求选定k个不同区间,使得区间长度在L,R之间,并使得k个区间和之和最大,输出这个最大值. 刚拿到题的时候想的是,对于每个点,如果以它开头,那么之后的L- ...
随机推荐
- Java的Executor框架和线程池实现原理
Java的Executor框架 1,Executor接口 public interface Executor { void execute(Runnable command); } Executor接 ...
- sphinx PDF 中文
使用reST撰写文档时,需要分多个文档时,就必须使用sphinx了,sphinx说起来很简单的,但是默认是不是支持中文的.幸好我出生的晚,sphinx现在已经支持xelatex了^_^ 安装 除了pa ...
- (个人开源)ffpanel --ffmpeg的GUI,让ffmpeg离开黑黑的命令行
程序及源代码下载地址 :https://github.com/langsim/ffpanel
- php类中const
常量 const 在类里面定义常量用 const 关键字,而不是通常的 define() 函数. 语法: const constant = "value"; 例子: <?ph ...
- iPhone,iPad如何获取WIFI名称即SSID
本文转载至 http://blog.csdn.net/wbw1985/article/details/20530281 2010年开始苹果清理了一批APP Store上的WIFI扫描软件, 缘由语焉 ...
- php部分:网页中报表的打印,并用CSS样式控制打印的部分;
网页中报表的打印,是通过调用window对象中的print()方法实现打印功能的: 调用浏览器本身的打印功能实现打印 <a href="#" onclick="wi ...
- 【BZOJ4197】[Noi2015]寿司晚宴 状压DP+分解质因数
[BZOJ4197][Noi2015]寿司晚宴 Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被邀请参加了寿司晚宴 ...
- 怎么用cookie解决选项卡问题刷新后怎么保持原来的选项?
什么是cookie? Cookies虽然一般都以英文名呈现,但是它还是有一个可爱的中文名“小甜饼”.Cookies是指服务器暂存放在你的电脑里的txt格式的文本文件资料,主要用于网络服务器辨别电脑使用 ...
- js闭包实际用途
闭包例:防止双击 在线商店的购物车里,为防止“多重购买”,需要防止按钮被双击. 下面用“jQuery + 闭包”来实现这一功能. HTML <form name="frm" ...
- Grunt学习笔记【3】---- filter使用方式和实现原理详解
本文主要讲配置任务中的filter,包括使用默认fs.Stats方法名和自定义过滤函数,以及filter的实现原理. 通过设置filter属性可以实现一些特殊处理逻辑.例如:要清理某个文件夹下的所有空 ...