[NOI2010]超级钢琴

[题目链接]

         https://www.lydsy.com/JudgeOnline/problem.php?id=2006

[算法]

          Sprase Table + 堆

[代码]

       

#include<bits/stdc++.h>
using namespace std;
#define MAXN 500010
#define MAXLOG 20

struct info
{
    int val,pos,l,r;
    friend bool operator < (info a,info b)
    {
        return a.val < b.val;
    }
} ;

int i,j,m1,m2,n,k,l,r,x,pos;
long long ans;
int mn[MAXN][MAXLOG];
int sum[MAXN];
priority_queue< info > q;
info tmp;

inline int my_min(int x,int y)
{
    return sum[x] < sum[y] ? x : y;
}
inline int query(int l,int r)
{
    if (l > r) return -1;
    int k = log(r - l + 1) / log(2.0);    
    return my_min(mn[l][k],mn[r-(1<<k)+1][k]);
}

int main()
{
    
    scanf("%d%d%d%d",&n,&k,&l,&r);
    for (i = 1; i <= n; i++)
    {
        scanf("%d",&x);
        sum[i] = sum[i-1] + x;
        mn[i][0] = i;
    }
     for (j = 1; (1 << j) <= n; j++)
    {
        for (i = 0; i + (1 << j) - 1 <= n; i++)    
        {
            mn[i][j] = my_min(mn[i][j-1],mn[i+(1<<(j-1))][j-1]);
        }
    }
    for (i = l; i <= n; i++) q.push((info){sum[i]-sum[query(max(i-r,0),i-l)],i,max(i-r,0),i-l});
    for (i = 1; i <= k; i++)
    {
        tmp = q.top();
        q.pop();
        ans += (long long)tmp.val;
        pos = query(tmp.l,tmp.r);
        m1 = query(tmp.l,pos-1);
        m2 = query(pos+1,tmp.r);
        if (m1 != -1) q.push((info){sum[tmp.pos]-sum[m1],tmp.pos,tmp.l,pos-1});
        if (m2 != -1) q.push((info){sum[tmp.pos]-sum[m2],tmp.pos,pos+1,tmp.r});
    }
    printf("%lld
",ans);

    return 0; 
} 
原文地址:https://www.cnblogs.com/evenbao/p/9323212.html