poj 1177/USACO 5.5 Picture 线段树+离散化+扫描线

题意:给出n个矩形,若某条边的一段被某个矩形覆盖,则这一段就会消失,求剩下的边的总长度。

分析:仍然要用到扫描线,跟hdu 1255有点类似。因为要统计的边分为横的和竖的,所以就分两次统计。

其他的操作和hdu 1255的基本相同,只是统计的时候变了一些而已,具体的看代码。

代码:

{
ID: ymwbegi1
PROG: picture
LANG: PASCAL
}

var
  n,a1,i:longint;
  x1,y1,x2,y2:array[1..5000] of real;
  s,ans:real;
  t:array[1..10000,1..4] of longint;
  a:array[0..10000] of real;
  bian:array[0..10000,1..3] of real;
  b:array[0..10000] of longint;

procedure qsort1(l,r:longint);
var
  i,j:longint;
  k,w:real;
begin
  if l>=r then exit;
  i:=l;
  j:=r;
  k:=bian[(i+j) div 2,1];
  w:=b[(l+r) div 2];
  repeat
    while (bian[i,1]<k)or(bian[i,1]=k)and(b[i]>w) do inc(i);
    while (bian[j,1]>k)or(bian[j,1]=k)and(b[j]<w) do dec(j);
    if i<=j then
    begin
      bian[0]:=bian[i];bian[i]:=bian[j];bian[j]:=bian[0];
      b[0]:=b[i];b[i]:=b[j];b[j]:=b[0];
      inc(i);dec(j);
    end;
  until i>j;
  qsort1(i,r);
  qsort1(l,j);
end;

procedure qsort2(l,r:longint);
var
  i,j:longint;
  k:real;
begin
  if l>=r then exit;
  i:=l;
  j:=r;
  k:=a[(i+j) div 2];
  repeat
    while a[i]<k do inc(i);
    while a[j]>k do dec(j);
    if i<=j then
    begin
      a[0]:=a[i];a[i]:=a[j];a[j]:=a[0];
      inc(i);dec(j);
    end;
  until i>j;
  qsort2(i,r);
  qsort2(l,j);
end;

procedure hehe(d,l,r:longint);
var
  m:longint;
begin
  t[d,1]:=l;
  t[d,2]:=r;
  t[d,3]:=0;
  t[d,4]:=0;
  if r-l=1 then exit;
  m:=(l+r) div 2;
  hehe(d*2,l,m);
  hehe(d*2+1,m,r);
end;

procedure insert(d:longint;l,r:real;z:longint);
var
  m:longint;
begin
  m:=(t[d,1]+t[d,2]) div 2;
  if (a[t[d,1]]=l)and(a[t[d,2]]=r) then
  begin
    if t[d,4]=0
      then begin
             t[d,4]:=2;
             t[d,3]:=t[d,3]+z;
             if (t[d,3]=0)or(t[d,3]=z) then ans:=ans+r-l;
           end
      else if t[d,4]=1
             then begin
                    insert(d*2,l,a[m],z);
                    insert(d*2+1,a[m],r,z);
                  end
             else begin
                    t[d,3]:=t[d,3]+z;
                    if (t[d,3]=0)or(t[d,3]=z) then ans:=ans+r-l;
                  end;
    exit;
  end;
  if t[d,4]=2 then
  begin
    t[d*2,4]:=2;
    t[d*2+1,4]:=2;
    t[d*2,3]:=t[d*2,3]+t[d,3];
    t[d*2+1,3]:=t[d*2+1,3]+t[d,3];
  end;
  t[d,4]:=1;
  if r<=a[m]
    then insert(d*2,l,r,z)
    else if l>=a[m]
           then insert(d*2+1,l,r,z)
           else begin
                  insert(d*2,l,a[m],z);
                  insert(d*2+1,a[m],r,z);
                end;
end;

procedure work1;
begin
  for i:=1 to n do
  begin
    bian[i*2-1,1]:=y1[i];
    bian[i*2-1,2]:=x1[i];
    bian[i*2-1,3]:=x2[i];
    b[i*2-1]:=1;
    bian[i*2,1]:=y2[i];
    bian[i*2,2]:=x1[i];
    bian[i*2,3]:=x2[i];
    b[i*2]:=-1;
    a[i*2-1]:=x1[i];
    a[i*2]:=x2[i];
  end;
  qsort1(1,n*2);
  qsort2(1,n*2);
  a1:=n*2;
  for i:=1 to n*2-1 do
    if a[i]=a[i+1] then
    begin
      a[i]:=maxlongint div 10;
      dec(a1);
    end;
  qsort2(1,n*2);
  hehe(1,1,a1);
  i:=1;
  bian[0,1]:=-1;
  bian[n*2+1,1]:=-1;
  while i<=n*2 do
  begin
    insert(1,bian[i,2],bian[i,3],b[i]);
    while bian[i,1]=bian[i+1,1] do
    begin
      inc(i);
      insert(1,bian[i,2],bian[i,3],b[i]);
    end;
    inc(i);
  end;
end;

procedure work2;
begin
  for i:=1 to n do
  begin
    bian[i*2-1,1]:=x1[i];
    bian[i*2-1,2]:=y1[i];
    bian[i*2-1,3]:=y2[i];
    b[i*2-1]:=1;
    bian[i*2,1]:=x2[i];
    bian[i*2,2]:=y1[i];
    bian[i*2,3]:=y2[i];
    b[i*2]:=-1;
    a[i*2-1]:=y1[i];
    a[i*2]:=y2[i];
  end;
  qsort1(1,n*2);
  qsort2(1,n*2);
  a1:=n*2;
  for i:=1 to n*2-1 do
    if a[i]=a[i+1] then
    begin
      a[i]:=maxlongint div 10;
      dec(a1);
    end;
  qsort2(1,n*2);
  hehe(1,1,a1);
  i:=1;
  bian[0,1]:=-1;
  bian[n*2+1,1]:=-1;
  while i<=n*2 do
  begin
    insert(1,bian[i,2],bian[i,3],b[i]);
    while bian[i,1]=bian[i+1,1] do
    begin
      inc(i);
      insert(1,bian[i,2],bian[i,3],b[i]);
    end;
    inc(i);
  end;
end;

begin
  assign(input,'picture.in');
  assign(output,'picture.out');
  reset(input);
  rewrite(output);
  readln(n);
  for i:=1 to n do
    readln(x1[i],y1[i],x2[i],y2[i]);
  ans:=0;
  work1;
  work2;
  writeln(ans:0:0);
  close(input);
  close(output);
end.

你可能感兴趣的:(poj 1177/USACO 5.5 Picture 线段树+离散化+扫描线)