P1047校門外的樹(線段樹初實踐)

2021-10-07 20:36:08 字數 2012 閱讀 8860

某校大門外長度為 l 的馬路上有一排樹,每兩棵相鄰的樹之間的間隔都是 1 公尺。我們可以把馬路看成乙個數軸,馬路的一端在數軸 0 的位置,另一端在 l的位置;數軸上的每個整數點,即 0,1,2,…,l,都種有一棵樹。

由於馬路上有一些區域要用來建地鐵。這些區域用它們在數軸上的起始點和終止點表示。已知任一區域的起始點和終止點的座標都是整數,區域之間可能有重合的部分。現在要把這些區域中的樹(包括區域端點處的兩棵樹)移走。你的任務是計算將這些樹都移走後,馬路上還有多少棵樹。

第一行有兩個整數,分別表示馬路的長度 l 和區域的數目 m。

接下來 m 行,每行兩個整數 u, v,表示乙個區域的起始點和終止點的座標。

輸出一行乙個整數,表示將這些樹都移走後,馬路上剩餘的樹木數量。

輸入輸出樣例

輸入           輸出

500 3         298

150 300

100 200

470 471

說明/提示

資料規模與約定

對於 20% 的資料,保證區域之間沒有重合的部分。

對於 100% 的資料,保證1≤l≤10e4

1≤m≤100

對於本題可以開乙個10000的陣列,初始化為1,對於每乙個對應區間的樹就標記為0,最後將整個陣列內的值求和即可。

在題解中看到了線段樹的內容,作為乙個剛學完資料結構的小白還不知道什麼是線段樹,藉著這道題熟悉了一下線段樹的基本內容和演算法。

線段樹類似於乙個二叉排序樹,只是排序的內容變成了集合的分割,即根節點的集合範圍被分割成左孩子的集合和右孩子的集合,以此類推,直到葉子節點的集合左右邊界相等。

下圖就是乙個典型的線段樹例項

對於本題,則可以將每個目標區間內的樹設定為0,利用線段樹從根節點向下搜尋,一旦節點的區間覆蓋了該節點則將該節點的value設定為0,進行更新,最後求和即可。

lazytag:延遲標記,目前的理解是當不需要處理子孩子節點的更新資料時,直接標記lazytag,當需要用到該節點的子孩子資料時,將lazytag向下推,並清除該節點的lazytag.

對於此題,可知道修改區間有重疊。比如第一次[150-300]時講[150-300]範圍內的lazytag記為1,並將目的節點置為0.

然而當第二次區間為[100-200]時,出現了修改區間的重疊,這時候就需要用到上一次lazytag標記的節點的子節點,這個時候我們再進行pushdown操作將節點內容下推更新,提高了修改效率,不需要牽一髮而動全身。

ac**如下:

#include #include #define maxn 20000

//線段樹

typedef struct segtree

tree;

tree segtree[maxn*4];

void build(int left,int right,int u)//u為節點位置

int m=(left+right)/2;

build(m+1,right,2*u+1);//右孩子

build(left,m,2*u);//左孩子

segtree[u].value=segtree[u+u].value+segtree[u*2+1].value;//父親權值為孩子區間和

}void pushdown(int u)

void update(int u,int x,int y)//x為目的查詢左區間,y為目的查詢右區間

if(segtree[u].lazytag!=0)//已經覆蓋了

int m=(segtree[u].left+segtree[u].right)/2;

if(x<=m)

if(y>m)

segtree[u].value=segtree[u+u].value+segtree[u+u+1].value;//更新值

}int main()

printf("%d",segtree[1].value);

}

洛谷 P1047 校門外的樹 線段樹版

第一次脫離模板寫線段樹題目 洛谷的線段樹模板題太 了 言歸正傳,這是乙個未完成版的線段樹,因為一直到最後都沒有發現為什麼第一組資料會wa.後來苦心研究之後,發現線段樹處理0的時候會有問題,於是想了兩個解決辦法應對該情況。這個題目唯一的坑點在於從0開始,意思是輸入的500實質上有501棵樹,而線段樹的...

P1047 校門外的樹

某校大門外長度為l的馬路上有一排樹,每兩棵相鄰的樹之間的間隔都是1公尺。我們可以把馬路看成乙個數軸,馬路的一端在數軸0的位置,另一端在l的位置 數軸上的每個整數點,即0,1,2,l,都種有一棵樹。由於馬路上有一些區域要用來建地鐵。這些區域用它們在數軸上的起始點和終止點表示。已知任一區域的起始點和終止...

P1047 校門外的樹

某校大門外長度為l的馬路上有一排樹,每兩棵相鄰的樹之間的間隔都是1公尺。我們可以把馬路看成乙個數軸,馬路的一端在數軸0的位置,另一端在l的位置 數軸上的每個整數點,即0,1,2,l,都種有一棵樹。由於馬路上有一些區域要用來建地鐵。這些區域用它們在數軸上的起始點和終止點表示。已知任一區域的起始點和終止...