【NOI2010T2】超级钢琴-主席树+优先队列
来源:互联网 发布:wifi网络测试工具 编辑:程序博客网 时间:2024/04/29 16:32
测试地址:超级钢琴
做法:题目要求的是,给定数列中长度在
实际上我们可以一个一个地提取出前
取出了最大子段和后,要求次大子段和了,这回要怎么办呢?其实我们可以在求最大子段和的时候排除掉已经取掉的子段,假设这个子段以
注意在使用主席树的时候,要开够空间,不然会RE或WA(只是显示,实质上还是RE)。
以下是本人代码:
#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>#include <queue>#define ll long longusing namespace std;int n,K,L,R,tot=0,a[500010],pos[500010],rt[500010],t[500010];ll sum[500010];int seg[20000010],lft[20000010],rht[20000010];struct forsort {int val,id;} f[500010];struct state{ ll val; int id; bool operator < (state a) const { return val<a.val; }};priority_queue <state> Q;bool cmp(forsort a,forsort b){ return a.val<b.val;}void buildtree(int &no,int l,int r){ no=++tot; seg[no]=0; if (l==r) return; int mid=(l+r)>>1; buildtree(lft[no],l,mid); buildtree(rht[no],mid+1,r);}void add(int &no,int last,int l,int r,int x){ no=++tot; seg[no]=seg[last],lft[no]=lft[last],rht[no]=rht[last]; if (l==r) { seg[no]++; return; } int mid=(l+r)>>1; if (x<=mid) add(lft[no],lft[last],l,mid,x); else add(rht[no],rht[last],mid+1,r,x); seg[no]=seg[lft[no]]+seg[rht[no]];}int query(int l,int r,int k){ if (k>seg[rt[r]]-seg[rt[l-1]]) return -1; int last=rt[l-1],no=rt[r],x=1,y=n+1; while(x!=y) { int mid=(x+y)>>1; if (seg[lft[no]]-seg[lft[last]]>=k) y=mid,no=lft[no],last=lft[last]; else x=mid+1,k-=seg[lft[no]]-seg[lft[last]],no=rht[no],last=rht[last]; } return f[x].id-1;}void work1(){ scanf("%d%d%d%d",&n,&K,&L,&R); f[1].id=1,f[1].val=0; sum[0]=0; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); f[i+1].id=i+1,f[i+1].val=f[i].val+a[i]; sum[i]=(ll)f[i+1].val; } sort(f+1,f+n+2,cmp); for(int i=1;i<=n+1;i++) { pos[f[i].id]=i; } buildtree(rt[0],1,n+1); for(int i=1;i<=n+1;i++) add(rt[i],rt[i-1],1,n+1,pos[i]);}void work2(){ state next; for(int i=L;i<=n;i++) { t[i]=1; int p=query(max(i-R+1,1),i-L+1,t[i]); next.val=sum[i]-sum[p],next.id=i; Q.push(next); } ll ans=0; while(K--) { state now=Q.top();Q.pop(); ans+=now.val; t[now.id]++; int p=query(max(now.id-R+1,1),now.id-L+1,t[now.id]); if (p!=-1) { next.val=sum[now.id]-sum[p],next.id=now.id; Q.push(next); } } printf("%lld",ans);}int main(){ work1(); work2(); return 0;}
- 【NOI2010T2】超级钢琴-主席树+优先队列
- bzoj2006NOI2010超级钢琴 主席树+优先队列
- [BZOJ2006][[NOI2010]超级钢琴][优先队列+线段树]
- bzoj2006 [NOI2010]超级钢琴 [优先队列|RMQ]
- 【BZOJ2006】【NOI2010】超级钢琴 Heap+主席树
- bzoj 2006: [NOI2010]超级钢琴 可持久化线段树+优先队列
- 2006: [NOI2010]超级钢琴 ST表+优先队列
- bzoj 2006: [NOI2010]超级钢琴 (st表+优先队列)
- BZOJ 2006: [NOI2010]超级钢琴 RMQ 优先队列
- [Noi2010] D1T2 超级钢琴 (ST表 线段树 主席树)
- [BZOJ2006][NOI2010][RMQ/主席树][二叉堆]超级钢琴
- BZOJ 2006 NOI 2010 超级钢琴 堆+主席树
- BZOJ 2006 [NOI2010]超级钢琴 主席树+堆
- bzoj2006 [NOI2010]超级钢琴 堆+ST表/主席树
- BZOJ2006【主席树】【优先队列】
- 【bzoj 2006】【codevs 2934】[NOI2010]超级钢琴(st表+优先队列)
- 超级钢琴
- NOI 2010 超级钢琴
- JAVA基础
- Linux内核学习笔记
- Elasticsearch-terms搜索及结果优化
- 模拟进程队列管理——按照优先级出列
- Mybatis 之 ParameterHandler
- 【NOI2010T2】超级钢琴-主席树+优先队列
- 启动hadoop时的两个警告
- 【CUGBACM15级BC第33场 A】hdu 5186 zhx's submissions
- Linux学前知识2
- 欢迎使用CSDN-markdown编辑器
- KVM构建线上虚拟平台(较长)
- listen()函数中backlog参数分析
- apache如何设置缓存
- leetcode 81. Search in Rotated Sorted Array II 二分查找