• BZOJ:4209: 西瓜王


    原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4209

    (虽然仅仅是看在名字的份上,我们还是得说这题是一道)

    绝世好题!西瓜王!西瓜王!西瓜王![wàng]

    说点正经的,一开始以为合成圣堂的时候必须相邻的,然后变成了区间内取k个数不能相邻的数的最大总价值,诶我的瓜妈妈呀,不会做啊……

    看一下CA爷blog:贪心,然后替换……

    诶,我看错题了?

    最后就是主席树维护一下区间前k大的总价值,再查一下这最大的k个里面有多少个奇数多少偶数,如果奇数数量是奇数的话(好拗口)那就再查一下在前k大的数中最小的奇数和偶数,不在前k大中最大奇数和偶数,然后替换一下就吼了啊。。。

    卡常卡不过啊T_T

    #include<cstdio>
    #include<algorithm>
    #define MN 300001
    #define ll long long
    using namespace std;
     
    char ibuf[20000004],*iptr=ibuf-1,C;
    inline int _(){
        int x=0,c=*++iptr;
        while(c<48)c=*++iptr;
        while(c>47)x=x*10+c-48,c=*++iptr;
        return x;
    }
    char obuf[5000000],*optr=obuf;
    inline void _(ll x){
        static int stk[32],stp=0;
        if (x<0) *(optr++)='-',x=-x;
        if(!x)stk[stp++]=0;
        while(x)stk[stp++]=x%10,x/=10;
        while(stp)*(optr++)=stk[--stp]+48;
        *(optr++)=10;
    }
    struct tree{int l,r,s[2],S;ll al;}t[MN*40];
    int n,m,a[MN],num=0,l,r,k,s[2],S[MN][2],ro[MN],mi,ma;
    ll mmh,c;
    inline ll min(ll a,ll b){return a<b?a:b;}
    inline ll max(ll a,ll b){return a>b?a:b;}
    void in(int &P,int x,int v){
        int l=mi,r=ma,mid,*p;p=&P;
        for (;;){
            *p=++num;t[*p]=t[x];t[*p].s[v&1]++;t[*p].S++;t[*p].al+=v;
            if (l==r) break;
            int mid=l+r>>1;
            if (v<=mid) p=&t[*p].l,x=t[x].l,r=mid;else p=&t[*p].r,x=t[x].r,l=mid+1;
        }
    }
    void ask(int p,int x,int l,int r,int k){
        while (l<r){
            if (k>=t[t[p].r].S-t[t[x].r].S) s[0]+=t[t[p].r].s[0]-t[t[x].r].s[0],s[1]+=t[t[p].r].s[1]-t[t[x].r].s[1],
            mmh+=t[t[p].r].al-t[t[x].r].al,k-=t[t[p].r].S-t[t[x].r].S,p=t[p].l,x=t[x].l,r=l+r>>1;else p=t[p].r,x=t[x].r,l=(l+r>>1)+1;
            if (k==0) return;
        }
        if (k) mmh+=1LL*k*l,s[l&1]+=k;
    }
    ll askmax(int p,int x,int k,bool bo){
        if (t[p].s[bo]-t[x].s[bo]<=k) return -1e18;
        int l=mi,r=ma;
        while (l<r)
        if (t[t[p].r].s[bo]-t[t[x].r].s[bo]>k) p=t[p].r,x=t[x].r,l=(l+r>>1)+1;else k-=t[t[p].r].s[bo]-t[t[x].r].s[bo],p=t[p].l,x=t[x].l,r=l+r>>1;
        return l;
    }
    ll askmin(int p,int x,int k,bool bo){
        if (t[p].s[bo]-t[x].s[bo]<k) return 1e18;
        int l=mi,r=ma;
        while (l<r)
        if (t[t[p].r].s[bo]-t[t[x].r].s[bo]>=k) p=t[p].r,x=t[x].r,l=(l+r>>1)+1;else k-=t[t[p].r].s[bo]-t[t[x].r].s[bo],p=t[p].l,x=t[x].l,r=l+r>>1;
        return l;
    }
    int main(){
        ibuf[fread(ibuf,1,20000000,stdin)]=0;
        register int i;
        n=_();t[0].l=t[0].r=t[0].s[0]=t[0].s[1]=t[0].al=t[0].S=0;
        for (i=1;i<=n;i++) a[i]=_(),S[i][0]=S[i-1][0],S[i][1]=S[i-1][1],S[i][a[i]&1]++,mi=min(mi,a[i]),ma=max(ma,a[i]);
        for (i=1;i<=n;i++) in(ro[i],ro[i-1],a[i]);
        m=_();
        while (m--){
            l=_();r=_();k=_();
            if ((S[r][0]-S[l-1][0]>>1)+(S[r][1]-S[l-1][1]>>1)<(k>>1)){_(-1);continue;}
            mmh=s[0]=s[1]=0;ask(ro[r],ro[l-1],mi,ma,k);
            if (s[0]&1) mmh-=min(askmin(ro[r],ro[l-1],s[1],1)-askmax(ro[r],ro[l-1],s[0],0),askmin(ro[r],ro[l-1],s[0],0)-askmax(ro[r],ro[l-1],s[1],1));
            _(mmh);
        }
        fwrite(obuf,1,optr-obuf,stdout);
        return 0;
    }
    View Code
  • 相关阅读:
    结语
    创建ejs模板的express工程
    浏览器控制台命令调试——console
    JS获取URL中参数值(QueryString)的4种方法分享
    oracle之报错:ORA-00054: 资源正忙,要求指定 NOWAIT
    javascript 获取页面的高度及滚动条的位置的代码
    javascript 页面各种高度宽度
    导出Excel之Epplus使用教程2(样式设置)
    索引 'GXHRCS.PK_A253' 或这类索引的分区处于不可用状态
    数据库操作
  • 原文地址:https://www.cnblogs.com/Enceladus/p/6680227.html
Copyright © 2020-2023  润新知