题目
x轴上有若干条不同线段,问某个单位区间[x,x+1]上重叠了多少条线段?
区间大小不超过100000
每行表示一条线段x,y
最后一行表示x,x+1
题解
题库上的输入样例和数据的输入完全不同!
只好用eoln来读入,而且数据中会出现x>y!
最后打出一个线段树
每一个区间记录一个c,表示这整个区间有多少条线段。统计是从(b[p]=x,e[p]=x+1)一直加到c[1],输出结果
时间复杂度O(m log n)
代码
var
b,e,j,k,c:array[1..1000000]of longint;
n,m,i:longint;
procedure setup(p:longint);
var
m:longint;
begin
if e[p]-b[p]>1 then
begin
m:=(b[p]+e[p])div 2;
b[p*2]:=b[p];
e[p*2]:=m;
b[p*2+1]:=m;
e[p*2+1]:=e[p];
setup(p*2);
setup(p*2+1);
end;
end;
procedure insert(p,l,r:longint);
var
m:longint;
begin
if (b[p]=l)and(e[p]=r) then begin c[p]:=c[p]+1;exit;end;
m:=(b[p]+e[p])div 2;
if r<=m then insert(p*2,l,r) else
if l>=m then insert(p*2+1,l,r) else
begin
insert(p*2,l,m);
insert(p*2+1,m,r);
end;
end;
function count(p,l:longint):longint;
var
m,k:longint;
begin
if e[p]-b[p]=1 then exit(c[p]);
m:=(b[p]+e[p]) div 2;
if l+1<=m then k:=count(p*2,l) else
if l>=m then k:=count(p*2+1,l);
exit(k+c[p]);
end;
begin
while not eoln do
begin
inc(m);
readln(j[m],k[m]);
if j[m]>k[m] then
begin
i:=j[m];
j[m]:=k[m];
k[m]:=i;
end;
if k[m]>n then n:=k[m];
end;
b[1]:=1;e[1]:=n;
setup(1);
for i:=1 to m-1 do
insert(1,j[i],k[i]);
writeln(count(1,j[m]));
end.