poj3667

来源:互联网 发布:淘宝禁售管理规范 编辑:程序博客网 时间:2024/06/06 01:14

【题意】

一共有n个空位,初始全为空,会有两种操作,一种是询问是否有r个连续的空位,若有,则将最左端有r个连续的空位的地方全部填满,若没有则不填,另一种是将从u开始的d个位置全部清空

【输入】

第一行两个数n、m(<=50000),表示n个空位,m次操作

接下来m行每行表示一次操作,

若该行第一个数字为1,接下来是一个数字,表示操作一

若该行第一个数字为2,接下来是两个数字,表示操作二

【输出】

对于每个操作一,若存在r个连续的空位,则输出最靠左的r个连续空位的起点,若不存在则输出0


线段树

每个节点记录三个值,从该节点左端往右有多少个连续的空位,从该节点右端往左有多少个连续的空位,该区间内最长连续空位长度为多少


program poj3667;var  tot,n,m,i,j,k,r,o,s,e:longint;  left,right,x,y,point:array [0..200001] of longint;function max (a,b:longint):longint;begin  if a>b then exit(a)         else exit(b);end;procedure down (now,l,r:longint);begin  if left[now]=0 then    begin      inc(tot);      left[now]:=tot;    end;  if right[now]=0 then    begin      inc(tot);      right[now]:=tot;    end;  if point[now]=r-l+1 then    begin      x[left[now]]:=(l+r) div 2 - l + 1;      y[left[now]]:=(l+r) div 2 - l + 1;      point[left[now]]:=(l+r) div 2 - l + 1;      x[right[now]]:=r-(l+r) div 2;      y[right[now]]:=r-(l+r) div 2;      point[right[now]]:=r-(l+r) div 2;    end;  if point[now]=0 then    begin      x[left[now]]:=0;      y[left[now]]:=0;      point[left[now]]:=0;      x[right[now]]:=0;      y[right[now]]:=0;      point[right[now]]:=0;    end;end;procedure fill (s,e,p,l,r,now:longint);var  mid:longint;begin  if (s=l)and(e=r) then    begin      if p=0 then        begin          x[now]:=r-l+1;          y[now]:=r-l+1;          point[now]:=r-l+1;        end             else        begin          x[now]:=0;          y[now]:=0;          point[now]:=0;        end;      exit;    end;  mid:=(l+r) div 2;  down(now,l,r);  if e<=mid then fill(s,e,p,l,mid,left[now])            else  if s>=mid+1 then fill(s,e,p,mid+1,r,right[now])              else    begin      fill(s,mid,p,l,mid,left[now]);      fill(mid+1,e,p,mid+1,r,right[now]);    end;  if x[left[now]]=mid-l+1 then x[now]:=x[left[now]]+x[right[now]]                          else x[now]:=x[left[now]];  if y[right[now]]=r-mid then y[now]:=y[right[now]]+y[left[now]]                         else y[now]:=y[right[now]];  point[now]:=max(y[left[now]]+x[right[now]],max(point[left[now]],point[right[now]]));end;function find (p,l,r,now:longint):longint;begin  if (p=point[now])and(r-l+1=point[now]) then exit(l);  down(now,l,r);  if point[left[now]]>=p then exit(find(p,l,(l+r) div 2,left[now]))                         else  if (y[left[now]]<>0)and(y[left[now]]+x[right[now]]>=p) then exit((l+r) div 2 + 1 - y[left[now]])                                                         else exit(find(p,(l+r) div 2 + 1,r,right[now]));end;begin  read(n,m);  tot:=0;  x[0]:=n;  y[0]:=n;  point[0]:=n;  for i:=1 to m do    begin      read(o);      if o=1 then        begin          read(r);          if point[0]<r then            writeln(0)                        else            begin              k:=find(r,1,n,0);              writeln(k);              fill(k,k+r-1,1,1,n,0);            end;        end             else        begin          read(s,e);          e:=s+e-1;          fill(s,e,0,1,n,0);        end;    end;end.


原创粉丝点击