题目描述:
输入包括n,m,n表示现在一共有n个相邻的房间,m表示有m条命令。
1 a 表示现在来了一个人数为a的队伍,需要一个连续的区间能够容纳这么多人,如果能够容纳,输入最靠左边的房间的号码,否则输出0。
2 a,b 表示清空[a,a+b-1]区间内所有的房子
解题思路:
线段树结构体,定义需要记录的三个值,最大左连续、最大右连续、最大连续。
由上面的图可知,我们现在要更新两端区间,此时,合并区间的最大连续房间数只有三种情况:
1、 左区间最大连续房间数
2、 右区间最大连续房间数
3、 左区间最大右连续房间数 + 右区间最大左连续房间数
只要能够维护这些值,当中的更新和询问就好办了。
代码:
View Code1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 using namespace std; 5 const int N = 50005; 6 int mmax[N<<2],lmax[N<<2],rmax[N<<2],cover[N<<2]; 7 void PushDown(int t,int m) 8 { 9 if(cover[t]!=-1) 10 { 11 cover[t<<1]=cover[t<<1|1]=cover[t]; 12 mmax[t<<1]=lmax[t<<1]=rmax[t<<1]=cover[t]?0:m-(m>>1); 13 mmax[t<<1|1]=lmax[t<<1|1]=rmax[t<<1|1]=cover[t]?0:(m>>1); 14 cover[t]=-1; 15 } 16 } 17 void PushUp(int t,int m) 18 { 19 lmax[t]=lmax[t<<1]; 20 if(lmax[t]==(m-(m>>1)))lmax[t]+=lmax[t<<1|1]; 21 rmax[t]=rmax[t<<1|1]; 22 if(rmax[t]==(m>>1))rmax[t]+=rmax[t<<1]; 23 mmax[t]=max(mmax[t<<1],mmax[t<<1|1]); 24 mmax[t]=max(mmax[t],rmax[t<<1]+lmax[t<<1|1]); 25 } 26 void build(int t,int l,int r) 27 { 28 mmax[t]=lmax[t]=rmax[t]=r-l+1; 29 cover[t]=-1; 30 if(l==r) return ; 31 int m=(l+r)>>1; 32 build(t<<1,l,m); 33 build(t<<1|1,m+1,r); 34 } 35 int query(int t,int l,int r,int w) 36 { 37 if(l==r)return l; 38 PushDown(t,r-l+1); 39 int m=(l+r)>>1; 40 if(mmax[t<<1]>=w)return query(t<<1,l,m,w); 41 else 42 if(rmax[t<<1]+lmax[t<<1|1]>=w)return m-rmax[t<<1]+1; 43 return query(t<<1|1,m+1,r,w); 44 } 45 void update(int t,int l,int r,int L,int R,int val) 46 { 47 if(L<=l&&r<=R) 48 { 49 mmax[t]=lmax[t]=rmax[t]=val?0:r-l+1; 50 cover[t]=val; 51 return ; 52 } 53 PushDown(t,r-l+1); 54 int m=(l+r)>>1; 55 if(L<=m)update(t<<1,l,m,L,R,val); 56 if(R>m)update(t<<1|1,m+1,r,L,R,val); 57 PushUp(t,r-l+1); 58 } 59 int main() 60 { 61 int n,m,o,a,b; 62 while(scanf("%d%d",&n,&m)!=EOF) 63 { 64 build(1,1,n); 65 for(int i=0;i<m;i++) 66 { 67 scanf("%d",&o); 68 if(o==1) 69 { 70 scanf("%d",&a); 71 if(mmax[1]<a)printf("0\n"); 72 else 73 { 74 int pos=query(1,1,n,a); 75 printf("%d\n",pos); 76 update(1,1,n,pos,pos+a-1,1); 77 } 78 } 79 else 80 { 81 scanf("%d%d",&a,&b); 82 update(1,1,n,a,a+b-1,0); 83 } 84 } 85 } 86 return 0; 87 }
来源:https://www.cnblogs.com/nuoyan2010/archive/2012/10/23/2736064.html