题目描述:
输入包括n,m,n表示现在一共有n个相邻的房间,m表示有m条命令。
1 a 表示现在来了一个人数为a的队伍,需要一个连续的区间能够容纳这么多人,如果能够容纳,输入最靠左边的房间的号码,否则输出0。
2 a,b 表示清空[a,a+b-1]区间内所有的房子
解题思路:
线段树结构体,定义需要记录的三个值,最大左连续、最大右连续、最大连续。

由上面的图可知,我们现在要更新两端区间,此时,合并区间的最大连续房间数只有三种情况:
1、 左区间最大连续房间数
2、 右区间最大连续房间数
3、 左区间最大右连续房间数 + 右区间最大左连续房间数
只要能够维护这些值,当中的更新和询问就好办了。
代码:
View Code
1 #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
