bzoj2006 [NOI2010]超级钢琴 堆+ST表/主席树
2017-10-21 16:10
579 查看
题意:Y sera 陷入了沉睡,幻境中它梦到一个长度为N 的序列{Ai}。
对于这个序列的每一个子串,定义其幻境值为这个子串的和,现在Y sera 希望选择K 个不同的子串并使得这K 个子串的幻境值之和最大。
然而由于梦境中的种种限制,这些子串的长度必须在L 到R 之间。
你需要告诉她,最大的幻境值之和。
比赛题目的描述直接拿过来用了。
很久之前做的一道题目,所以没有第一时间认出来,而且当时也是用的主席树,感觉亏成狗。。看来当时做的时候就没有很理解。。。
其实挺好想的一道题目,比赛的时候想到了正解但是已经没有时间了。
把区间按照右端点分类,先预处理每个点作为右端点的最优左端点。
然后可以发现,次优的答案一定在上一次左端点的左边或者右边。。所以每一次做完一个区间以后,往堆中加入形如l,t-1和t+1,r的区间,用st表进行区间最小值查询。
感觉不是很能理解我为什么要打主席树。。
对于这个序列的每一个子串,定义其幻境值为这个子串的和,现在Y sera 希望选择K 个不同的子串并使得这K 个子串的幻境值之和最大。
然而由于梦境中的种种限制,这些子串的长度必须在L 到R 之间。
你需要告诉她,最大的幻境值之和。
比赛题目的描述直接拿过来用了。
很久之前做的一道题目,所以没有第一时间认出来,而且当时也是用的主席树,感觉亏成狗。。看来当时做的时候就没有很理解。。。
其实挺好想的一道题目,比赛的时候想到了正解但是已经没有时间了。
把区间按照右端点分类,先预处理每个点作为右端点的最优左端点。
然后可以发现,次优的答案一定在上一次左端点的左边或者右边。。所以每一次做完一个区间以后,往堆中加入形如l,t-1和t+1,r的区间,用st表进行区间最小值查询。
感觉不是很能理解我为什么要打主席树。。
#include<cstdio> #include<cstring> #include<algorithm> #define fo(i,a,b) for(int i=a;i<=b;i++) #define fd(i,a,b) for(int i=a;i>=b;i--) using namespace std; const int N=5e5+5; const int inf=1e9; typedef long long ll; struct node { int v,p,l,r,t; bool operator <(const node& x) const { return v<x.v; } }t[N*5]; int a ,sum ,cnt; int mn [21],lg ,n,m,l,r; inline int find(int l,int r) { int x=lg[r-l+1]; if (sum[mn[l][x]]<sum[mn[r-(1<<x)+1][x]]) return mn[l][x]; else return mn[r-(1<<x)+1][x]; } int main() { freopen("fantasy.in","r",stdin); freopen("fantasy.out","w",stdout); scanf("%d%d%d%d",&n,&m,&l,&r); fo(i,1,n) { scanf("%d",&a[i]); sum[i]=sum[i-1]+a[i]; } fo(i,0,n) { mn[i][0]=i; if (i<=1)lg[i]=0; else lg[i]=lg[i>>1]+1; } fo(j,1,19) fo(i,0,n) { if (sum[mn[i][j-1]]<sum[mn[i+(1<<(j-1))][j-1]]) mn[i][j]=mn[i][j-1]; else mn[i][j]=mn[i+(1<<(j-1))][j-1]; } fo(i,l,n) { int L=max(0,i-r); int R=i-l,pos=find(L,R); t[cnt++]=(node){sum[i]-sum[pos],i,L,R,pos}; } ll ans=0; make_heap(t,t+cnt); while (m--) { node x=t[0]; pop_heap(t,t+(cnt--)); ans+=x.v; if (x.t>x.l) { int y=find(x.l,x.t-1); t[cnt++]=(node){sum[x.p]-sum[y],x.p,x.l,x.t-1,y}; push_heap(t,t+cnt); } if (x.t<x.r) { int y=find(x.t+1,x.r); t[cnt++]=(node){sum[x.p]-sum[y],x.p,x.t+1,x.r,y}; push_heap(t,t+cnt); } } printf("%lld\n",ans); }
相关文章推荐
- 【BZOJ2006】【NOI2010】超级钢琴 Heap+主席树
- [NOI2010][bzoj2006] 超级钢琴 [主席树/ST表+堆]
- [BZOJ2006][NOI2010][RMQ/主席树][二叉堆]超级钢琴
- BZOJ 2006: [NOI2010]超级钢琴 [ST表+堆 | 主席树]
- BZOJ 2006 NOI 2010 超级钢琴 堆+主席树
- BZOJ 2006 [NOI2010]超级钢琴 主席树+堆
- 【BZOJ 2006】2006: [NOI2010]超级钢琴(RMQ+优先队列)
- BZOJ2006: [NOI2010]超级钢琴
- bzoj2006 [NOI2010]超级钢琴
- 【bzoj2006】 NOI2010—超级钢琴
- bzoj2006 [NOI2010]超级钢琴
- BZOJ 2006 NOI2010 超级钢琴 划分树+堆
- BZOJ 2006: [NOI2010]超级钢琴( RMQ + 堆 )
- BZOJ 2006: [NOI2010]超级钢琴
- [BZOJ2006][NOI2010]超级钢琴(ST表+堆)
- [BZOJ2006][NOI2010]超级钢琴(st表+堆贪心)
- bzoj 2006: [NOI2010]超级钢琴
- Bzoj 2006: [NOI2010]超级钢琴 堆,ST表
- bzoj 2006: [NOI2010]超级钢琴 可持久化线段树+优先队列
- [BZOJ2006][NOI2010]超级钢琴-ST表+堆