[BZOJ 2006] [NOI 2010] super piano (Table greedy + ST + stack)

[BZOJ 2006] [NOI 2010] super piano (Table greedy + ST + stack)

Face questions

Given a sequence of length n, k is selected from the interval length between the L and R, equal to the value of a section of the inner section and all the elements, so that the k value and the maximum interval. Section may intersect or contain, but a range can only be selected once.

\(n,k,L,R \leq 5 \times 10^5\)

analysis

And transforming into a first section and a prefix. Enumerated left endpoint \ (I \) , the right end of the range is \ ([+ L-I. 1, \ min (I-R & lt +. 1, n-)] \) . In this inside find a range of prefixes and maximum position p, the answer is \ (SUM [the p-] -sum [i-1] \) . static maintenance intervals can be done with the maximum position ST table.

But we ask k largest interval, only to find each point corresponds to the maximum left out of answers, may not be the k. For each point of violence left enumerate all sections, all of the value added to the heap, and finally removed the k obviously will timeout.

We maintain a stack (STL implemented on a priority queue), the stack inside each element is a triple \ ((I, L, R & lt) \) . Left point representing the interval \ (I \) , the right end point in ([l, r] \) \ within the time can take the maximum Let \ (f_m (l, r) \) of \ ([L, R] \ ) position of the maximum in, then we follow the \ ( sum [f_m (l, r) ] - sum [i] \) to maintain a maximum heap. The initial \ ((i, i + L -1, min (i + R-1, n)) \) is inserted into the heap. Each taking top of the stack \ ((i, l, r ), \) the accumulated value of the top of the stack. Order \ (f_m (L, R & lt) = P \) , a large value that corresponds to the right end of the section should be in the \ ([l, p-1 ] \) or \ ([p + 1, r ] \) inside. Thus the pop top of the stack, inserting \ ((I, L,. 1-P), (I, P +. 1, R & lt) \) . K times to do so, you can find the answer.

ST table query is \ (O (1) \) , so the total time complexity is \ (O ((n + k ) \ log n) \)

Code

#include<iostream>
#include<cstdio>
#include<cstring> 
#include<queue> 
#define maxn 500000 
#define maxlogn 25
using namespace std;
typedef long long ll;
int n,k,L,R;
struct sparse_table{
    int log2[maxn+5];
    int st[maxn+5][maxlogn+5];
    void ini(ll *a,int n){
        log2[0]=-1;
        for(int i=1;i<=n;i++) log2[i]=log2[i>>1]+1;
        for(int i=1;i<=n;i++) st[i][0]=i;
        for(int j=1;j<=log2[n]+1;j++){
            for(int i=1;i+(1<<(j-1))<=n;i++){
                if(a[st[i][j-1]]>a[st[i+(1<<(j-1))][j-1]]) st[i][j]=st[i][j-1];
                else st[i][j]=st[i+(1<<(j-1))][j-1];
            } 
        }
    }
    int query(ll *a,int l,int r){
        int k=log2[r-l+1];
        if(a[st[l][k]]>a[st[r-(1<<k)+1][k]]) return st[l][k];
        else return st[r-(1<<k)+1][k];
    }
}T;

int a[maxn+5];
ll sum[maxn+5];
struct node{
    int l;
    int r;
    int i;
    inline ll val(){
        return sum[T.query(sum,l,r)]-sum[i-1];
    }
    node(){
        
    } 
    node(int _i,int _l,int _r){
        i=_i;
        l=_l;
        r=_r;
    } 
    friend bool operator < (node p,node q){
        return p.val()<q.val();
    } 
};
priority_queue<node>q; 
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];
    }
    T.ini(sum,n);
    for(int i=1;i+L-1<=n;i++){
        q.push(node(i,i+L-1,min(i+R-1,n)));
    }
    ll ans=0;
    for(int i=1;i<=k;i++){
        node now=q.top();
        q.pop(); 
        ans+=now.val();
        int p=T.query(sum,now.l,now.r);
        if(p>now.l) q.push(node(now.i,now.l,p-1));
        if(p<now.r) q.push(node(now.i,p+1,now.r)); 
    }
    printf("%lld\n",ans); 
}

Guess you like

Origin www.cnblogs.com/birchtree/p/11516960.html