• BZOJ 1828: [Usaco2010 Mar]balloc 农场分配


    Description

    Input

    第1行:两个用空格隔开的整数:N和M * 第2行到N+1行:第i+1行表示一个整数C_i * 第N+2到N+M+1行: 第i+N+1行表示2个整数 A_i和B_i

    Output

    * 第一行: 一个整数表示最多能够被满足的要求数

    题解:

    将请求按右端点排序,然后依次添加,用线段树判断是否能添加,不能的放弃。统计个数即可。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    //by zrt
    //problem:
    using namespace std;
    int minn[100005*4];
    int mark[100005*4];
    int c[100005];
    void pd(int o){
        if(mark[o]){
            minn[o<<1]-=mark[o];
            minn[o<<1|1]-=mark[o];
            mark[o<<1]+=mark[o];
            mark[o<<1|1]+=mark[o];
            mark[o]=0;
        }
    }
    void insert(int o,int l,int r,int L,int R){
        if(l==L&&r==R){
            mark[o]+=1;
            minn[o]-=1;
            return;
        }else{
            pd(o);
            int m=(L+R)>>1;
            if(r<=m) insert(o<<1,l,r,L,m);
            else if(l>m) insert(o<<1|1,l,r,m+1,R);
            else insert(o<<1,l,m,L,m),insert(o<<1|1,m+1,r,m+1,R);
            minn[o]=min(minn[o<<1],minn[o<<1|1]);
        }
    }
    void build(int o,int l,int r){
        if(l==r){
            minn[o]=c[l];
        }else{
            int m=(l+r)>>1;
            build(o<<1,l,m);
            build(o<<1|1,m+1,r);
            minn[o]=min(minn[o<<1],minn[o<<1|1]);
        }
    }
    bool ok;
    void ask(int o,int l,int r,int L,int R){
        if(l==L&&r==R)  ok&=(minn[o]>0);
        else{
            pd(o);
            int m=(L+R)>>1;
            if(r<=m) ask(o<<1,l,r,L,m);
            else if(l>m) ask(o<<1|1,l,r,m+1,R);
            else ask(o<<1,l,m,L,m),ask(o<<1|1,m+1,r,m+1,R);
        }
    }
    struct node{
        int a,b;
    }q[100005];
    bool cmp(node a,node b){
        return a.b<b.b;
    }
    int main(){
        #ifdef LOCAL
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
        #endif
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%d",&c[i]);
        }
        for(int i=0;i<m;i++){
            scanf("%d%d",&q[i].a,&q[i].b);
        }
        sort(q,q+m,cmp);
        int ans=0;
        build(1,1,n);
        for(int i=0;i<m;i++){
            ok=1;ask(1,q[i].a,q[i].b,1,n);
            if(ok){
                ans++;
                insert(1,q[i].a,q[i].b,1,n);
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    Linux新手入门:通过chmod改变文件权限
    Android Activity 以及 Application 生命周期
    java 并发库之 Executors
    java Netty tcp通讯
    Android App 切换语言
    java svg转png
    高效的数独算法-位运算
    Android 高效的`InjectView – ButterKnife`
    Android 监听文件夹
    Android 更新UI
  • 原文地址:https://www.cnblogs.com/zrts/p/bzoj1828.html
Copyright © 2020-2023  润新知