码迷,mamicode.com
首页 > 其他好文 > 详细

2006: [NOI2010]超级钢琴|ST表|堆

时间:2016-04-06 11:30:26      阅读:169      评论:0      收藏:0      [点我收藏+]

标签:

由于K很小,所以就直接取出最大的K个值加起来即可
考虑一个(i,l,r)表示以i开始以[l,r]中的某个位置结束的区间和的最大值,假设这个位置为p,然后把这些东西都存起来一起扔到堆中,每次取出区间和最大的一个元素,然后继续向堆中添加新的元素,直接对(i,l,p?1),(i,p+1,r)这两个组合再分别找出最大的区间和再扔到堆中,然后重复此过程直到找出前K
(i,l,r)组合的最大区间和为max(sum[l],sum[l+1]...sum[r])?sum[i?1],找(i,l,r)组合的最大区间和可以开一个ST表来维护,先求一个前缀和,然后ST表维护区间最大值

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#define N 500550
using namespace std;
int sc()
{
    int i=0,f=1;char c=getchar();
    while(c>‘9‘||c<‘0‘){if(c==‘-‘)f=-1;c=getchar();}
    while(c>=‘0‘&&c<=‘9‘)i=i*10+c-‘0‘,c=getchar();
    return i*f;
}
struct W{
    int i,l,r,p;long long sum;
};
long long f[N][22],sum[N],ans;
int a[N],n,k,L,R;
void pre()
{
    for(int i=1;i<=n;i++) f[i][0]=i;
    for(int k=1;k<=19;k++)
        for(int i=1;i<=n;i++)
            if(i+(1<<k)>n+1)break;
            else f[i][k]=sum[f[i][k-1]]>sum[f[i+(1<<k-1)][k-1]]?f[i][k-1]:f[i+(1<<k-1)][k-1];
}
int ask(int l,int r)
{
    int k=log2(r-l+1);
    return sum[f[l][k]]>sum[f[r-(1<<k)+1][k]]?f[l][k]:f[r-(1<<k)+1][k];
}
priority_queue<W,vector<W> > q;
bool operator<(W a,W b){return a.sum<b.sum;}
int main()
{
    n=sc();k=sc(),L=sc(),R=sc();
    for(int i=1;i<=n;i++)
        sum[i]=sum[i-1]+(a[i]=sc());
    pre();
    for(int i=1;i<=n-L+1;i++)
    {
        int l=i+L-1,r=min(n,i+R-1);
        int p=ask(l,r);
        q.push((W){i,l,r,p,sum[p]-sum[i-1]});
    }
    while(k--)
    {
        W x=q.top();q.pop();ans+=x.sum;
        int i=x.i,l=x.l,r=x.r,p=x.p;
        if(l<p)
        {
            int w=ask(l,p-1);
            q.push((W){i,l,p-1,w,sum[w]-sum[i-1]});
        }
        if(p<r)
        {
            int w=ask(p+1,r);
            q.push((W){i,p+1,r,w,sum[w]-sum[i-1]});
        }
    }
    cout<<ans;
    return 0;
}

2006: [NOI2010]超级钢琴|ST表|堆

标签:

原文地址:http://blog.csdn.net/ws_yzy/article/details/51072474

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!