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 ...
随机推荐
- android在Canvas使用drawBitmap画一幅画
1.画图的主要方法 //Bitmap:图片对象,left:向左偏移.top: 顶部偏移 drawBitmap(Bitmap bitmap, float left, float top, Pai ...
- Qt中提高sqlite的读写速度(使用事务一次性写入100万条数据)
SQLite数据库本质上来讲就是一个磁盘上的文件,所以一切的数据库操作其实都会转化为对文件的操作,而频繁的文件操作将会是一个很好时的过程,会极大地影响数据库存取的速度.例如:向数据库中插入100万条数 ...
- poj 动态规划的主题列表和总结
此文转载别人,希望自己可以做完这些题目. 1.POJ动态规划题目列表 easy:1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, ...
- 初始化openwrt的rootpassword
更改openwrt源代码 shadow 文件 package/base-files/files/etc/shadow shadow 文件參考http://blog.csdn.net/u01164188 ...
- oschina 编程语言
编程语言 Java C/C++ Objective-C PHP Perl Python Ruby C# .NET ASP Google Go D语言 Groovy Scala JavaScript T ...
- 传京东副总裁蒉莺春或将接管POP业务-搜狐IT
传京东副总裁蒉莺春或将接管POP业务-搜狐IT 传京东副总裁蒉莺春或将接管POP业务
- C#的百度地图开发(一)发起HTTP请求
原文:C#的百度地图开发(一)发起HTTP请求 百度地图的开发文档中给出了很多的事例,而当用到具体的语言来开发时,又会有些差异.我是使用C#来开发的.在获取相应的数据时,需要通过URL传值,然后获取相 ...
- 啊上班我排名可人皮号i家狂喷
http://pan.baidu.com/share/link?shareid=3011665141&uk=338692646&third=15 http ...
- getline与get函数的区别
get()函数相对getline来说使用方法要灵活的多了. 1. int get()是指从流中抽取单个字符并返回,这个是没有參数的形式.由于c++不像c语言使用getchar() 2.istrea ...
- NYOJ 104 最大子矩阵(二维DP)
最大和 时间限制:1000 ms | 内存限制:65535 KB 难度:5 描写叙述 给定一个由整数组成二维矩阵(r*c),如今须要找出它的一个子矩阵,使得这个子矩阵内的全部元素之和最大,并把这个 ...