Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 347 Accepted Submission(s): 108
http://acm.hdu.edu.cn/showproblem.php?pid=4614
思路:很基本的线段树问题,我们可以用线段树维护每一个区间的剩余空间数量(也就是可以插画的地方),对于第一个询问,我们计算区间[a,n-1]所剩余的空间数,假设为num,若为0,则输出 “Can not put any one.”,否则若小于F,则将F设为num,接下来可以二分区间[a,mid]来确定插入的第一只花和最后一只花的位置l,r,然后将区间[l,r]全赋值为1即可,对于询问2,则计算出区间[a,b]所剩余的空间num,然后 b-a+1-num即为答案。最后将区间[a,b]赋值为1.以上,下面是代码.
#include <iostream> #include <string.h> #include <algorithm> #include <stdio.h> #define maxn 50010 #define mid ((t[p].l+t[p].r)>>1) #define ls (p<<1) #define rs (ls|1) using namespace std; struct tree { int l,r; int sum; int lazy; }t[maxn<<2]; void pushup(int p) { t[p].sum=t[ls].sum+t[rs].sum; } void pushdown(int p) { if(t[p].lazy==0) { t[ls].lazy=0; t[rs].lazy=0; t[ls].sum=0; t[rs].sum=0; t[p].lazy=-1; } else if(t[p].lazy==1) { t[ls].lazy=1; t[rs].lazy=1; t[ls].sum=t[ls].r-t[ls].l+1; t[rs].sum=t[rs].r-t[rs].l+1; t[p].lazy=-1; } } void build(int p,int l,int r) { t[p].l=l,t[p].r=r,t[p].sum=1,t[p].lazy=-1; if(l==r) return; build(ls,l,mid); build(rs,mid+1,r); pushup(p); } void change(int p,int l,int r,int val) { if(t[p].l==l&&t[p].r==r) { t[p].lazy=val; if(val) { t[p].sum=r-l+1; } else t[p].sum=0; return; } pushdown(p); 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(p); } int query(int p,int l,int r) { if(t[p].l==l&&t[p].r==r) { return t[p].sum; } pushdown(p); 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); } int main() { //freopen("dd.txt","r",stdin); int ncase; scanf("%d",&ncase); while(ncase--) { int n,m,i; scanf("%d%d",&n,&m); build(1,0,n-1); int k,a,b; for(i=1;i<=m;i++) { scanf("%d%d%d",&k,&a,&b); if(k==1) { int ttmp=query(1,a,n-1); if(ttmp==0) { printf("Can not put any one.\n"); } else { if(ttmp<b) b=ttmp; int mi=a,ma=n-1,Mid; int l,r; while(mi<=ma) { Mid=(mi+ma)>>1; if(query(1,a,Mid)>0) { l=Mid; ma=Mid-1; } else mi=Mid+1; } mi=a,ma=n-1; while(mi<=ma) { Mid=(mi+ma)>>1; if(query(1,a,Mid)>=b) { r=Mid; ma=Mid-1; } else mi=Mid+1; } change(1,l,r,0); printf("%d %d\n",l,r); } } else { printf("%d\n",b-a+1-query(1,a,b)); change(1,a,b,1); } } printf("\n"); } return 0; }