http://acm.hdu.edu.cn/showproblem.php?pid=4614

线段树 , 中间有二分操作

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define ls (rt<<1)
#define rs (rt<<1|1)
#define mid ((t[rt].l+t[rt].r)>>1)
const int maxn = 50050;
struct node {
    int l , r;
    int sum;
    int lazy;
}t[maxn<<2];
void pushup(int rt) {
    t[rt].sum = t[ls].sum + t[rs].sum;
}
void pushdown(int rt) {
    if(t[rt].lazy == 0) {
        t[rt].lazy = -1;
        t[ls].lazy = t[rs].lazy = 0;
        t[ls].sum = t[rs].sum = 0;
    }
    if(t[rt].lazy == 1) {
        t[rt].lazy = -1;
        t[ls].lazy = t[rs].lazy = 1;
        t[ls].sum = t[ls].r - t[ls].l + 1;
        t[rs].sum = t[rs].r - t[rs].l + 1;
    }
}
void build(int rt,int l,int r) {
    t[rt].sum = 1;
    t[rt].l = l;
    t[rt].r = r;
    t[rt].lazy = -1;
    if(l == r) return;
    build(ls,l,mid);
    build(rs,mid+1,r);
    pushup(rt);
}
int query(int rt,int l,int r) {
    if(t[rt].l == l && t[rt].r == r) return t[rt].sum;
    pushdown(rt);
    if(l > mid) return query(rs,l,r);
    else if(r <= mid) return query(ls,l,r);
    else return query(ls,l,mid) + query(rs,mid+1,r);
}
void change(int rt,int l,int r,int val) {
    if(t[rt].l == l && t[rt].r == r) {
        t[rt].lazy = val;
        t[rt].sum = val * (r - l + 1);
        return;
    }
    pushdown(rt);
    if(l > mid) change(rs , l , r , val);
    else if(r <= mid) change(ls , l , r , val);
    else change(ls , l , mid , val) , change(rs , mid+1 , r, val);
    pushup(rt);
}
int T , n , m , k , a , b , s , e , l , r;
int main() {
    scanf("%d" , &T);
    while(T--) {
        scanf("%d%d",&n,&m);
        build(1 , 0 , n-1);
        while(m--) {
            scanf("%d%d%d",&k,&a,&b);
            if(k == 1) {
                int sum = query(1 , a , n-1);
                if(!sum) puts("Can not put any one.");
                else {
                    if(sum < b) b = sum;
                    l = a , r = n - 1;
                    while(l <= r) {
                        int mm = (l + r) >> 1;
                        if(query(1 , a , mm) >= 1) {
                            s = mm;
                            r = mm - 1;
                        }
                        else l = mm + 1;
                    }
                    l = a , r = n - 1;
                    while(l <= r) {
                        int mm = (l + r) >> 1;
                        if(query(1 , a , mm) >= b) {
                            e = mm;
                            r = mm - 1;
                        }
                        else l = mm + 1;
                    }
                    change(1 , s , e , 0);
                    printf("%d %d\n" , s ,e);
                }
            }
            else {
                printf("%d\n" , b-a+1-query(1,a,b));
                change(1 , a , b , 1);
            }
        }
        puts("");
    }
    return 0;
}

  

 posted on 2013-08-02 17:16  tobec  阅读(186)  评论(0编辑  收藏  举报