洛谷P2894[USACO08FEB]酒店Hotel(线段树)

问题描述

奶牛们最近的旅游计划,是到苏必利尔湖畔,享受那里的湖光山色,以及明媚的阳光。作为整个旅游的策划者和负责人,贝茜选择在湖边的一家著名的旅馆住宿。这个巨大的旅馆一共有N (1 <= N <= 50,000)间客房,它们在同一层楼中顺次一字排开,在任何一个房间里,只需要拉开窗帘,就能见到波光粼粼的湖面。 贝茜一行,以及其他慕名而来的旅游者,都是一批批地来到旅馆的服务台,希望能订到D_i (1 <= D_i <= N)间连续的房间。服务台的接待工作也很简单:如果存在r满足编号为r..r+D_i-1的房间均空着,他就将这一批顾客安排到这些房间入住;如果没有满足条件的r,他会道歉说没有足够的空房间,请顾客们另找一家宾馆。如果有多个满足条件的r,服务员会选择其中最小的一个。 旅馆中的退房服务也是批量进行的。每一个退房请求由2个数字X_iD_i 描述,表示编号为X_i..X_i+D_i-1 (1 <= X_i <= N-D_i+1)房间中的客人全部离开。退房前,请求退掉的房间中的一些,甚至是所有,可能本来就无人入住。 而你的工作,就是写一个程序,帮服务员为旅客安排房间。你的程序一共需要处理M (1 <= M < 50,000)个按输入次序到来的住店或退房的请求。第一个请求到来前,旅店中所有房间都是空闲的。

 

输入输出格式

输入格式:

 

 

  • Line 1: Two space-separated integers: N and M

  • Lines 2..M+1: Line i+1 contains request expressed as one of two possible formats: (a) Two space separated integers representing a check-in request: 1 and Di (b) Three space-separated integers representing a check-out: 2, Xi, and Di

 

 

输出格式:

 

 

  • Lines 1.....: For each check-in request, output a single line with a single integer r, the first room in the contiguous sequence of rooms to be occupied. If the request cannot be satisfied, output 0.

 

 

 

输入输出样例

 

输入样例#1:
10 6
1 3
1 3
1 3
1 3
2 5 5
1 6
输出样例#1:
1
4
7
0
5



本题可用线段树维护区间最长连续0的长度,同时记录区间左起最长连续0长度和右起最长连续0长度就可实现区间合并。
 1 program rrr(input,output);
 2 type
 3   treetype=record
 4      l,r,lmax,rmax,max,c:longint;
 5   end;
 6 var
 7   a:array[0..200020]of treetype;
 8   n,m,i,opt,x,y:longint;
 9 function max(a,b:longint):longint;
10 begin
11    if a>b then exit(a) else exit(b);
12 end;
13 procedure build(k,l,r:longint);
14 var
15   mid,t:longint;
16 begin
17    t:=r-l+1;
18    a[k].l:=l;a[k].r:=r;a[k].max:=t;a[k].lmax:=t;a[k].rmax:=t;a[k].c:=-1;
19    if l=r then exit;
20    mid:=(l+r)>>1;
21    build(k+k,l,mid);
22    build(k+k+1,mid+1,r);
23 end;
24 procedure pushdown(k:longint);
25 var
26   i,t:longint;
27 begin
28    if a[k].c=-1 then exit;
29    if a[k].l=a[k].r then begin a[k].c:=-1;exit; end;
30    i:=k+k;
31    if a[k].c=0 then
32       begin
33          t:=a[i].r-a[i].l+1;
34          a[i].lmax:=t;a[i].rmax:=t;a[i].max:=t;a[i].c:=0;
35          t:=a[i+1].r-a[i+1].l+1;
36          a[i+1].lmax:=t;a[i+1].rmax:=t;a[i+1].max:=t;a[i+1].c:=0;
37        end
38    else
39       begin
40          a[i].lmax:=0;a[i].rmax:=0;a[i].max:=0;a[i].c:=1;
41          a[i+1].lmax:=0;a[i+1].rmax:=0;a[i+1].max:=0;a[i+1].c:=1;
42       end;
43    a[k].c:=-1;
44 end;
45 function ask(k:longint):longint;
46 var
47   i:longint;
48 begin
49    pushdown(k);
50    i:=k+k;
51    if a[i].max>=x then exit(ask(i))
52    else if a[i].rmax+a[i+1].lmax>=x then exit(a[i].r-a[i].rmax+1)
53    else exit(ask(i+1));
54 end;
55 procedure change1(k,x,y:longint);
56 var
57   mid,i:longint;
58 begin
59    pushdown(k);
60    if (x<=a[k].l) and (a[k].r<=y) then
61       begin a[k].lmax:=0;a[k].rmax:=0;a[k].max:=0;a[k].c:=1;exit; end;
62    mid:=(a[k].l+a[k].r)>>1;i:=k+k;
63    if x<=mid then change1(i,x,y);
64    if mid<y then change1(i+1,x,y);
65    if a[i].lmax=a[i].r-a[i].l+1 then a[k].lmax:=a[i].lmax+a[i+1].lmax else a[k].lmax:=a[i].lmax;
66    if a[i+1].rmax=a[i+1].r-a[i+1].l+1 then a[k].rmax:=a[i].rmax+a[i+1].rmax else a[k].rmax:=a[i+1].rmax;
67    a[k].max:=max(max(a[i].max,a[i+1].max),a[i].rmax+a[i+1].lmax);
68 end;
69 procedure change0(k,x,y:longint);
70 var
71   mid,t,i:longint;
72 begin
73    pushdown(k);
74    if (x<=a[k].l) and (a[k].r<=y) then
75       begin t:=a[k].r-a[k].l+1;a[k].lmax:=t;a[k].rmax:=t;a[k].max:=t;a[k].c:=0;exit; end;
76    mid:=(a[k].l+a[k].r)>>1;i:=k+k;
77    if x<=mid then change0(i,x,y);
78    if mid<y then change0(i+1,x,y);
79    if a[i].lmax=a[i].r-a[i].l+1 then a[k].lmax:=a[i].lmax+a[i+1].lmax else a[k].lmax:=a[i].lmax;
80    if a[i+1].rmax=a[i+1].r-a[i+1].l+1 then a[k].rmax:=a[i].rmax+a[i+1].rmax else a[k].rmax:=a[i+1].rmax;
81    a[k].max:=max(max(a[i].max,a[i+1].max),a[i].rmax+a[i+1].lmax);
82 end;
83 begin
84    assign(input,'r.in');assign(output,'r.out');reset(input);rewrite(output);
85    readln(n,m);
86    build(1,1,n);
87    for i:=1 to m do
88       begin
89          read(opt);
90          if opt=1 then
91             begin
92                readln(x);
93                if a[1].max<x then writeln(0)
94                else begin y:=ask(1);writeln(y);change1(1,y,y+x-1); end;
95             end
96          else begin readln(x,y);change0(1,x,x+y-1); end;
97       end;
98    close(input);close(output);
99 end.

 

 

 

posted @ 2017-03-03 22:29  Klaier  阅读(245)  评论(0编辑  收藏  举报