BZOJ 2006 NOI2010 超级钢琴 划分树+堆
题目大意:给定一个序列。找到k个长度在[l,r]之间的序列。使得和最大
暴力O(n^2logn),肯定过不去
看到这题的第一眼我OTZ了一下午。。。
后来研究了非常久别人的题解才弄明确怎么回事。。。蒟蒻果然不能理解大神的思路啊0.0
首先维护前缀和,那么以第i个元素结尾的和最大的序列自然就是sum[i]-min{sum[j]}(i-r<=j<=i-l)
然后我们维护一个大根堆,每取走一个以i为结尾的元素,增加sum[i]-2thmin{sum[j]}。再取走这个元素就增加sum[i]-3thmin{sum[j]},以此类推
维护区间第k小,划分树。不说啥了吧 尼玛本大爷的划分树竟然还写挂了0.0
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define M 500500
using namespace std;
typedef pair<int,int> abcd;
typedef long long ll;
int n,k,l,r;ll ans;
int sum[M],a[M],b[M],c[M],s[22][M],now[M];
abcd heap[M];int top;
void insert(abcd x)
{
heap[++top]=x;
int t=top;
while(t>1&&heap[t]>heap[t>>1])
swap(heap[t],heap[t>>1]),t>>=1;
}
void pop()
{
heap[1]=heap[top--];
int t=2;
while(t<=top)
{
if(t<top&&heap[t+1]>heap[t])
t++;
if(heap[t]>heap[t>>1])
swap(heap[t],heap[t>>1]),t<<=1;
else
break;
}
}
void Build_Tree(int l,int r,int dpt)
{
int i,mid=l+r>>1;
int l1=l,l2=mid+1;
int left=mid-l+1;
if(l==r)
return ;
for(i=l;i<=r;i++)
left-=a[i]<c[mid];
for(i=l;i<=r;i++)
{
if(a[i]<c[mid]||a[i]==c[mid]&&left)
b[l1++]=a[i],s[dpt][i]=i==l?1:s[dpt][i-1]+1,left-=a[i]==c[mid];
else
b[l2++]=a[i],s[dpt][i]=i==l? 0:s[dpt][i-1];
}
memcpy(a+l,b+l,r-l+1<<2);
Build_Tree(l,mid,dpt+1);
Build_Tree(mid+1,r,dpt+1);
}
int Get_Ans(int l,int r,int dpt,int x,int y,int k)
{
int mid=l+r>>1;
int l1=x==l? 0:s[dpt][x-1],l2=s[dpt][y];
if(l==r)
return c[mid];
if(k<=l2-l1)
return Get_Ans(l,mid,dpt+1,l+l1,l+l2-1,k);
else
return Get_Ans(mid+1,r,dpt+1,(mid+1)+(x-l-l1),(mid+1)+(y-l+1-l2)-1,k-l2+l1);
}
int main()
{ //freopen("piano.in","r",stdin);
//freopen("piano.out","w",stdout); int i;
cin>>n>>k>>l>>r;
for(i=1;i<=n;i++)
scanf("%d",&sum[i]),sum[i]+=sum[i-1];
memcpy(a,sum,n+1<<2);
memcpy(c,sum,n+1<<2);
sort(c,c+n+1);
Build_Tree(0,n,0);
for(i=l;i<=n;i++)
{
now[i]=1;
int temp=Get_Ans(0,n,0,max(i-r,0),i-l,1);
insert( make_pair(sum[i]-temp,i) );
}
for(i=1;i<=k;i++)
{
abcd temp=heap[1];pop();
if( now[temp.second]!=(temp.second-l)-( max(temp.second-r,0) )+1 )
insert( make_pair(sum[temp.second]-Get_Ans(0,n,0,max(temp.second-r,0),temp.second-l,++now[temp.second]),temp.second) );
ans+=temp.first;
}
cout<<ans<<endl;
}
BZOJ 2006 NOI2010 超级钢琴 划分树+堆的更多相关文章
- BZOJ 2006: [NOI2010]超级钢琴 [ST表+堆 | 主席树]
题意: 一个序列,求k个不相同的长度属于\([L,R]\)的区间使得和最大 前缀和,对于每个r找最小的a[l] 然后我yy了一个可持久化线段树做法...也许会T 实际上主席树就可以了,区间k小值 然后 ...
- bzoj 2006 [NOI2010]超级钢琴——ST表+堆
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2006 每个右端点的左端点在一个区间内:用堆记录端点位置.可选区间,按价值排序:拿出一个后也许 ...
- BZOJ 2006: [NOI2010]超级钢琴 ST表+堆
开始想到了一个二分+主席树的 $O(n\log^2 n)$ 的做法. 能过,但是太无脑了. 看了一下题解,有一个 ST 表+堆的优美解法. 你发现肯定是选取前 k 大最优. 然后第一次选的话直接选固定 ...
- Bzoj 2006: [NOI2010]超级钢琴 堆,ST表
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2222 Solved: 1082[Submit][Statu ...
- BZOJ 2006: [NOI2010]超级钢琴( RMQ + 堆 )
取最大的K个, 用堆和RMQ来加速... ----------------------------------------------------------------- #include<c ...
- BZOJ 2006: [NOI2010]超级钢琴
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2613 Solved: 1297[Submit][Statu ...
- 洛谷 P2048 BZOJ 2006 [NOI2010]超级钢琴
题目描述 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度为Ai,其中A ...
- BZOJ 2006 [NOI2010]超级钢琴 (堆+主席树)
题面:BZOJ传送门 洛谷传送门 让你求前$K$大的子序列和,$n\leq 5*10^{5}$ 只想到了个$nlog^{2}n$的做法,似乎要被卡常就看题解了.. 好神奇的操作啊,我傻了 我们把序列和 ...
- BZOJ.2006.[NOI2010]超级钢琴(贪心 堆)
BZOJ 洛谷 思路和BZOJ3784一样,用前缀和+堆维护.做那题吧,不赘述啦. (没错我就是水一个AC) //54620kb 1060ms #include <queue> #incl ...
随机推荐
- 李兴华JavaWeb开发笔记
李兴华JavaWeb开发笔记 1.Java语法-基础 环境变量-JAVA_HOME, PATH, ClassPath 变量名 作用 举例 JAVA_HOME 指向JDK目录 C:\Program Fi ...
- 安卓MP3播放器开发实例(1)之音乐列表界面
学习安卓开发有一年了,想想这一年的努力,确实也收获了不少.也找到了比較如意的工作. 今天准备分享一个以前在初学阶段练习的一个项目.通过这个项目我真正的找到了开发安卓软件的感觉,从此逐渐步入安卓开发的正 ...
- Fitnesse使用系列二
决策表 Fitnesse中提供了好几种表格样式,前面说了.表格是运行測试的关键.从字面看.表格描写叙述的是測试用例.从运行角度看,表格为后端的代码(fitnesse里称作fixture)提供了包名.类 ...
- CentOS 7没有ifconfig命令处理
新安装CentOS 7 64位后发现查看ip配置的时候没有ifconfig,百度后发现# yum install net-tools软件包即可.
- POJ2155:Matrix(二维树状数组,经典)
Description Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the ...
- 开源语法分析器--ANTLR
序言 有的时候,我还真是怀疑过上本科时候学的那些原理课究竟是不是在浪费时间.比方学完操作系统原理之后我们并不能自己动手实现一个操作系统:学完数据库原理我们也不能弄出个像样的DBMS出来:相同,学完 ...
- 全面剖析Redis Cluster原理和应用 (转)
1.Redis Cluster总览 1.1 设计原则和初衷 在官方文档Cluster Spec中,作者详细介绍了Redis集群为什么要设计成现在的样子.最核心的目标有三个: 性能:这是Redis赖以生 ...
- 将svnkit转成dlls时的问题
未处理 System.TypeInitializationException Message="“org.tmatesoft.svn.core.internal.wc.DefaultSVNO ...
- OpenCV 通过 MFC 的 Picture Control 控件操作图像
假设希望对显示在MFC Picture Control 控件里的图像进行操作,比方画线画点之类的,能够利用 OpenCV 结合 MFC 本身的鼠标响应函数来实现. 怎样将图像显示到 Picture C ...
- Android JNI 获取应用程序签名
使用Android JNI 获取应用程序签名. 获取基础上生成自己的签名password,这可以防止别人反编译找到自己的源代码password. jstring Java_com_masonsdk_j ...