题意:1 a:询问是不是有连续长度为a的空房间,有的话住进最左边
2 a b:将[a,a+b-1]的房间清空
#include <stdio.h> #define maxn 51000 int sum[4*maxn],lsum[4*maxn],rsum[4*maxn]; int vis[4*maxn]; int max(int a,int b) { if(a>b) return a; else return b; } void pushup(int o,int l,int r) { int m=(l+r)/2; lsum[o]=lsum[o*2]; rsum[o]=rsum[o*2+1]; if(lsum[o]==m-l+1) lsum[o]+=lsum[o*2+1]; if(rsum[o]==r-m) rsum[o]+=rsum[o*2]; sum[o]=max(lsum[o*2+1]+rsum[o*2],max(sum[o*2],sum[o*2+1])); } void pushdown(int o,int l,int r) { if(vis[o]!=-1) { int m=r-l+1; vis[o*2]=vis[o*2+1]=vis[o]; sum[o*2]=lsum[o*2]=rsum[o*2]=vis[o]?0:m-(m/2); sum[o*2+1]=lsum[o*2+1]=rsum[o*2+1]=vis[o]?0:(m/2); vis[o]=-1; } } void build(int l,int r,int o) { sum[o]=lsum[o]=rsum[o]=r-l+1; vis[o]=-1; if(l==r) return ; else { int m=(l+r)/2; build(l,m,o*2); build(m+1,r,o*2+1); } } void update(int ql,int qr,int flag,int l,int r,int o) { if(ql<=l&&r<=qr) { vis[o]=flag; if(flag==0) sum[o]=lsum[o]=rsum[o]=r-l+1; else if(flag==1) sum[o]=lsum[o]=rsum[o]=0; return ; } else { pushdown(o,l,r); int m=(l+r)/2; if(ql<=m) update(ql,qr,flag,l,m,o*2); if(qr>m) update(ql,qr,flag,m+1,r,o*2+1); pushup(o,l,r); } } int query(int d,int l,int r,int o) { if(l==r) return l; else { pushdown(o,l,r); int m=(l+r)/2; if(sum[o*2]>=d) return query(d,l,m,o*2); else if(rsum[o*2]+lsum[o*2+1]>=d) return m-rsum[o*2]+1; else return query(d,m+1,r,o*2+1); } } int main() { int n,m; int i,y,x,d; scanf("%d%d",&n,&m); build(1,n,1); for(i=1;i<=m;i++) { scanf("%d",&y); if(y==2) //out { scanf("%d%d",&x,&d); update(x,x+d-1,0,1,n,1); } else //in { scanf("%d",&d); if(sum[1]<d) printf("0 "); else { int ans=query(d,1,n,1); printf("%d ",ans); update(ans,ans+d-1,1,1,n,1); } } } return 0; }