zoukankan      html  css  js  c++  java
  • 洛谷P4559 [JSOI2018]列队(主席树)

    题面

    传送门

    题解

    首先考虑一个贪心,我们把所有的人按(a_i)排个序,那么排序后的第一个人到(k),第二个人到(k+1),...,第(i)个人到(k+i-1),易证这样一定是最优的

    然后发现这里有一个很重要的性质,(a_i)互不相同。那么就必定存在一个点(mid),在(mid)左边(包括(mid))的空格子和人一样多,右边(不包括(mid))也一样多

    那么很明显,(mid)左边的所有人都需要往右跑,(mid)右边的所有人都需要往左跑

    然后来康康答案啊……先看看(mid)左边,第一个人要跑(k-a_1),第二个人要跑(k+1-a_2),...,第(mid-k+1)个人要跑(mid-a_{mid-k+1})……

    这不就等价于(sum_{i=k}^{mid}i-sum_{a_ileq mid}a_i)嘛!

    也就是说,左边的答案就是(k)(mid)的和,减去所有标号在([l,r])区间内,且(a_ileq mid)(a_i)之和,一发主席树就搞定了。右边同理

    顺便这个(mid)也可以在主席树上二分得到

    //minamoto
    #include<bits/stdc++.h>
    #define R register
    #define ll long long
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    using namespace std;
    char buf[1<<21],*p1=buf,*p2=buf;
    inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
    int read(){
        R int res,f=1;R char ch;
        while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
        for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
        return res*f;
    }
    char sr[1<<21],z[20];int C=-1,Z=0;
    inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
    void print(R ll x){
        if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
        while(z[++Z]=x%10+48,x/=10);
        while(sr[++C]=z[Z],--Z);sr[++C]='
    ';
    }
    const int N=5e5+5,M=(N<<5);
    ll sum[M],Pre[N],ss,res;int sz[M],lc[M],rc[M],rt[N],a[N];
    int n,m,l,r,k,cnt,zz,lim=2e6;
    inline bool cmp(const int &x,const int &y){return a[x]<a[y];}
    inline ll calc(R int l,R int r){return (1ll*r*(r+1)>>1)-(1ll*(l-1)*l>>1);}
    void update(int &p,int q,int l,int r,int x){
        p=++cnt,sz[p]=sz[q]+1,sum[p]=sum[q]+x;
        if(l==r)return;int mid=(l+r)>>1;
        x<=mid?(rc[p]=rc[q],update(lc[p],lc[q],l,mid,x)):
            (lc[p]=lc[q],update(rc[p],rc[q],mid+1,r,x));
    }
    void query(int p,int q,int l,int r,int x){
        if(!p||l==r)return zz+=sz[p]-sz[q],ss+=sum[p]-sum[q],void();
        int mid=(l+r)>>1,res=mid-x+1;
        zz+sz[lc[p]]-sz[lc[q]]<=res?query(lc[p],lc[q],l,mid,x):
            (zz+=sz[lc[p]]-sz[lc[q]],ss+=sum[lc[p]]-sum[lc[q]],query(rc[p],rc[q],mid+1,r,x));
    }
    int main(){
    //	freopen("testdata.in","r",stdin);
    //	freopen("testdata.out","w",stdout);
        n=read(),m=read();
        fp(i,1,n)a[i]=read(),Pre[i]=Pre[i-1]+a[i],update(rt[i],rt[i-1],1,lim,a[i]);
        while(m--){
            l=read(),r=read(),k=read(),ss=zz=0;
            query(rt[r],rt[l-1],1,lim,k);
            res=calc(k,k+zz-1)-ss+Pre[r]-Pre[l-1]-ss-calc(k+zz,k+r-l);
            print(res);
        }
        return Ot(),0;
    }
    
  • 相关阅读:
    大屏设计-大数据综合展示可视化平台
    大数据可视化大屏设计经验,教给你!
    数据可视化表格-设计经验分享!
    大数据可视化大屏图表设计经验,教给你
    数据可视化美学形式与功能需要齐头并进
    大屏可视化解决方案
    node-sass 安装失败 win32-x64-57_binding.node
    node版本如何升级
    ES6课程---8、模板字符串
    ES6课程---7、箭头函数
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/10511487.html
Copyright © 2011-2022 走看看