題目大意:
在長為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.
2647 線段樹題練習四
x軸上有若干條不同線段,問某個單位區間 x,x 1 上重疊了多少條線段?區間大小不超過100000 每行表示一條線段x,y 最後一行表示x,x 1 題庫上的輸入樣例和資料的輸入完全不同!只好用eoln來讀入,而且資料中會出現x y!最後打出乙個線段樹 每乙個區間記錄乙個c,表示這整個區間有多少條線段...
線段樹 SSLOJ 2647 線段樹練習四
ssl oj ssloj sslo j2647 2647 2647 在平面內有一條長度為n的線段 也算一條線段 可以對進行以下2種操作 1 x y 把從x到y的再加一條線段 2 x 查詢從x到x 1有多少條線段 第一行輸入n,m 第2 m 1行,每行3個數 對於每個查詢操作,輸出線段數目 7 2 2...
SSLGZ 2647 線段樹練習四
問題描述 在平面內有一條長度為n的線段 也算一條線段 可以對進行以下2種操作 1 x y 把從x到y的再加一條線段 2 x 查詢從x到x 1有多少條線段 輸入 第一行兩個數n,m 表示長度為n的線段 接下來的m行讀入x,y 表示在 x,y 的區間中加入一條線段 最後一行兩個數x,y 輸出x到y這乙個...