[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.

浙公网安备 33010602011771号