BZOJ2802: [Poi2012]Warehouse Store

来源:互联网 发布:淘宝旺旺手机版卖家版 编辑:程序博客网 时间:2024/05/21 06:28

很经典的贪心,有两种做法
1:我的做法,按需求从小到大排序,写一棵线段树,对于每个判这一天是否能取,易证这样取一定是最优的
2:经典做法?直接按天数处理,维护一个大根堆,如果当前这一天不能满足顾客要求,若大根堆堆顶比当前要求大,就把堆顶pop出,把这一天的放进去

code:

#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long long#define lowbit(x) x&(-x)using namespace std;void read(int &x){    char c;    while(!((c=getchar())>='0'&&c<='9'));    x=c-'0';    while((c=getchar())>='0'&&c<='9') x=(x<<3)+(x<<1)+c-'0';}const int maxn = 260000;struct node{    int x,i;    node(){}    node(int _x,int _i){x=_x;i=_i;}}a[maxn]; int n;bool cmp(node x,node y) {return x.x<y.x;}ll v[maxn];struct tree{    ll c,flag;}tr[maxn<<2];void pushup(int x){    int lc=x<<1,rc=lc|1;    tr[x].c=min(tr[lc].c,tr[rc].c);}void pushdown(int x){    if(!tr[x].flag) return ;    int lc=x<<1,rc=lc|1;    tr[lc].flag+=tr[x].flag;    tr[lc].c-=tr[x].flag;    tr[rc].flag+=tr[x].flag;    tr[rc].c-=tr[x].flag;    tr[x].flag=0;}void build_tree(int x,int l,int r){    if(l==r){ tr[x].c=v[l]; return ; }    int mid=(l+r)>>1,lc=x<<1,rc=lc|1;    build_tree(lc,l,mid); build_tree(rc,mid+1,r);    pushup(x);}void change(int x,int l,int r,int lx,int rx,ll c){    if(lx<=l&&r<=rx) { tr[x].c-=c; tr[x].flag+=c; return ; }    int mid=(l+r)>>1,lc=x<<1,rc=lc|1;    pushdown(x);    if(rx<=mid) change(lc,l,mid,lx,rx,c);    else if(lx>mid) change(rc,mid+1,r,lx,rx,c);    else change(lc,l,mid,lx,mid,c),change(rc,mid+1,r,mid+1,rx,c);    pushup(x);}ll query(int x,int l,int r,int lx,int rx){    if(lx<=l&&r<=rx) return tr[x].c;    pushdown(x);    int mid=(l+r)>>1,lc=x<<1,rc=lc|1;    if(rx<=mid) return query(lc,l,mid,lx,rx);    else if(lx>mid) return query(rc,mid+1,r,lx,rx);    else return min(query(lc,l,mid,lx,mid),query(rc,mid+1,r,mid+1,rx));}int ans[maxn];int main(){    read(n);    for(int i=1;i<=n;i++)    {        int x; read(x);        v[i]=v[i-1]+x;    }    build_tree(1,1,n);    for(int i=1;i<=n;i++)    {        int x; read(x);        a[i]=node(x,i);    }    sort(a+1,a+n+1,cmp);    int an=0;    for(int i=1;i<=n;i++)    {        ll k=query(1,1,n,a[i].i,n);        if(k>=a[i].x) ans[++an]=a[i].i,change(1,1,n,a[i].i,n,a[i].x);    }    sort(ans+1,ans+an+1);    printf("%d\n",an);    for(int i=1;i<an;i++)    {        printf("%d ",ans[i]);    }    printf("%d\n",ans[an]);    return 0;}
0 0
原创粉丝点击