zoukankan      html  css  js  c++  java
  • 超级钢琴 2010年NOI

    /*
    自己yy的奇葩做法居然A了23333
    不过空间好像很大 时间好像略慢.....
    毕竟不是正解
    前缀维护sum值 枚举区间起点
    然后终点的坐标可以确定在一个范围
    可持久化线段树查询区间第1大
    然后放到堆里 注意每个从堆里取出来再把这个区间第2大的放进去 
    这里k可能减成负的 注意特判 开始wa了
    还有开longlong 
    */
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    #include<algorithm>
    #define pa pair<int,int>
    #define mk make_pair
    #define maxn 500010
    using namespace std;
    int n,m,l,r,k,x,root[maxn],a[maxn],s[maxn],cnt[maxn],tot;
    long long ans;
    struct node{
        int sum,lc,rc;
    }t[maxn*20*4];
    priority_queue<pa>q;
    int init(){
        int x=0,f=1;char s=getchar();
        while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
        while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
        return x*f;
    }
    int Build(int S,int L,int R){
        ++tot;t[tot].sum=S;
        t[tot].lc=L;t[tot].rc=R;
        return tot;
    }
    void Insert(int &root,int pre,int l,int r,int pos){
        root=Build(t[pre].sum+1,t[pre].lc,t[pre].rc);
        if(l==r)return;
        int mid=l+r>>1;
        if(pos<=mid)Insert(t[root].lc,t[pre].lc,l,mid,pos);
        else Insert(t[root].rc,t[pre].rc,mid+1,r,pos);
    }
    int Query(int L,int R,int l,int r,int k){
        if(l==r)return l;
        int mid=l+r>>1;
        int sum=t[t[R].lc].sum-t[t[L].lc].sum;
        if(k<=sum)return Query(t[L].lc,t[R].lc,l,mid,k);
        else return Query(t[L].rc,t[R].rc,mid+1,r,k-sum);
    }
    int main()
    {
        freopen("piano.in","r",stdin);
        //freopen("piano.out","w",stdout);
        n=init();k=init();l=init();r=init();
        for(int i=1;i<=n;i++){
            x=init();
            s[i]=s[i-1]+x;
            a[i]=s[i];
        }
        int num,pos,L,R,p,len,t;
        sort(a+1,a+1+n);
        num=unique(a+1,a+1+n)-a-1;
        for(int i=1;i<=n;i++){
            pos=lower_bound(a+1,a+1+num,s[i])-a;
            Insert(root[i],root[i-1],1,num,pos);
        }
        while(!q.empty())q.pop();
        for(int i=1;i+l-1<=n;i++){
            L=i+l-1,R=min(n,i+r-1);
            len=R-L+1;++cnt[i];t=len-cnt[i]+1;
            pos=Query(root[L-1],root[R],1,num,t);
            q.push(mk(a[pos]-s[i-1],i));
        }
        for(int i=1;i<=k;i++){
            p=q.top().second;
            ans+=q.top().first;q.pop();
            L=p+l-1,R=min(n,p+r-1);
            len=R-L+1;++cnt[p];t=len-cnt[p]+1;
            if(t<=0)continue;
            pos=Query(root[L-1],root[R],1,num,t);
            q.push(mk(a[pos]-s[p-1],p));
        }
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    IP掩码的作用
    linux shell 笔记
    ubuntu apt-get Failed to fetch Temporary failure resolving 'security.ubuntu.com'
    ubuntu 16.04 & 18.04 远程桌面使用
    取消Ubuntu开机硬盘自检
    linux shell 脚本输入参数解析
    Ubuntu 16.04 + python3 源码 安装+使用labelImg最新版
    用tinyxml2读写xml文件_C++实现
    常用工具问题及解决方案
    可视化调试工具
  • 原文地址:https://www.cnblogs.com/yanlifneg/p/5858654.html
Copyright © 2011-2022 走看看