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; }