BZOJ 2006 超级钢琴(划分树+优先队列)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2006
题意: 给出一个数列A,L,R,构造出一个新的集合,集合中的数字为A中任意连续t(L<=t<=R)个数字的和(集合中的数字可以重复)。求集合中前K大的数字和。
思路:首先,我们令S[i]表示A的前i项和,P[i] 表示以A中第i个数字结尾可以取到的最大值,那么显然有:
求出P之后,我们可以用一个堆或者优先队列来维护最大值。那么现在来了另外一个问题,某次在优先队列中取得的是P[i],那么显然要将其从优先队列中删除,此时,以i结尾的次大值也是有可能成为最后答案中一部分的,类似的,我们可能还要求第三大、第四大,也就是求一段区间的第三小、第四小等,我们可以用划分树解决这个问题。现在,整个问题都解决了,首先,求出S,将S建立划分树。然后将所有P插入优先队列。每次从优先队列中取出最大值,删掉,并将这个最大值对应的原数列中位置结尾的下一大的值插入优先队列(这一步也就是在划分树中找到下一小的值),直到取出K个。
int n,m,L,R;
i64 b[N],s[N],S[N];
struct node
{
int L,R;
};
node a[N<<2];
i64 t[35][N];
int tot[35][N];
void init()
{
RD(n,m); RD(L,R);
int i;
for(i=2;i<=n+1;i++) RD(b[i]),S[i]=t[1][i]=s[i]=s[i-1]+b[i];
n++;
sort(s+1,s+n+1);
}
void build(int dep,int u,int L,int R)
{
a[u].L=L;
a[u].R=R;
if(L==R) return;
int mid=(L+R)>>1;
int i,sameNum=mid-L+1;
FOR(i,L,R) if(t[dep][i]<s[mid]) sameNum--;
int LL=L,LR=mid,RL=mid+1,RR=R;
int Lnum=0,Rnum=0;
i64 x;
FOR(i,L,R)
{
if(i==L) tot[dep][i]=0;
else tot[dep][i]=tot[dep][i-1];
x=t[dep][i];
if(x<s[mid])
{
tot[dep][i]++;
t[dep+1][LL+Lnum]=x;
Lnum++;
}
else if(x>s[mid])
{
t[dep+1][RL+Rnum]=x;
Rnum++;
}
else
{
if(sameNum>0)
{
sameNum--;
tot[dep][i]++;
t[dep+1][LL+Lnum]=x;
Lnum++;
}
else
{
t[dep+1][RL+Rnum]=x;
Rnum++;
}
}
}
build(dep+1,u*2,LL,LR);
build(dep+1,u*2+1,RL,RR);
}
i64 query(int dep,int u,int L,int R,int K)
{
if(L==R) return t[dep][L];
int x,y,xx,yy,_L,_R;
int mid=(a[u].L+a[u].R)>>1;
if(L==a[u].L) x=0;
else x=tot[dep][L-1];
y=tot[dep][R]-x;
if(y>=K)
{
_L=a[u].L+x;
_R=a[u].L+x+y-1;
return query(dep+1,u*2,_L,_R,K);
}
else
{
xx=L-a[u].L-x;
yy=R-L+1-y;
_L=mid+1+xx;
_R=mid+1+xx+yy-1;
return query(dep+1,u*2+1,_L,_R,K-y);
}
}
struct Node
{
int pos,k;
i64 x;
Node(){}
Node(int _pos,int _k,i64 _x)
{
pos=_pos;
k=_k;
x=_x;
}
int operator<(const Node &a) const
{
return x<a.x;
}
};
priority_queue<Node> Q;
int main()
{
init(); build(1,1,1,n);
int i,x,y;
for(i=L+1;i<=n;i++)
{
x=max(1,i-R);
y=i-L;
Q.push(Node(i,1,S[i]-query(1,1,x,y,1)));
}
i64 ans=0;
Node p;
while(m--)
{
p=Q.top(); Q.pop();
ans+=p.x;
x=max(1,p.pos-R);
y=p.pos-L;
if(p.k+1>y-x+1) continue;
Q.push(Node(p.pos,p.k+1,S[p.pos]-query(1,1,x,y,p.k+1)));
}
PR(ans);
}
BZOJ 2006 超级钢琴(划分树+优先队列)的更多相关文章
- BZOJ 2006 NOI2010 超级钢琴 划分树+堆
题目大意:给定一个序列.找到k个长度在[l,r]之间的序列.使得和最大 暴力O(n^2logn),肯定过不去 看到这题的第一眼我OTZ了一下午... 后来研究了非常久别人的题解才弄明确怎么回事...蒟 ...
- bzoj2006 noi2010 超级钢琴 主席树 + 优先队列
Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2435 Solved: 1195 Description 小 Z是一个小有名气的钢琴家,最近C博士送 ...
- BZOJ 2006 超级钢琴(堆+主席树)
很好的一道题. 题意:给出长度为n的数列,选择k个互不相同的区间,满足每个区间长度在[L,R]内,求所有选择的区间和的总和最大是多少.(n,k<=5e5). 首先将区间和转化为前缀和之差,那么我 ...
- [BZOJ 2006] 超级钢琴
Link: https://www.lydsy.com/JudgeOnline/problem.php?id=2006 Algorithm: 对于此类区间最值类问题,我们可以通过控制一端不变来寻找当前 ...
- bzoj 2006 超级钢琴 —— ST表
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2006 本来应该是可以用主席树,找区间最小值,取出来后再找那段区间的次小值...... 但也可 ...
- 【BZOJ 2006】2006: [NOI2010]超级钢琴(RMQ+优先队列)
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2792 Solved: 1388 Description 小 ...
- [BZOJ2006] [NOI2010]超级钢琴 主席树+贪心+优先队列
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 3591 Solved: 1780[Submit][Statu ...
- [NOI2010]超级钢琴 主席树
[NOI2010]超级钢琴 链接 luogu 思路 和12省联考的异或粽子一样. 堆维护n个左端点,每次取出来再放回去次 代码 #include <bits/stdc++.h> #defi ...
- [NOI2010][bzoj2006] 超级钢琴 [主席树/ST表+堆]
题面: 传送门 思路: 首先容易想到用堆维护的O(n2logn)暴力 那么肯定就是在这个基础上套数据结构了[愉快] 然而我因为过于蒟蒻......只想得到主席树暴力***过去的方法 大概就是把前缀和算 ...
随机推荐
- windows phone MVVM开发心得第一天
之前刚刚学了asp.net网站的三层架构,为其中的优点着迷,可惜寒假本来决定学下MVC的计划泡汤了,刚开学,学了下windows phone 的MVVM模式的开发,在此留下点心得和脚印,第一天只是学了 ...
- PE文件之资源讲解
资源是PE文件中非常重要的部分,几乎所有的PE文件中都包含资源,与导入表与导出表相比,资源的组织方式要复杂得多,要了解资源的话,重点在于了解资源整体上的组织结构. 我们知道,PE文件资源中的内容包括: ...
- DSP中常用的C语言关键字
const Ø使用:const 数据类型 变量名: Ø作用:优化存储器的分配,表示变量的内容是常数,不会改变. Ø举例:const char tab[1024]={显示数据}; volatile(易变 ...
- uitableviewcell 和 uibutton
如果cell上面只有一个button 可以设置button.tag=IndexPath.Row;得到当前点击的行数,设置button属性的时候,可以设置一个全局的button来记住当前点击的butt ...
- BZOJ 2038
基础不牢:补莫队算法: 莫队算法入门题: 2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 26 ...
- cache应用(asp.net 2.0 SQL数据缓存依赖 [SqlCacheDependency ] )
Asp.net 2.0 提供了一个新的数据缓存功能,就是利用sql server2005 的异步通知功能来实现缓存 1.首先在sqlserver2005 中创建一个test的数据库. 在SQL Ser ...
- 简单CSS hack:区分IE6、IE7、IE8、Firefox、Opera
一.跨浏览器的网页设计一直是让人很头疼的问题,这不只是因为浏览器的版本众多,还有一个重要的原因是相同浏览器的不同时期的版本也会有差异,甚至是在不同操作同台上还会有不同.因此使CSS hack技术进行浏 ...
- Unity3D 将 Unity 嵌入WPF中的一些研究笔记
一. 在 WPF 中使用 WebBrowser,直接打开 WebPlayer.html 以这种方式有一个问题是. 无法在 WebBrowser 的上面 放置其它的控件, 在运行时,都不会显示 . 以 ...
- close和shutdown的区别
转的,没验证 close(sock_fd)会把sock_fd的内部计数器减1当sock_fd的内部计数器为0时, 才调用shutodwn(), 并最终释放文件描述符调用shutdown()只是进行了T ...
- Java 8怎么了之二:函数和原语
[编者按]本文作者为专注于自然语言处理多年的 Pierre-Yves Saumont,Pierre-Yves 著有30多本主讲 Java 软件开发的书籍,自2008开始供职于 Alcatel-Luce ...