zoukankan      html  css  js  c++  java
  • BZOJ 2006: [NOI2010]超级钢琴

    题目大意:

    一个区间的价值为区间内所有数的和

    求序列中长度在L至R的区间中价值前k大的区间的价值和。

    题解:

    一个区间价值用s[r]-s[l]来表示,s为前缀和。假设固定了右端点,则可以通过st表来确定左端点的最优位置。对于所有的右端点,我们将他们扔进堆里就能找出最大值来。

    然后对于一个右端点确定了一个左端点,之后对于这个右端点这个左端点就不能选了,所以把原来区间断成两端,再扔进堆里。重复k次就可以了。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #define ma make_pair
    #define pr pair<int,int>
    #define prr pair<pr,pr>
    #define mp make_pair
    #define fr first
    #define sc second
    using namespace std;
    int n,k,l,r,a[1000005],lg[1000005],st[500005][21],sum[1000005];
    priority_queue<prr> q;
    int calc(int a,int b){
    	if (sum[a]<sum[b]) return a;
    	else return b;
    }
    int query(int a,int b){
    	if (a>b) return -1;
    	int len=lg[b-a+1];
    	return calc(st[a][len],st[b-(1<<len)+1][len]);
    }
    int main(){
    	scanf("%d%d%d%d",&n,&k,&l,&r);
    	for (int i=1; i<=n; i++){
    		scanf("%d",&a[i]);
    		sum[i]=sum[i-1]+a[i]; 
    	}
    	for (int i=2; i<=n; i++) lg[i]=lg[i>>1]+1;
    	for (int i=1; i<=n; i++) st[i][0]=i;
    	for (int j=1; (1<<j)<=n; j++)
    		for (int i=0; i+(1<<j)-1<=n; i++)
    			st[i][j]=calc(st[i][j-1],st[i+(1<<j-1)][j-1]);
    	for (int i=l; i<=n; i++)
    		q.push(mp(mp(sum[i]-sum[query(max(i-r,0),i-l)],i),mp(max(i-r,0),i-l)));
    	long long ans=0;
    	for (int i=1; i<=k; i++){
    		ans+=q.top().fr.fr;
    		int x=q.top().fr.sc,a=q.top().sc.fr,b=q.top().sc.sc,y=query(a,b);
    		q.pop();
    		int id1=query(a,y-1),id2=query(y+1,b);
    		if (id1!=-1) q.push(mp(mp(sum[x]-sum[id1],x),mp(a,y-1)));
    		if (id2!=-1) q.push(mp(mp(sum[x]-sum[id2],x),mp(y+1,b)));
    	} 
    	printf("%lld
    ",ans);
    	return 0;
    }
    

      

  • 相关阅读:
    spymemcache与spring结合
    Turtle库的学习积累
    汉诺塔绘图学习
    计算圆周率π和显示进度条
    川菜 in English
    一些必不可少的Sublime Text 2插件 钟磊的专栏 博客频道 CSDN.NET
    \usepackage{natbib}在latex模板写作中的心得_格致轩_百度空间
    Geant4新版本:新安装方法,新运行方式
    ubuntu系统备份
    Latex数学公式中的空格
  • 原文地址:https://www.cnblogs.com/silenty/p/8733051.html
Copyright © 2011-2022 走看看