Stop the Hollyweb! No DRM in HTML5.

[poj2528]求最后未完全被其它线段覆盖的线段个数

大意:给出N<=10000个线段,每个数l,r<=10000000,求最后未被完全覆盖的线段条数。

解答:先离散化,再线段树,每次记录一下每个区间被那一个覆盖,最后扫一遍即可。

program poj2528;

Type
 re=record
  l,r,cover:longint;
 end;
 
Var
 a:array[0..20000] of re;
 z:array[0..40000] of longint;
 n,o,all,i,top:longint;
 f:array[0..180000] of re;
 t:array[0..20000] of boolean;
 ans:longint;
 
Function max(a,b:longint):longint;
  begin
  if a>b then exit(a) else exit(b);
end;

Function min(a,b:longint):longint;
  begin
  if a<b then exit(a) else exit(b);
end;

Procedure lsh(var a:array of longint;k:longint);
Type
 rec=record
   pos:longint;
   num:longint;
 end;
 
Var
 b:array[0..100000] of rec;
 i,now,last:longint;

Procedure qsort(var b:array of rec;l,r:longint);
var
 i,j:longint;
 x,y:rec;
  begin
  i:=l;j:=r;x:=b[random(r-l+1)+l];
    repeat
    while b[i].num<x.num do inc(i);
    while b[j].num>x.num do dec(j);
    if i<=j then
      begin
      y:=b[i];
      b[i]:=b[j];
      b[j]:=y;
      inc(i);
      dec(j);
    end;
  until i>j;
  if l<j then qsort(b,l,j);
  if i<r then qsort(b,i,r);
end;

  begin
  for i:=1 to k do
    with b[i] do
      begin
      num:=a[i];
      pos:=i;
    end;
  qsort(b,1,k);
  now:=1;
  a[b[1].pos]:=1;
  last:=1;
  for i:=2 to k do
    begin
    if b[i-1].num<>b[i].num then
      begin
      last:=i;
      inc(now);
    end;
    a[b[i].pos]:=now;
  end;
end;

Procedure build(p:longint);
  begin
	if f[p].l=f[p].r then exit;
	f[p*2].l:=f[p].l;
	f[p*2].r:=(f[p].l+f[p].r) div 2;
	f[p*2+1].l:=(f[p].l+f[p].r) div 2+1;
	f[p*2+1].r:=f[p].r;
	build(p*2);
	build(p*2+1);
end;

Procedure pushdata(P:longint);
  begin
	if f[p].cover<>0 then
	  begin
		f[p*2].cover:=f[p].cover;
		f[p*2+1].cover:=f[p].cover;
		f[p].cover:=0;
	end;
end;

Procedure insert(p,pl,pr,v:longint);
var
 mid:longint;
  begin
//	writeln('#',p,' ',pl,' ',pr,' ',v,' ',f[p].l,' ',f[p].r);
	if (f[p].l=pl) and (f[p].r=pr) then
	  begin
		f[p].cover:=v;
		exit;
	end;
	pushdata(p);
	mid:=(f[p].l+f[p].r) div 2;
	if pl<=mid then insert(p*2,pl,min(mid,pr),v);
	if pr>mid then insert(p*2+1,max(mid+1,pl),pr,v);
end;

Procedure visit(P:longint);
  begin
//	writeln(p,' ',f[p].l,' ',f[p].r,' ',f[p].cover);
	if f[p].cover<>0 then
	  begin
		t[f[p].cover]:=true;
		exit;
	end;
	if f[p].l=f[p].r then exit;
	visit(p*2);
	visit(p*2+1);
end;
	
  begin
	readln(o);
	for all:=1 to o do begin
	readln(n);
	for i:=1 to n do
	  begin
		readln(a[i].l,a[i].r);
		z[i*2-1]:=a[i].l;
		z[i*2]:=a[i].r;
	end;
	lsh(z,n*2);
	for i:=1 to n*2 do
	  if i mod 2=1 then 
		  a[(i-1) div 2+1].l:=z[i] else
			a[(i-1) div 2+1].r:=z[i];
			
		
	fillchar(f,sizeof(f),0);		
	f[1].l:=1;
	f[1].r:=40000;
	build(1);
	for i:=1 to n do
	  insert(1,a[i].l,a[i].r,i);
	fillchar(t,sizeof(t),false);
	top:=1;
	while f[top].r>=2*n do top:=top*2;
  top:=top div 2;
  visit(top);	
	ans:=0;
	for i:=1 to n do
	  if t[i] then inc(ans);
	writeln(ans);
	end;

end.

 

posted on 2012-05-23 20:51  灰天飞雁  阅读(270)  评论(0编辑  收藏  举报

填写您的邮件地址,订阅我们的精彩内容:  点击这里给我发消息

添加到收藏夹