zoukankan      html  css  js  c++  java
  • P2048 [NOI2010]超级钢琴(RMQ+堆+贪心)

    P2048 [NOI2010]超级钢琴

    区间和--->前缀和做差

    多次查询区间和最大--->前缀和RMQ

    每次取出最大的区间和--->堆

    于是我们设个3元组$(o,l,r)$,表示左端点为$o$,右端点在$l,r$之间(最优处为$t$)的最大区间和。

    $t$可以RMQ在$l,r$间$O(1)$查询

    所以我们事先把$n$个三元组(1<=o<=n)扔到堆里,每次把$s[t]-s[o-1]$最大的拿出来累加进答案。

    取出来后$[o,t]$就不能取了,于是我们再把$(o,l,t-1)$和$(o,t+1,r)$再扔进堆里就好辣

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #define rint register int
    using namespace std;
    inline int Min(int a,int b){return a<b?a:b;}
    void read(int &x){
        char c=getchar();x=0; bool f=1;
        while(c<'0'||c>'9') f=f&&(c!='-'),c=getchar();
        while('0'<=c&&c<='9') x=x*10+(c^48),c=getchar();
        x=f?x:-x;
    }
    #define N 500005
    int n,k,s[N],f[19][N],Log[N],a,L,R; long long ans;
    void maketb(){//RMQ:f数组存的是最大值的下标
        for(rint i=1;i<=n;++i) f[0][i]=i;
        for(rint j=1;(1<<j)<=n;++j)
            for(rint i=1;i+(1<<(j-1))<=n;++i){
                if(s[f[j-1][i]]>s[f[j-1][i+(1<<(j-1))]])
                    f[j][i]=f[j-1][i];
                else f[j][i]=f[j-1][i+(1<<(j-1))];
            }
    }
    int ask(int l,int r){
        int k=Log[r-l+1];
        if(s[f[k][l]]>s[f[k][r-(1<<k)+1]]) return f[k][l];
        else return f[k][r-(1<<k)+1];
    }
    struct data{
        int o,l,r,t;
        data(int A,int B,int C):
            o(A),l(B),r(C),t(ask(B,C))
        {}
        bool operator < (const data &tmp) const{
            return s[t]-s[o-1]<s[tmp.t]-s[tmp.o-1];
        }
    };priority_queue <data> h;
    int main(){
        read(n);read(k);read(L);read(R); Log[0]=-1;
        for(rint i=1;i<=n;++i) read(a),s[i]=s[i-1]+a,Log[i]=Log[i>>1]+1;
        maketb();
        for(rint i=1;i+L-1<=n;++i) h.push(data(i,i+L-1,Min(i+R-1,n)));
        while(k--){
            data x=h.top(); h.pop();
            ans+=s[x.t]-s[x.o-1];
            if(x.l<x.t) h.push(data(x.o,x.l,x.t-1));
            if(x.r>x.t) h.push(data(x.o,x.t+1,x.r));
        }printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    【计算机网络】物理层
    【计算机网络】计算机网络体系结构
    【计算机组成原理】存储器
    【计算机组成原理】定点数运算
    【计算机组成原理】校验码
    【计算机组成原理】数据的表示和运算
    【计算机组成原理】计算机系统概述
    【计算机组成原理】输入输出系统(一)
    【计算机组成原理】总线
    【计算机组成原理】中央处理器-硬布线控制器 流水线
  • 原文地址:https://www.cnblogs.com/kafuuchino/p/10675992.html
Copyright © 2011-2022 走看看