题意:n(n<=10000)个人依次贴海报,给出每张海报所贴的范围li,ri(1<=li<=ri<=10000000)。求出最后还能看见多少张海报。
分析:一看就知道是线段树啦。然后就先离散化一下,再就是个普通的线段树啦。注意在插入操作时要把原来的海报覆盖掉就好啦。(啦够了没有)
代码:
var o,e,i,j,ans,x,y,n:longint; l,r:array[1..10000] of longint; a:array[0..20000,1..2] of longint; v:array[1..10000] of boolean; t:array[1..400000,1..3] of longint; procedure qsort(l,r:longint); var i,j,k:longint; begin if l>=r then exit; i:=l; j:=r; k:=a[(i+j) div 2,1]; repeat while a[i,1]<k do inc(i); while a[j,1]>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; qsort(i,r); qsort(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; if l=r then exit; m:=(l+r) div 2; hehe(d*2,l,m); hehe(d*2+1,m+1,r); end; procedure insert(d,l,r,z:longint); var m:longint; begin if (t[d,1]=l)and(t[d,2]=r) then begin t[d,3]:=z; exit; end; if t[d,3]>0 then begin t[d*2,3]:=t[d,3]; t[d*2+1,3]:=t[d,3]; t[d,3]:=0; end; m:=(t[d,1]+t[d,2]) div 2; if r<=m then insert(d*2,l,r,z) else if l>m then insert(d*2+1,l,r,z) else begin insert(d*2,l,m,z); insert(d*2+1,m+1,r,z); end; end; procedure count(d:longint); begin if t[d,3]>0 then begin v[t[d,3]]:=false; exit; end; if t[d,1]=t[d,2] then exit; count(d*2); count(d*2+1); end; begin readln(o); for e:=1 to o do begin readln(n); for i:=1 to n do begin readln(x,y); a[i*2-1,1]:=x; a[i*2-1,2]:=i; a[i*2,1]:=y; a[i*2,2]:=i; end; qsort(1,n*2); j:=0; a[0,1]:=0; fillchar(l,sizeof(l),0); fillchar(r,sizeof(r),0); for i:=1 to n*2 do begin if a[i,1]<>a[i-1,1] then inc(j); if l[a[i,2]]=0 then l[a[i,2]]:=j else r[a[i,2]]:=j; end; hehe(1,1,j); for i:=1 to n do insert(1,l[i],r[i],i); fillchar(v,sizeof(v),true); count(1); ans:=0; for i:=1 to n do if v[i]=false then inc(ans); writeln(ans); end; end.