题目大意:
在长为N的线段中(这条线段不算),加入M条线段[X,Y],最后查询某个线段[x,y]保证y=x+1。
1≤n,m≤100000,1≤x≤y≤n
题解:
就是一个线段树+lazy:
1.每次走的时候因为如果你二分到这一个区间就代表你插入的线段一定经过这个区间,这个区间的线段数+1,如果查询到的刚好跟插入的完全覆盖就直接加入lazy中然后退出,等下一次查询这个点带下去。
PS:因为查询的是[l,l+1]所以你二分注意是[l,mid],[mid,r]而不是[l,mid],[mid+1,r],如果那样的话[l,l+1]是搜不到的。
2.递归求解,因为是[l,mid],[mid,r]这样的二分,所以保证[l,l+1]一定不会分开成[l,l],[l+1,l+1],这个区间一定是个整体,是能被查询到的,所以暴力递归,查询到就直接输出= =。
再PS:
本来有貌似强迫症的我想求出全图任意一个区间[l,r]内的线段数的,可无奈做不出,想不出来……
var
rp,tree:array [0..500001] of longint;
i,j,n,m,s,x,y,z:longint;
procedure insert(p,l,r,a,b:longint);
var
mid:longint;
begin
mid:=(l+r) div 2;
inc(tree[p]);
if (l=a) and (r=b)
then inc(rp[p])
else begin
if r-l=1 then exit;
tree[p * 2]:=tree[p * 2]+rp[p];
tree[p*2+1]:=tree[p*2+1]+rp[p];
rp[p * 2]:=rp[p * 2]+rp[p];
rp[p*2+1]:=rp[p*2+1]+rp[p];
rp[p]:=0;
if b<=mid then insert(p * 2,l,mid,a,b)
else if a>=mid then insert(p*2+1,mid,r,a,b)
else begin
insert(p * 2,l,mid,a,mid);
insert(p*2+1,mid,r,mid,b);
end;
end;
end;
procedure count(p,l,r:longint);
var
mid:longint;
begin
mid:=(l+r) div 2;
if (l=x) and (r=y)
then writeln(tree[p])
else begin
if r-l=1 then exit;
tree[p * 2]:=tree[p * 2]+rp[p];
tree[p*2+1]:=tree[p*2+1]+rp[p];
rp[p * 2]:=rp[p * 2]+rp[p];
rp[p*2+1]:=rp[p*2+1]+rp[p];
rp[p]:=0;
if r<=mid then count(p * 2,l,mid)
else if l>=mid then count(p*2+1,mid,r)
else begin
count(p * 2,l,mid);
count(p*2+1,mid,r);
end;
end;
end;
begin
readln(n,m);
for i:=1 to m do
begin
readln(x,y);
insert(1,1,n,x,y);
end;
readln(x,y);
count(1,1,n);
end.