bzoj 1828: [Usaco2010 Mar]balloc farm allocation [greedy + line segment tree]

It looks very greedy, sort according to the right endpoint, use the minimum line segment tree query to determine whether the current cow can be put in, and update the line segment tree if it can. Ans++
comes from https://www.cnblogs.com/rausen/p/ 4529245.htmlVery rigorous proof

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=100005;
int n,m,c[N],ans;
struct xds
{
    int l,r,mn,lz;
}t[N<<2];
struct qwe
{
    int l,r;
}a[N];
bool cmp(const qwe &a,const qwe &b)
{
    return a.r<b.r;
}
int read()
{
    int r=0,f=1;
    char p=getchar();
    while(p>'9'||p<'0')
    {
        if(p=='-')
            f=-1;
        p=getchar();
    }
    while(p>='0'&&p<='9')
    {
        r=r*10+p-48;
        p=getchar();
    }
    return r*f;
}
void pd(int ro)
{
    if(t[ro].lz!=0)
    {
        t[ro<<1].mn-=t[ro].lz,t[ro<<1].lz+=t[ro].lz;
        t[ro<<1|1].mn-=t[ro].lz,t[ro<<1|1].lz+=t[ro].lz;
        t[ro].lz=0;
    }
}
void build(int ro,int l,int r)
{
    t[ro].l=l,t[ro].r=r;
    if(l==r)
    {
        t[ro].mn=c[l];
        return;
    }
    int mid=(l+r)>>1;
    build(ro<<1,l,mid);
    build(ro<<1|1,mid+1,r);
    t[ro].mn=min(t[ro<<1].mn,t[ro<<1|1].mn);
}
void update(int ro,int l,int r)
{
    if(t[ro].l==l&&t[ro].r==r)
    {
        t[ro].mn--,t[ro].lz++;
        return;
    }
    pd(ro);
    int mid=(t[ro].l+t[ro].r)>>1;
    if(r<=mid)
        update(ro<<1,l,r);
    else if(l>mid)
        update(ro<<1|1,l,r);
    else
        update(ro<<1,l,mid),update(ro<<1|1,mid+1,r);
    t[ro].mn=min(t[ro<<1].mn,t[ro<<1|1].mn);
}
int ques(int ro,int l,int r)
{
    if(t[ro].l==l&&t[ro].r==r)
        return t[ro].mn;
    pd(ro);
    int mid=(t[ro].l+t[ro].r)>>1;
    if(r<=mid)
        return ques(ro<<1,l,r);
    else if(l>mid)
        return ques(ro<<1|1,l,r);
    else
        return min(ques(ro<<1,l,mid),ques(ro<<1|1,mid+1,r));
}
int main()
{
    n=read(),m=read();
    for(int i=1;i<=n;i++)
        c[i]=read();
    for(int i=1;i<=m;i++)
        a[i].l=read(),a[i].r=read();
    sort(a+1,a+1+m,cmp);
    build(1,1,n);
    for(int i=1;i<=m;i++)
        if(ques(1,a[i].l,a[i].r)>0)
            update(1,a[i].l,a[i].r),ans++;
    printf("%d\n",ans);
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325341088&siteId=291194637