http://www.lydsy.com/JudgeOnline/problem.php?id=1818
给定平面上的一些黑点,其它位置都是白点,一个白点如果上下左右都有黑点就会变成黑点,求最终会有多少个黑点
就是求交点个数
离散化后,取出所有线段,然后沿任意一个轴朝着一个方向扫,然后把平行于另一个轴的线段用端点记录,扫到一端就在树状数组里+1,另一端-1,树状数组求个区间和贡献答案即可
const
maxn=200000;
type
data=array[0..2*maxn,1..3]of longint;
var
x,y,z:data;
bit:array[0..maxn]of longint;
i,j,k:longint;
n,len,rx,ry,ans:longint;
function min(a,b:longint):longint;
begin
if a>b then exit(b) else exit(a);
end;
function max(a,b:longint):longint;
begin
if a<b then exit(b) else exit(a);
end;
procedure sort(var x:data; l,r:longint);
var i,j,a,b:longint;
begin
i:=l; j:=r; a:=x[(l+r) div 2,1];
repeat
while x[i,1]<a do inc(i);
while a<x[j,1] do dec(j);
if not(i>j) then
begin
b:=x[i,1]; x[i,1]:=x[j,1]; x[j,1]:=b;
b:=x[i,2]; x[i,2]:=x[j,2]; x[j,2]:=b;
b:=x[i,3]; x[i,3]:=x[j,3]; x[j,3]:=b;
inc(i); dec(j);
end;
until i>j;
if l<j then sort(x,l,j);
if i<r then sort(x,i,r);
end;
procedure update(pos,val:longint);
begin
while pos<=ry do
begin
inc(bit[pos],val);
inc(pos,pos and (-pos));
end;
end;
function query(pos:longint):longint;
var sum:longint;
begin
sum:=0;
while pos>0 do
begin
inc(sum,bit[pos]);
dec(pos,pos and (-pos));
end;
exit(sum);
end;
begin
readln(n);
for i:=1 to n do
readln(z[i,1],z[i,2]);
for i:=1 to n do
begin
x[i,1]:=z[i,1];
x[i,2]:=i;
end;
sort(x,1,n);
len:=0; x[0,1]:=-100000005;
for i:=1 to n do
if x[i,1]<>x[i-1,1]
then begin inc(len); z[x[i,2],1]:=len; end
else z[x[i,2],1]:=len;
ry:=len;
for i:=1 to n do
begin
x[i,1]:=z[i,2];
x[i,2]:=i;
end;
sort(x,1,n);
len:=0; x[0,1]:=-100000005;
for i:=1 to n do
if x[i,1]<>x[i-1,1]
then begin inc(len); z[x[i,2],2]:=len; end
else z[x[i,2],2]:=len;
rx:=len;
for i:=1 to n do
begin x[i,1]:=-maxlongint; x[i,2]:=maxlongint; y[i,1]:=-maxlongint; y[i,2]:=maxlongint; end;
for i:=1 to n do
begin
if x[z[i,2],1]=-maxlongint
then begin x[z[i,2],1]:=z[i,1]; x[z[i,2],2]:=z[i,1]; end
else begin x[z[i,2],1]:=min(z[i,1],x[z[i,2],1]); x[z[i,2],2]:=max(z[i,1],x[z[i,2],2]); end;
if y[z[i,1],1]=-maxlongint
then begin y[z[i,1],1]:=z[i,2]; y[z[i,1],2]:=z[i,2]; end
else begin y[z[i,1],1]:=min(z[i,2],y[z[i,1],1]); y[z[i,1],2]:=max(z[i,2],y[z[i,1],2]); end;
end;
ans:=0; len:=0;
for i:=1 to ry do
begin
inc(len); z[len,1]:=y[i,1]; z[len,2]:=i; z[len,3]:=1;
inc(len); z[len,1]:=y[i,2]+1; z[len,2]:=i; z[len,3]:=-1;
end;
sort(z,1,len); {z[i,1]}
j:=1;
for i:=1 to rx do
begin
while z[j,1]=i do
begin
update(z[j,2],z[j,3]);
inc(j);
end;
ans:=ans+query(x[i,2])-query(x[i,1]-1);
end;
writeln(ans);
end.