bzoj2006: [NOI2010]超级钢琴
题意:给一个序列(n<=500000),要求选定k个不同区间,使得区间长度在L,R之间,并使得k个区间和之和最大,输出这个最大值。
刚拿到题的时候想的是,对于每个点,如果以它开头,那么之后的L-1个一定被选,剩下的R-L个可选,对这一部分进行最大前缀和就好啦!用主席树搞搞,建树的时候维护下就好了。
但有个问题,以这个区间为开头的情况不止一种,这种做法确实能求出以它开头的最大值,那次大值,k大值呢?这也是有可能计入答案的。所以不行。
正解是,对于一个位置,如果我们考虑以它结尾,这个区间等于它的前缀和减去前面一个位置的前缀和,其中位置i满足i离这个位置不小于L不超过R。对于这个位置,我们只需要找这个区间内的区间k大,用这个位置前缀和减掉就好了,然后去求区间k+1大。放入一个堆中取k次就好。
#include<bits/stdc++.h>
using namespace std;
#define N 500005
#define LL long long
inline int read(){
int x=,f=; char a=getchar();
while(a<'' || a>'') {if(a=='-') f=-; a=getchar();}
while(a>='' && a<='') x=x*+a-'',a=getchar();
return x*f;
}
LL sum[N];
struct data{
int num,k;LL val;
bool operator < (const data& w)const{
return val<w.val;
}
}t;
priority_queue<data>q;
namespace Chairman_Tree{
int root[N],size;
struct ct{
int son[],sz;
}tr[];
void insert(int x,int& y,LL l,LL r,LL v){
y=++size; tr[y].sz=tr[x].sz+;
if(l==r) return;
memcpy(tr[y].son,tr[x].son,sizeof(tr[y].son));
int mid=(l+r)>>;
if(mid>=v) insert(tr[x].son[],tr[y].son[],l,mid,v);
else insert(tr[x].son[],tr[y].son[],mid+,r,v);
}
LL query(int x,int y,LL l,LL r,int k){
if(tr[y].sz-tr[x].sz<k) return 1e9;
if(l==r) return l;
int mid=(l+r)>>,s=tr[tr[y].son[]].sz-tr[tr[x].son[]].sz;
if(k<=s) return query(tr[x].son[],tr[y].son[],l,mid,k);
else return query(tr[x].son[],tr[y].son[],mid+,r,k-s);
}
}
#define CT Chairman_Tree
#define L -500000005
#define R 500000005
int main(){
int n=read(),k=read(),l=read(),r=read();
LL ans=; CT::insert(,CT::root[],L,R,);
for(int i=;i<=n;i++) sum[i]=sum[i-]+read();
for(int i=;i<=n;i++) CT::insert(CT::root[i-],CT::root[i],L,R,sum[i]);
for(int i=l;i<=n;i++){
int ri=i-l,le=i-r-;
LL tmp;
if(le<) tmp=CT::query(,CT::root[ri],L,R,);
else tmp=CT::query(CT::root[le],CT::root[ri],L,R,);
q.push((data){i,,sum[i]-tmp});
}
while(k--){
t=q.top(); q.pop();
ans+=t.val;
int ri=t.num-l,le=t.num-r-; LL tmp;
if(le<) tmp=CT::query(,CT::root[ri],L,R,t.k+);
else tmp=CT::query(CT::root[le],CT::root[ri],L,R,t.k+);
q.push((data){t.num,t.k+,sum[t.num]-tmp});
}
cout<<ans;
return ;
}
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个最大的区间,我们思考最暴力的做法,就是把这个所有的区间枚举出来算,取出前 ...
随机推荐
- 渗透测试工具Nmap从初级到高级使用教程
本文由阿德马翻译自国外网站,请尊重劳动成果,转载请注明出处,谢谢 Nmap是一款网络扫描和主机检测的非常有用的工具.Nmap是不局限于仅仅收集信息和枚举,同时可以用来作为一个漏洞探测器或安全扫描器.它 ...
- Codeforces Round #389 (Div. 2, Rated, Based on Technocup 2017 - Elimination Round 3) E. Santa Claus and Tangerines
E. Santa Claus and Tangerines time limit per test 2 seconds memory limit per test 256 megabytes inpu ...
- Linux系统下配置JDK环境变量
刚申请了阿里云,平时很少接触Linux,特此记录一下Linux系统下安装JDK的步骤. 1.进入usr:cd /usr: 2.创建java文件夹:mkdir java: 3.将下载好的文件拷贝至jav ...
- Unity3d外包(北京)公司(长年承接U3D外包)
我们制作各类型严肃游戏,虚拟现实,增强现实项目! 品质保证,售后完备. 联系请加QQ:372900288 电话:13911652504 我们团队成立于2011年10月,是一个专业从事严肃游戏研发的团 ...
- 深圳楼市2007vs2016
昨日新政,虽在预料之中,但心中未免有些感慨.今日在回深的火车上,突然由此让我回想起了2007年的那场深圳房价大溃败.忍不住写上一段供大家参考.前奏:2000年后的深圳楼市在2004年之前可以说是波澜不 ...
- 程序设计入门——C语言 第6周编程练习 2 完数(5分)
2 完数(5分) 题目内容: 一个正整数的因子是所有可以整除它的正整数.而一个数如果恰好等于除它本身外的因子之和,这个数就称为完数.例如6=1+2+3(6的因子是1,2,3). 现在,你要写一个程序, ...
- Hangfire项目使用
基本介绍: hangfire 主要用于根据设置时间来执行任务,间隔几分钟执行一次,每天几点钟执行一次,如此执行任务. 方法: backgroundjob.enqueue(()=>"要执 ...
- 解析json串,利用正则表达式,split
public class SplitJson { public static void main(String[] args) { // TODO Auto-generated meth ...
- Linux中修改环境变量导致大量命令不可用的解决办法
如果搞死环境变量别慌张.因为ls等命令都不能使用了,所以先找到/usr/bin/目录 使用./sudo su命令获取root权限 然后在进入/etc目录 利用vim profile命令 修改profi ...
- el: 在jsp页面内使用函数判断子字符串
e.g. <c:forEach items="${datas}" var="data"> <c:if test="${not fn: ...