zoukankan      html  css  js  c++  java
  • 【BZOJ】2006: [NOI2010]超级钢琴(前缀和+RMQ+堆)

    题目

    传送门:QWQ

    分析

    又不会做。。。。。。。

    显然很好想到前缀和处理一下。

    然后考虑最大化结果,直接上st表。

    问题来了,然后呢?

    怎么做$ length in [l,r]  $ 呢? 

    是设一个五元组 (i,l,r,val,pos) 。

    i是左端点,l,r是右端点范围,val是 i 到 pos的和, pos是 右端点位置。

     然后对于  l,r   二分,扔进优先队列处理 。取出前 k 大,累加一下就是答案。

    完了。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=500005;
    int n,posi[maxn][23];
    int sum[maxn],Log2[maxn];
    struct Node{
        int i,l,r,val,pos;
        bool operator < (const Node& a) const{ return val<a.val;}
    };
    
    inline int Max(int x,int y) {return sum[x]>sum[y]? x:y;}
    void ST(){
        Log2[0]=-1;
        for(int i=1;i<=n;i++)
            if((i&(i-1))==0) Log2[i]=Log2[i-1]+1; else Log2[i]=Log2[i-1];
        for(int i=1;i<=n;i++) posi[i][0]=i;
    
        for(int j=1;(1<<j)<=n;j++)
            for(int i=1;i+(1<<j)<=n+1;i++){
                posi[i][j]=Max(posi[i][j-1],posi[i+(1<<(j-1))][j-1]);
            }
    }
    inline int RMQ(int l,int r){
        int tmp=Log2[r-l+1];
        return Max(posi[l][tmp],posi[r-(1<<tmp)+1][tmp]);
    }
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    priority_queue<Node> que;
    int main()
    {
        int k,L,R;
        scanf("%d%d%d%d",&n,&k,&L,&R);
        for(int i=1;i<=n;i++){
            sum[i]=sum[i-1]+read();
        }
        ST();
        for(int i=1;i<=n+1-L;i++){
            int pos=RMQ(i+L-1,min(n,i+R-1));
    //        printf("---------- %d %d %d
    ",i+L-1,min(n,i+R-1),pos);
            que.push((Node){i,i+L-1,min(n,i+R-1),sum[pos]-sum[i-1],pos});
        }
        ll ans=0;
        while(k){
            Node x=que.top();que.pop();
    //        printf("##########  %d %d %d
    ",x.i,x.pos,x.val);
            k--; ans+=(ll)x.val;
            Node ls=x,rs=x;
            ls.r=x.pos-1; rs.l=x.pos+1;
            if(ls.r>=ls.l) {
                ls.pos=RMQ(ls.l,ls.r); ls.val=sum[ls.pos]-sum[ls.i-1]; que.push(ls);
            }
            if(rs.r>=rs.l) {
                rs.pos=RMQ(rs.l,rs.r); rs.val=sum[rs.pos]-sum[rs.i-1]; que.push(rs);
            }
        }
    //    puts("-----------debug------------");
    //    for(int i=1;i<=n;i++)    printf("%d ",Log2[i]);
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    Python 模块 itertools
    Python 字符串的encode与decode
    python 模块 hashlib(提供多个不同的加密算法)
    暴力尝试安卓gesture.key
    hdu 1300 Pearls(DP)
    hdu 1232 畅通工程(并查集)
    hdu 1856 More is better(并查集)
    hdu 1198 Farm Irrigation(并查集)
    hdu 3635 Dragon Balls(并查集)
    hdu 3038 How Many Answers Are Wrong(并查集)
  • 原文地址:https://www.cnblogs.com/noblex/p/9147570.html
Copyright © 2011-2022 走看看