【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. 训练 smallcorgi/Faster-RCNN_TF 模型(附ImageNet model百度云下载地址)

    1. 下载训练.验证.测试数据和 VOCdevkit,下载地址: http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtrainval_06-Nov-2 ...

  2. laravel服务容器-----深入理解控制反转(IoC)和依赖注入(DI)

    首先大家想一想什么是容器,字面意思就是盛放东西的东西,常见的变量,对象属性都是容器,一个容器能够装什么东西,完全在于你对这个容器的定义.有的容器不仅仅只是存文本,变量,而是对象,属性,那么我们通过这种 ...

  3. Kudu存储实战笔记

    有人会问,为啥要用这个叫啥Kudu的,Kudu是啥? 就像官网所说,Kudu是一个针对Apache hadoop 平台而开发的列式存储管理器,在本菜鸟看来,它是一种介于hdfs与hbase的一种存储. ...

  4. 移动web页面给用户发送邮件的方法

    微信商户通有这么一个需求,用户打开H5页面后,引导用户到电脑下载设计资源包,由于各种内部原因,被告知无后台资源支持,自己折腾了一段时间找了下面2个办法,简单做下笔记. 使用mailto功能,让用户自己 ...

  5. SQL SERVER FOR LINUX初体验

    今天得空,就在Ubuntu17.04上安装了SQL SERVER 2017体验下,总体来说还是不错的. 在Ubuntu上安装SQL SERVER 2017还是比较方便的,只需几条命令即可: curl ...

  6. jsz中的作用域与上下文

    var x=10; function fun() { console.log(x);//10 } function demo(f) { if(f instanceof Function){ fun() ...

  7. Jquery那些坑

    今天写Jquery的时候突然发现在将$("<td><td/>").appendTo(someElement)的时候发现一下子多出来两个,甚是奇怪,检查后端和 ...

  8. C语言_初步了解一下指针

    指针的基本概念 在计算机中,所有的数据都是存放在存储器中的. 一般把存储器中的一个字节称为一个内存单元, 不同的数据类型所占用的内存单元数不等,如整型量占2个单元,字符量占1个单元等.为了正确地访问这 ...

  9. UART知识总结

    一.定义 通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),通常称作UART. 二.时序 上图是uart协议传输一个"A" ...

  10. Python开发入门14天集训营-第一章

    python第一章 python变量 变量的作用 存数据 被程序调用和操作 标记数据 声明变量 name = "Ydh" 变量名 = 变量值 变量定义规范: 变量名只能是 字母.数 ...