演算法導論學習 線段樹 2

2021-06-28 15:29:08 字數 2483 閱讀 6422

線段樹(1)

1. 線段樹應用之動態點插與統計:

如上圖所示,我們最後統計的時候是找出cover不為零的節點,(再上圖對應的是節點[3,4]. [5,6], [2], [4], [5], [7].),但是注意到[3,4]和[4] 還有[5,6]和[5]不能從重複統計,所以最後統計的長度是[2]+[3,4]+[5,6]+[7]=6.所以四根木條在牆上的總投影長是6. 

現在我們可以來歸納一下區段插值的幾個重要部分:首先是插入動作,比如插入[l, r]線段,插入動作需要遞迴的從根節點開始插入,而遞迴的出口就是找到能夠和[l, r]完全匹配的線段樹節點,即找到a[i].left==l and a[i].right==r,並且同時將a[i].cover值加1.,遞迴終止。然後是刪除動作,假設刪除[l, r],同樣的也是要從根節點開始刪除,也是要遞迴的找到與[l, r]完全匹配的線段樹節點a[i],並且將a[i].cover值減去1.最後是統計,仍然是從根節點開始遞迴的統計,遞迴的出口要麼是找到的節點a[i]滿足a[i].cover>=0,則返回該節點代表的區段長度。要麼是找到葉子節點(a[i].left==a[i].right),如果葉子節點的cover不為0,則返回1,否則返回零。

以上是對區段插入的回顧,下面開始介紹動態點插與統計。所謂動態點插(其實是我自己diy的,所以我就用圖表示一下吧,大家理解就好)

如上圖所示,1-8表示相互連線的8個槽,然後在這些草內的任意位置放置任意數量個小球,然後讓你求出任意區段內[l, r]的小球數量。比如[2,3]區段內的小球數量是2,[1,6]區段內的小球數量是6。要解決這個問題,可以優良中辦法,一種方法不用說也知道,暴力嘛,開乙個陣列a,然後更新陣列的值。。這種做法當「槽」的範圍過大時是效率很低的。所以這時候線段樹再次派上用場了。我們還是用cover域來表示某個節點縮地阿彪範圍的小球數量。比如根節點代表1-8槽的小球數量。

###第一步,建立線段樹( 裡面有介紹,這裡直接跳過)

###第二步,線段樹插入(點插)

1

void updatepoint(int pos,int step)

我們可以看到,線段樹點插動作是「一路插值的」,這也不難理解,比如我在第3個槽內放置乙個球,那麼顯然的,節點[3].num=1,但同時的,節點[3,4],[1,2,3,4],[1,2,3,4,5,6,7,8]的num值也是為1.所以線段樹點插可以理解記憶為:一路遞迴向下插值。

###第三步,線段樹統計

1

int query(int l,int r,int

step)

5else

12return

ans;13}

14 }

可以看到,線段樹點插結果統計是按照區段來查詢的,所以遞迴查詢的出口也就是找到與之匹配的節點,然後返回相應的cover值,對應**2-4行。如果與當前節點不匹配,則遞迴的「往下」查[6-8],如果帶查詢區段在左右子樹都有子結果,則返回兩個子結果之和。

2. 線段樹應用之區間最大最小值問題:

-----------------------------------

1 #include2 #include3 #include4

using

namespace

std;

5const

int max_size=100;6

const

int inf=1

<<30;7

struct

segmenttreea[max_size*3

];10

void buildtree(int l,int r,int

rt)20

void insert(int pos,int v,int

rt)

26int mid=(a[rt].lc+a[rt].rc)/2;27

if(pos<=mid) insert(pos,v,rt*2

);28

else insert(pos,v,rt*2+1

);29 a[rt].mi=min(a[rt*2].mi,a[rt*2+1

].mi);

30 a[rt].mx=max(a[rt*2].mx,a[rt*2+1

].mx);31}

32int query_min(int l,int r,int

rt)41}42

intmain()

51 scanf("

%d",&q);

52while(q--)57}

58 }

演算法導論學習2

一般的,對於演算法來說,重點關注的是對演算法的時間和空間度量,也就是時間複雜度和空間複雜度。演算法所需要的時間與輸入的規模同步增長的,而時間複雜度就是衡量演算法執行的基本運算元的乙個函式。對於插入排序來說,當需要排列的陣列分別為順序排列和逆序排列時,演算法的時間複雜度是不一樣的。根據演算法執行的每一...

演算法導論學習筆記(2)

big o notation 模擬為小於等於 n2 o n o n2 big omega notation 模擬為 大於等於 模擬為等於 嚴格符號 小o與小 模擬為小於和大於 解遞迴方法 1 替換法 guess the form,verify by induction,solve the const...

演算法導論B樹學習筆記

定義就不重複說明了 b樹與b 樹的不同是,b 樹中非葉子節點的節點也會出現在葉子節點中 b樹要求至少t 1,至多2t 1 b樹一 插入 1 關於高度的定理 h l ogtn 1 2h leqslant log t frac h logt 2n 1 2 操作 抽象出來就是插入到某個節點,滿了之後從中間...