Description
在遥远的火星上,上面的植物非常奇怪,都是长方形的,每个植物用三个数来描述:左边界L、右边界R以及高度H,如下图所示描述一个植物:L=2,R=5和H=4。
每天都有一个新植物长出来,第一天的植物高度为1,后面每天长出的植物比前一天的高1。
当一个新植物长出来的时候,跟其他植物的水平线段相交处会长出一朵小花(前提是之前没有长出花朵),如果线段交于端点,是不会长花的。
下图为示意图:
给出每天的植物的坐标,计算每天长出多少新花。
Input
第一行包含一个整数N(1<=N<=100000),表示天数。
接下来N行,每行两个整数L和R(1<=L<=R<=100000),表示植物的左右边界。
Output
输出每天长出新植物后增加新花的数量。
思路
看到线段和区间就要想到线段树,这是应该的吧
维护一棵线段树,记录区间上有多少线段覆盖
每次查询当前线段的l,l和r,r线段覆盖数,减去重复的u[l]和u[r]就是答案
(自行画图理解一下)
code
type
tree=record
l,r,c:longint;
end;
var
t:array[0..801872]of tree;
u:array[0..100000]of longint;
ans,p:longint;
procedure build(f,x,y:Longint);
var
mid:longint;
begin
t[f].l:=x;
t[f].r:=y;
if y=x then exit;
mid:=(x+y)div 2;
build(f*2,x,mid);
build(f*2+1,mid+1,y);
end;
procedure add(f,x,y:longint);
var
mid:Longint;
begin
mid:=(t[f].l+t[f].r)div 2;
if (x=t[f].l)and(y=t[f].r) then
inc(t[f].c)
else
if (y<=mid) then
add(f*2,x,y)
else
if (x>=mid+1) then
add(f*2+1,x,y)
else
begin
add(f*2,x,mid);
add(f*2+1,mid+1,y);
end;
end;
procedure find(f,x,y:longint);
var
mid:longint;
begin
ans:=ans+t[f].c;
mid:=(t[f].l+t[f].r)div 2;
if (t[f].l=x)and(t[f].r=y) then exit
else
if y<=mid then
find(f*2,x,y)
else
if x>=mid+1 then
find(f*2+1,x,y)
else
begin
find(f*2+1,x,mid);
find(f*2+1,mid+1,y);
end;
end;
procedure main;
var
n,i,j,k:longint;
x,y,g:longint;
begin
readln(n);
build(1,1,100000);
for i:=1 to n do
begin
readln(x,y);
ans:=0;
find(1,x,x);
j:=ans;
find(1,y,y);
k:=ans-j;
writeln(ans-u[x]-u[y]);
u[x]:=j+1;
u[y]:=k+1;
add(1,x,y);
end;
end;
begin
main;
end.