zoukankan      html  css  js  c++  java
  • P2048 [NOI2010]超级钢琴 主席树+优先队列

    首先用前缀和 o1 地维护区间和

    对于每个序列尾 将将满足长度的序列的最大值放入优先队列里  然后每次弹出一个 将 该尾部的序列的这个的前驱放入优先队列   重复k次即可  

    用主席树来维护即可

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define ll long long
    #define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
    #define inf 0x3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    const int N=1e6+100;
    int T[N<<5],lson[N<<5],rson[N<<5],ncnt,t[N<<5];
    
    void upnode(int x,int l,int r,int pre,int &pos)
    {
        pos=++ncnt;
        t[pos]=t[pre]+1;lson[pos]=lson[pre];rson[pos]=rson[pre];
        if(l==r)return ;int m=(l+r)>>1;
        if(x<=m)upnode(x,l,m,lson[pre],lson[pos]);
        else upnode(x,m+1,r,rson[pre],rson[pos]);
    }
    int qk(int k,int l,int r,int pre,int pos)
    {
        int x=t[lson[pos]]-t[lson[pre]];
        if(l==r)return l;int m=(l+r)>>1;
        if(k<=x)return qk(k,l,m,lson[pre],lson[pos]);
        else return qk(k-x,m+1,r,rson[pre],rson[pos]);
    }
    struct node
    {
        int v,k,pos;
        bool operator<(const node &b)const 
        {
            return v<b.v;
        }
    };
    priority_queue<node>q;
    int a[N],L,R,k,n,s[N];
    int main()
    {   
        scanf("%d%d%d%d",&n,&k,&L,&R);
        n++;//空出一位0  方便前缀和
        rep(i,2,n)
        {
            scanf("%d",&a[i]);
            a[i]+=a[i-1];s[i]=a[i];
        }
        sort(s+1,s+1+n);
        int nn=unique(s+1,s+1+n)-s-1;
        rep(i,1,n)a[i]=lower_bound(s+1,s+1+nn,a[i])-s;
    
        rep(i,1,n)upnode(a[i],1,nn,T[i-1],T[i]);
    
        rep(i,L+1,n)
        {
            node x;x.k=1;x.pos=i;
            x.v=s[a[i]]-s[qk(1,1,nn,T[max(0,i-R-1)],T[i-L] )];
            q.push(x);
        }
        ll ans=0;
        while(k--)
        {
            node u=q.top();q.pop();
            ans+=u.v;
            if(u.k==min(R-L+1,u.pos-L))continue;
            u.k++;
            u.v=s[a[u.pos]]-s[qk(u.k,1,nn,T[max(0,u.pos-R-1)],T[max(0,u.pos-L)])];
            q.push(u);
        }
        cout<<ans;
        return 0;
    }
    View Code
  • 相关阅读:
    docker swarm使用keepalived+haproxy搭建基于percona-xtradb-cluster方案的高可用mysql集群
    docker搭建基于percona-xtradb-cluster方案的mysql集群
    flask实现基于elasticsearch的关键词搜索建议
    tcp === udp
    re 模块===正则表达式
    模块===包
    析构方法====
    python===属性--类方法
    python====接口类 抽象类===19
    python==继承===18
  • 原文地址:https://www.cnblogs.com/bxd123/p/11508551.html
Copyright © 2011-2022 走看看