noi2017 day2t2
Posted ccz181078
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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; }
以上是关于noi2017 day2t2的主要内容,如果未能解决你的问题,请参考以下文章
洛谷P1083 [NOIP2012提高组Day2T2]借教室