考研C語言資料結構-圖(圖的鄰接矩陣實現 + 廣度、深度優先遍歷)
阿新 • • 發佈:2022-06-05
樹狀陣列學習筆記
簡介
樹狀陣列是一個可以在 \(O(\log n)\) 的時間複雜度內支援單點修改和查詢字首和的操作的資料結構。
\(\text{lowbit}\)
\(\text{lowbit}\) 是指一個數在二進位制下最末尾的1的位置。\(\text{lowbit(x) = x and -x}\)
寫法
建立
把編號為 \(i\) 的點和編號為\(i+\text{lowbit}(i)\)的點連起來。
然後把點\(i\)到根節點路徑上的所有點的\(val\)加上\(a_i\)。
修改
把點\(i\)到根節點路徑上的所有點的\(val\)加上\(data\)。
查詢
如果要查詢\([l,r]\)
如何求字首和呢?
就是從點 \(i\) 一直往下跳 (\(\text{-lowbit(i)}\)),直到跳到0,把中間的所有\(val\)加起來就是字首和了。
程式碼
int val[MAXN]; void change(int x,int data){//修改&建立 for(int i=x;i<=MAXN;i+=lowbit(i))val[i]+=data; } int ask(int x){//字首和 int ans=0; for(int i=x;i!=0;i-=lowbit(i))ans+=val[i]; return ans; } int ask(int l,int r){//查詢 return ask(r)-ask(l-1); }
二維樹狀陣列
可以求出二維數組裡的字首和,時間複雜度\(O(\log^2 n)\)。
與一維樹狀陣列相似。
int val[MAXN][MAXN]; void change(int x,int y,int data){//修改&建立 for(int i=x;i<=MAXN;i+=lowbit(i)) for(int j=y;j<=MAXN;j+=lowbit(j)) val[i][j]+=data; } int ask(int x,int y){//字首和 int ans=0; for(int i=x;i!=0;i-=lowbit(i)) for(int j=y;j!=0;j-=lowbit(j)) ans+=val[i][j]; return ans; } int ask(int x1,int y1,int x2,int y2){//查詢 return ask(x2,y2)-ask(x2,y1-1)-ask(x1-1,y2)+ask(x1-1,y1-1); }