線段樹 樹狀陣列 並查集

2021-10-08 22:18:17 字數 2298 閱讀 2341

利用線段樹十分方便的處理區間,線段樹是一棵完美的二叉樹,樹上的每乙個節點都維護乙個區間,根維護的是整個區間,線段樹通常用來計算區間內資料的和或者是修改某處的值。

對區間的操作可以再o(logn)的時間內完成。

下面我們通過**實現線段樹的構建,修改,區間求和。

#include

#include

//線段樹

#define max_len 1000

//構造線段樹

void

build_tree

(int arr,

int tree,

int node,

int start,

int end)

else

}void

update_tree

(int arr,

int tree,

int node,

int start,

int end,

int idx,

int val)

else

else

//更新節點(通過搜尋到了相應的部位)

tree[node]

= tree[left_node]

+ tree[right_node];}

}int

query_tree

(int arr,

int tree,

int node,

int start,

int end,

int l,

int r)

else

if(start == end)

else

if(l<=start && r>=end )

int mid =

(start+end)/2

;int left_node =

2* node +1;

int right_node =

2* node +2;

int sum_left =

query_tree

(arr,tree,left_node,start,mid,l,r)

;int sum_right =

query_tree

(arr,tree,right_node,mid+

1,end,l,r)

;return sum_left+sum_right;

}int

main()

;int size=6;

int tree[max_len]=;

build_tree

(arr,tree,0,

0,size-1)

;return0;

}

最為重要的就是lowbit操作(類似補碼)

這樣在給陣列的某乙個值向上新增的時候就可以逐層向上操作了

**實現

int bit[max_n+1]

,n;int

sum(

int i)

return s;

}void

add(

int i,

int x)

}

b站很詳細的詳解 看前分鐘就可

並查集主要是為了找根節點,按照普通方法找的話,應該是從最深的節點往上遞迴,看看最終的根節點是哪個。(圖已經很清楚了)

上**

#include

using

namespace std;

const

int maxn =

1e6+7;

int fa[maxn]

;intfi(

int x)

void

union1

(int x,

int y)

intcheck

(int x,

int y)

intmain()

}

03 並查集 帶權,分類 樹狀陣列 線段樹

並查集板子題,記錄是否被修,然後每次修了以後更新相連的電腦。include include includeusing namespace std typedef long long ll const ll max n 2e5 100 const ll inf 0x3f3f3f3f int n,xs ...

紅綠 線段樹分治, 並查集

對 1,q to t 1,q tot 1,q t ot 進行線段樹分治,將每個 綠綠 的 影響區間分為 log q tot log q tot logq t ot個區間散布在線段樹節點中,其中 qto tq tot qt o t 為詢問的總數 然後對線段樹dfs dfsdf s,合併祖先鏈的和當前節...

bzoj 3211 樹狀陣列 並查集

題意 1 詢問 l,r 區間和 2 修改 l,r 區間的delta dalta i int sqrt delta i 思路 1 區間求和和區間修改我們可以考慮相應的資料結構 線段樹或樹狀陣列,這裡我們選擇樹狀陣列 2 開根號的性質 1 1 或 0 開根號後數值和對答案的貢獻不變,即開根號操作對0 或...