poj 3667 Hotel

来源:互联网 发布:网络平台金融整顿 编辑:程序博客网 时间:2024/05/11 20:25

http://poj.org/problem?id=3667

题目大意:给定长度n的空序列和m个操作。操作分两种:

1 x:询问长度为x的最左端的空子序列,输出子序列左端点。

2 x l:清空从x开始长度为l的序列(不一定l长度里面都是非空的)。

 

比较基础的线段树实现的段修改。线段树上每个单元记录当前段中最长的空段max,左端开始最长的空段lmax,右端开始最长的空段rmax。

 

ACCODE

program pku_3667;
var max,lmax,rmax:array[1..200000] of longint;
   p:array[1..200000] of boolean;
   i,n,m,x,s,t,l,command:longint;
//============================================================================
procedure cover(be,en,now:longint);
var mid:longint;
begin
  if (s<=be) and(t>=en) then
  begin
   max[now]:=(en-be+1)*x;
   lmax[now]:=max[now];
   rmax[now]:=max[now];
   p[now]:=true; exit;
  end; mid:=(be+en) shr 1;
  if p[now] then
  begin
    max[now shl1]:=max[now] div (en-be+1)*(mid-be+1);
    lmax[now shl1]:=max[now shl 1]; rmax[now shl 1]:=max[now shl 1];
    max[now shl1+1]:=max[now] div (en-be+1)*(en-mid);
    lmax[now shl1+1]:=max[now shl 1+1]; rmax[now shl 1+1]:=max[now shl 1+1];
    p[now shl1]:=true; p[now shl 1+1]:=true; p[now]:=false;
  end;
  if s<=mid then cover(be,mid,nowshl 1);
  if t>mid then cover(mid+1,en,nowshl 1+1);
  if max[now shl 1]>max[now shl1+1] then
   max[now]:=max[now shl 1] else max[now]:=max[now shl 1+1];
  if rmax[now shl 1]+lmax[now shl1+1]>max[now] then
   max[now]:=rmax[now shl 1]+lmax[now shl 1+1];
  if lmax[now shl 1]=mid-be+1then   //不仅要更行max还有lmax,rmax。
   lmax[now]:=lmax[now shl 1]+lmax[now shl 1+1] elselmax[now]:=lmax[now shl 1];
  if rmax[now shl 1+1]=en-mid then
   rmax[now]:=rmax[now shl 1]+rmax[now shl 1+1] elsermax[now]:=rmax[now shl 1+1];
end;
//============================================================================
function find(be,en,now:longint):longint;
var mid:longint;
begin
  if en-be+1=x then exit(be);
  mid:=(be+en) shr 1;
  if p[now]then   //在询问的时候也要推标号,及时更新。
  begin
    max[now shl1]:=max[now] div (en-be+1)*(mid-be+1);
    lmax[now shl1]:=max[now shl 1]; rmax[now shl 1]:=max[now shl 1];
    max[now shl1+1]:=max[now] div (en-be+1)*(en-mid);
    lmax[now shl1+1]:=max[now shl 1+1]; rmax[now shl 1+1]:=max[now shl 1+1];
    p[now shl1]:=true; p[now shl 1+1]:=true; p[now]:=false;
  end;
  if max[now shl 1]>=x thenfind:=find(be,mid,now shl 1) else
  if rmax[now shl 1]+lmax[now shl1+1]>=x then find:=mid-rmax[now shl 1]+1 else
  find:=find(mid+1,en,now shl 1+1);
end;
//============================================================================
begin
  readln(n,m);
  max[1]:=n; p[1]:=true;
  lmax[1]:=n; rmax[1]:=n;
  for i:=1 to m do
  begin
   read(command);
    if command=1then
    begin
     readln(x);
     if max[1]>=x then
     begin
       s:=find(1,n,1); t:=s+x-1; x:=0;
       cover(1,n,1); writeln(s);
     end else writeln('0')
    endelse
    begin
     readln(s,l); t:=s+l-1; x:=1;
     cover(1,n,1);
    end;
  end;
end.

 

0 0
原创粉丝点击