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

    题意

    给定一个长为n的序列,从中选出k个不同的长度在[L,R]范围内的区间,使得这些选出的数的和最大

    思路

    1. 区间求和,首先要求前缀和sum

    2. 如果固定了左端点,那么右端点就会在右边一定范围内移动,我们把固定的左端点设为p,右边的范围设为[l,r],以p为左端点的最大区间的右端点一定是在[l,r]范围内的最大sum所在的位置,即求区间最大,由于不带修改,所以所有的sum不会改变,求区间最大可以用ST表完成,只是这里的ST表维护最大值所在的位置而不是值。再开一个堆来维护(p,l,r)这样的三元组的最大值即可

    3. 不能取重复区间。如果取了一个区间[p,t],将[l,r]拆成[l,t-1],[t+1,r]重新分别和t插入堆中即可

    Code:

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cmath>
    #define N 500005
    using namespace std;
    typedef long long ll;
    int n,k,L,R;
    ll a[N],sum[N];
    int maxx[N][21],lg[N];
    
    int getmax(int l,int r)
    {
    	int LG=lg[r-l+1];
    	int x=maxx[l][LG],y=maxx[r-(1<<LG)+1][LG];
    	return sum[x] > sum[y] ? x : y; 
    }
    struct Node
    {
    	int p,l,r;	
    	bool operator < (const Node a)const 
    	{
    		return sum[getmax(a.l,a.r)]-sum[a.p-1]>sum[getmax(l,r)]-sum[p-1];
    	}
    };
    priority_queue<Node> q;
    
    template <class T>
    void read(T &x)
    {
    	char c;int sign=1;
    	while((c=getchar())>'9'||c<'0') if(c=='-') sign=-1; x=c-48;
    	while((c=getchar())>='0'&&c<='9') x=(x<<1)+(x<<3)+c-48; x*=sign;
    }
    void init()
    {
    	for(int i=1;i<=n;++i) maxx[i][0] = i;
    	for(int i=n;i>=1;--i)
    		for(int j=1;i+(1<<j)-1<=n;++j)
    		{
    			int x=maxx[i][j-1],y=maxx[i+(1<<j-1)][j-1];
    			maxx[i][j]=sum[x]>sum[y] ? x : y;
    		}
    	for(int i=1;i<=n;++i) lg[i]=log2(i);
    }
    int main()
    {
    	read(n);read(k);read(L);read(R);
    	for(int i=1;i<=n;++i)
    	{
    		read(a[i]);
    		sum[i]=sum[i-1]+a[i];
    	}
    	init();
    	for(int i=1;i<=n;++i) if(i+L-1<=n) q.push((Node){i,i+L-1,min(n,i+R-1)});
    	ll ans=0;
    	for(int i=1;i<=k;++i)
    	{
    		Node u=q.top();q.pop();
    		int t=getmax(u.l,u.r);
    		ans+=(sum[t]-sum[u.p-1]);
    		if(u.l!=t) q.push((Node){u.p,u.l,t-1});
    		if(u.r!=t) q.push((Node){u.p,t+1,u.r});
    	}
    	cout<<ans<<endl;
    	return 0;
    }
    
  • 相关阅读:
    JavaWeb--HttpSession案例
    codeforces B. Balls Game 解题报告
    hdu 1711 Number Sequence 解题报告
    codeforces B. Online Meeting 解题报告
    ZOJ 3706 Break Standard Weight 解题报告
    codeforces C. Magic Formulas 解题报告
    codeforces B. Sereja and Mirroring 解题报告
    zoj 1109 Language of FatMouse 解题报告
    hdu 1361.Parencodings 解题报告
    hdu 1004 Let the Balloon Rise 解题报告
  • 原文地址:https://www.cnblogs.com/Chtholly/p/11293738.html
Copyright © 2011-2022 走看看