【BZOJ2006】超级钢琴(主席树,优先队列)

题面

BZOJ

题解

既然是一段区间

首先就要变成单点

所以求一个前缀和

这个时候贪心很明显了:

枚举每一个点和可以和它组成一段的可行的点

全部丢进一个堆里面

取出最大的\(K\)个就行了

但是,很显然,我们做不到都取出来

所以,考虑怎么优化这个过程

每次堆里面对于每个点就先维护一个最大贡献

显然的,只有取出了最大贡献,才会取出次大贡献

那么,最大/次大/\(K\)大贡献怎么算?

一个点,能够和他组成和弦的是一个连续的区间

最大的贡献就是它和区间最小值的差

依次类推

就是区间第\(K\)大

所以搞一棵主席树

维护一下区间第\(K\)大就好啦

再用堆每次取出/加入即可

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define MAX 510000
inline int read()
{
int x=0,t=1;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
struct Data{int v,id,k;};
bool operator<(Data a,Data b){return a.v<b.v;}
priority_queue<Data> Q;
struct Node
{
int ls,rs;
int sum;
}t[MAX<<6];
int tot,S[MAX],top,rt[MAX],L,R,n,K;
int a[MAX];
void Modify(int &now,int ff,int l,int r,int pos,int w)
{
t[now=++tot]=t[ff];t[now].sum+=w;
if(l==r)return;
int mid=(l+r)>>1;
if(pos<=mid)Modify(t[now].ls,t[ff].ls,l,mid,pos,w);
else Modify(t[now].rs,t[ff].rs,mid+1,r,pos,w);
}
int Query(int A,int B,int l,int r,int K)
{
if(l==r)return l;
int mid=(l+r)>>1;
int sum=t[t[A].ls].sum-t[t[B].ls].sum;
if(sum<K)return Query(t[A].rs,t[B].rs,mid+1,r,K-sum);
else return Query(t[A].ls,t[B].ls,l,mid,K);
}
int main()
{
n=read()+1;K=read();L=read();R=read();
for(int i=2;i<=n;++i)S[++top]=a[i]=a[i-1]+read();S[++top]=0;
sort(&S[1],&S[top+1]);
top=unique(&S[1],&S[top+1])-S-1;
for(int i=1;i<=n;++i)a[i]=lower_bound(&S[1],&S[top+1],a[i])-S;
for(int i=1;i<=n;++i)Modify(rt[i],rt[i-1],1,top,a[i],1);
for(int i=L+1;i<=n;++i)
{
Data x;x.id=i;x.k=1;
x.v=S[a[i]]-S[Query(rt[i-L],rt[max(0,i-R-1)],1,top,1)];
Q.push(x);
}
long long ans=0;
while(K--)
{
Data x=Q.top();Q.pop();
ans+=x.v;
if(x.k==min(x.id-L,R-L+1))continue;
x.k++;
x.v=S[a[x.id]]-S[Query(rt[x.id-L],rt[max(0,x.id-R-1)],1,top,x.k)];
Q.push(x);
}
printf("%lld\n",ans);
return 0;
}

【BZOJ2006】超级钢琴(主席树,优先队列)的更多相关文章

  1. bzoj2006 noi2010 超级钢琴 主席树 + 优先队列

    Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 2435  Solved: 1195 Description 小 Z是一个小有名气的钢琴家,最近C博士送 ...

  2. [NOI2010][bzoj2006] 超级钢琴 [主席树/ST表+堆]

    题面: 传送门 思路: 首先容易想到用堆维护的O(n2logn)暴力 那么肯定就是在这个基础上套数据结构了[愉快] 然而我因为过于蒟蒻......只想得到主席树暴力***过去的方法 大概就是把前缀和算 ...

  3. [BZOJ2006] [NOI2010]超级钢琴 主席树+贪心+优先队列

    2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 3591  Solved: 1780[Submit][Statu ...

  4. [NOI2010]超级钢琴 主席树

    [NOI2010]超级钢琴 链接 luogu 思路 和12省联考的异或粽子一样. 堆维护n个左端点,每次取出来再放回去次 代码 #include <bits/stdc++.h> #defi ...

  5. 【BZOJ 2006】2006: [NOI2010]超级钢琴(RMQ+优先队列)

    2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 2792  Solved: 1388 Description 小 ...

  6. BZOJ 2006 NOI2010 超级钢琴 划分树+堆

    题目大意:给定一个序列.找到k个长度在[l,r]之间的序列.使得和最大 暴力O(n^2logn),肯定过不去 看到这题的第一眼我OTZ了一下午... 后来研究了非常久别人的题解才弄明确怎么回事...蒟 ...

  7. BZOJ2006 超级钢琴

    Description ​ 给定一个长度为n的区间,询问前k大的区间和,区间长度\(\in [L, R]\). $ n, k <= 500000$ Solution ​ 首先求前缀和.把一个区间 ...

  8. 【BZOJ2006】【NOI2010】超级钢琴(主席树,优先队列)

    [BZOJ2006]超级钢琴(主席树,优先队列) 题面 BZOJ 题解 既然是一段区间 首先就要变成单点 所以求一个前缀和 这个时候贪心很明显了: 枚举每一个点和可以和它组成一段的可行的点 全部丢进一 ...

  9. BZOJ2006[NOI2010]超级钢琴——堆+主席树

    题目描述 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的 音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度为Ai,其中 ...

随机推荐

  1. alertifyjs

    <%@ page contentType="text/html; charset=UTF-8"%> <!DOCTYPE html PUBLIC "-// ...

  2. PHP 批量获取指定目录下的文件列表(递归,穿透所有子目录)

    //调用 $dir = '/Users/xxx/www'; $exceptFolders = array('view','test'); $exceptFiles = array('BaseContr ...

  3. node.js简单搭建服务,访问本地站点文件

    1.安装nodejs服务(从官网下载安装),node相当于apache服务器 2.在自己定义的目录下新建服务器文件如 server.js 例如,我在D:\nodeJs下创建了server.js文件 v ...

  4. 关于UIButton嵌入到UIView点击无反应问题的解决方法和delegate的简单用法示例(转载)

    做项目封装UIView的时候碰到的问题,没想到有个哥们儿还写成博客,特此收藏! 问题是这样的,几个界面用到同一个自定义返回按钮,于是就想着把这个按钮单独封装起来,添加一个UIView类,在里面自定义U ...

  5. 算法提高 P1001

    必须感叹下,大数模板就是好用! AC代码: #include <cstdio> #include <cmath> #include <algorithm> #inc ...

  6. tox环境安装

    ubuntu 下安装tox环境 1.apt-get install pip 2.pip install tox 3.git git clone https://github.com/openstack ...

  7. php-fpm问题

    这个问题怎么说呢?之前遇到这个问题内心是奔溃的.因为我压根不知道是哪里出问题啦.不过,在我努力探索下,最终还是解决了问题. so请记住,坚持不一定成功,但放弃一定失败. 简单描述一下问题: 1.本地的 ...

  8. ubuntu14.04 安装redis 2.8.9

    ubuntu14.04安装前准备工作,为了保证安装顺利,请先执行apt-get update 然后安装make 和gcc(已安装的可忽略) apt-get install make apt-get i ...

  9. 和scikit-learn打个招呼

    1.先装对应的库.不能偷懒,都得装,不然飞不起来. pip install scikit-learn pip install numpy pip install scipy 2.测试如下代码. imp ...

  10. 总结MySQL大数据量下如何进行优化

    写在建库前: 在确定数据库业务后.建立数据库表格时,就应对一些常见问题有所考虑,以避免在数据增长一段时间后再做应对,可能造成时间及维护成本增加: 数据的月增量,年增量 数据的快速增长点 是否需要触发器 ...