【bzoj1593-预定旅馆】线段树维护连续区间
题解:
这题非常经典啊似乎。。经典模型要记住啊。。
对于每个节点维护该区间里的最大的连续区间,然后我们就可以logn递归找最前面的一段。
那就维护mx(无限制),lmx(必须从左边开始),rmx(必须从右边开始)。
代码:
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<iostream>
5 #include<ctime>
6 #include<queue>
7 #include<algorithm>
8 using namespace std;
9
10 const int N=50010;
11 int n,m,tl;
12 struct trnode{
13 int l,r,lc,rc,mx,lmx,rmx,len,lazy;
14 }t[2*N];
15
16 int minn(int x,int y){return x<y ? x:y;}
17 int maxx(int x,int y){return x>y ? x:y;}
18
19 int bt(int l,int r)
20 {
21 int x=++tl;
22 t[x].l=l;t[x].r=r;
23 t[x].lc=t[x].rc=0;
24 t[x].lazy=-1;t[x].len=r-l+1;
25 t[x].lmx=t[x].rmx=t[x].mx=t[x].len;
26 if(l<r)
27 {
28 int mid=(l+r)/2;
29 t[x].lc=bt(l,mid);
30 t[x].rc=bt(mid+1,r);
31 }
32 return x;
33 }
34
35 void pd(int x)
36 {
37 if(t[x].lazy==-1) return ;
38 int d=t[x].lazy,lc=t[x].lc,rc=t[x].rc,l=t[x].l,r=t[x].r;
39 t[x].lazy=-1;
40 if(d==0) t[x].mx=t[x].lmx=t[x].rmx=t[x].len;
41 else t[x].mx=t[x].lmx=t[x].rmx=0;
42 if(lc) t[lc].lazy=d;
43 if(rc) t[rc].lazy=d;
44 }
45
46 void upd(int x)
47 {
48 int lc=t[x].lc,rc=t[x].rc;
49 pd(x);pd(lc);pd(rc);
50 t[x].lmx=t[lc].lmx;
51 if(t[lc].lmx==t[lc].len) t[x].lmx+=t[rc].lmx;
52 t[x].rmx=t[rc].rmx;
53 if(t[rc].rmx==t[rc].len) t[x].rmx+=t[lc].rmx;
54 t[x].mx=maxx(maxx(maxx(t[x].lmx,t[x].rmx),t[lc].rmx+t[rc].lmx),maxx(t[lc].mx,t[rc].mx));//debug 一开始这里忘了取lc和rc的mx了。
55 }
56
57 void change(int x,int l,int r,int d)
58 {
59 pd(x);
60 if(t[x].l==l && t[x].r==r) {t[x].lazy=d;pd(x);return ;}
61 int lc=t[x].lc,rc=t[x].rc,mid=(t[x].l+t[x].r)/2;
62 if(r<=mid) change(lc,l,r,d);
63 else if(l>mid) change(rc,l,r,d);
64 else
65 {
66 change(lc,l,mid,d);
67 change(rc,mid+1,r,d);
68 }
69 upd(x);
70 }
71
72 int query(int x,int len)
73 {
74 pd(x);
75 int k,lc=t[x].lc,rc=t[x].rc;
76 if(t[x].mx>=len)
77 {
78 if(t[x].lmx>=len) return t[x].l;
79 if((k=query(lc,len)) > 0) return k;
80 if(t[lc].rmx+t[rc].lmx>=len) return t[lc].r-t[lc].rmx+1;
81 if((k=query(rc,len)) > 0) return k;
82 }
83 return 0;
84 }
85
86 int main()
87 {
88 // freopen("a.in","r",stdin);
89 freopen("hotel.in","r",stdin);
90 freopen("hotel.out","w",stdout);
91 scanf("%d%d",&n,&m);
92 tl=0;
93 bt(1,n);
94 for(int i=1;i<=m;i++)
95 {
96 int tmp,x,len;
97 scanf("%d",&tmp);
98 if(tmp==1)
99 {
100 scanf("%d",&len);
101 x=query(1,len);
102 printf("%d\n",x);
103 if(x>0) change(1,x,x+len-1,1);
104 }
105 else
106 {
107 scanf("%d%d",&x,&len);
108 change(1,x,x+len-1,0);
109 }
110 }
111 return 0;
112 }