• noi2017 day2t2


    设a[i]为当前方案中第 1..i 天变质的蔬菜有几个,b[i]为前i天至少能卖出几个,方案可行的条件是对任意i有a[i]<=b[i],用线段树维护b[i]-a[i]。

    从小到大枚举天数,枚举到第w天时,对所有u>=w,b[u]+=m,表示第w天从可以卖0个变为m个

    选一个蔬菜,在第w天变质,则相当于对所有u>=w,a[u]+=1,因此必须保证w在b[i]-a[i]的最右一个零点的右侧

    对每种蔬菜都贪心先取变质时间晚的,用另一颗线段树维护变质时间>=w的最大价值,每次贪心选可行的价值最大的一个更新答案

    可以构造一个等价的费用流模型,从而证明贪心的正确性

    #include<bits/stdc++.h>
    const int N=1e5+777;
    typedef long long i64;
    char ib[N*100],*ip=ib,ob[N*25],*op=ob;
    int _(){
        int x=0;
        while(*ip<48)++ip;
        while(*ip>47)x=x*10+*ip++-48;
        return x;
    }
    void pr(i64 x){
        int ss[25],sp=0;
        do ss[++sp]=x%10+48;while(x/=10);
        while(sp)*op++=ss[sp--];
        *op++=10;
    }
    int max(int a,int b){return a>b?a:b;}
    int min(int a,int b){return a<b?a:b;}
    int n,m,qp;
    i64 as[N],ans=0;
    int qs[N],md=1;
    struct item{
        int a,s,c,x;
        void R(){
            a=_(),s=_(),c=_(),x=_();
            a+=s;
        }
        void ins();
        void dec(){
            ans+=a;
            --c;
            if(s)a-=s,s=0;
        }
        int tm(){
            if(!x)return md;
            return min(md,(c+x-1)/x);
        }
        bool operator<(const item&i)const{return a>i.a;}
    }is[N];
    std::multiset<item>st[N];
    int tr[1<<18|111],mx=0;
    void up(int x){
        tr[mx+x]=st[x].size()?st[x].begin()->a:0;
        for(x=mx+x>>1;x;x>>=1)tr[x]=max(tr[x<<1],tr[x<<1^1]);
    }
    void item::ins(){
        if(c<=0)return;
        int x=tm();
        st[x].insert(*this);
        up(x);
    }
    void maxs(int&a,int b){if(a<b)a=b;}
    void mins(int&a,int b){if(a>b)a=b;}
    int _l,_a;
    struct node{
        node*lc,*rc;
        int L,R,M;
        int v,a,p;
        void add(int x){
            v+=x,a+=x;
        }
        void add(){
            if(_l<=L)return add(_a);
            dn();
            if(_l<=M)lc->add();
            rc->add();
            up();
        }
        void dn(){
            if(a){
                lc->add(a);
                rc->add(a);
                a=0;
            }
        }
        void up(){
            v=rc->v,p=rc->p;
            if(lc->v<v)v=lc->v,p=lc->p;
        }
    }ns[N*2],*np=ns,*rt;
    node*build(int L,int R){
        node*w=np++;
        w->L=L,w->R=R;
        w->p=R;
        if(L<R){
            int M=w->M=L+R>>1;
            w->lc=build(L,M);
            w->rc=build(M+1,R);
        }
        return w;
    }
    bool chk(int pos){
        int mw=0;
        for(int w=mx+pos-1;w;w>>=1)if((~w&1)&&tr[w+1]>tr[mw])mw=w+1;
        if(!mw)return 0;
        for(;mw<mx;mw<<=1,mw+=(tr[mw]<tr[mw+1]));
        mw-=mx;
        item i=*st[mw].begin();
        st[mw].erase(st[mw].begin());up(mw);
        i.dec();
        i.ins();
        _l=mw,_a=-1,rt->add();
        return 1;
    }
    int main(){
        fread(ib,1,sizeof(ib),stdin);
        n=_();m=_();qp=_();
        for(int i=0;i<n;++i)is[i].R();
        for(int i=0;i<qp;++i)maxs(md,qs[i]=_());
        rt=build(1,md);
        for(mx=1;mx<=md+10;mx<<=1);
        for(int i=0;i<n;++i)is[i].ins();
        for(int i=1;i<=md;++i){
            _l=i,_a=m,rt->add();
            while(1){
                int pos=rt->v?1:rt->p+1;
                if(pos>n||!chk(pos))break;
            }
            as[i]=ans;
        }
        for(int i=0;i<qp;++i)pr(as[qs[i]]);
        fwrite(ob,1,op-ob,stdout);
        return 0;
    }
    View Code
  • 相关阅读:
    spark学习进度9
    spark学习进度8-scrapy框架的安装与使用
    spark学习进度7-Python爬取大学排名实例
    spark学习进度6-Python爬取数据的四个简单实例
    spark学习进度5-利用开发工具IntelliJ IDEA编写Spark应用程序(Scala+Maven)
    Scala官网下载不下来问题-已解决
    spark学习进度4
    大数据学习总结07
    大数据学习总结06
    大数据学习总结05
  • 原文地址:https://www.cnblogs.com/ccz181078/p/7392451.html
Copyright © 2020-2023  润新知