樹狀陣列的基操

2022-02-04 15:28:22 字數 2358 閱讀 7851

前沿:資料結構

任何乙個資料結構都逃不開這麼幾個東西:增,刪,改,查

樹狀陣列,也叫做二叉索引樹(bit)。

是乙個用來進行區間運算的資料結構。

在一定程度上可以代替線段樹。

樹狀陣列有以下幾個特徵:

1.巧妙地利用了位運算

2.巧妙地結合了樹的資料結構的思想來處理區間問題

3.樹狀陣列的本質還是用來維護序列的字首

樹狀陣列有以下幾個基本操作:

1.樹的節點轉移(位運算)//是2,3,4,的根基

2.單點修改

3.區間修改

4.區間查詢

首先樹狀陣列的大致情況,我給出了一下資料:

演算法競賽入門經典-訓練指南-第194-197頁 

樹狀陣列的時間複雜度和空間複雜度:

1、時間複雜度:

o(logn),這是按照一次更改或者查詢來講的(區域性)

o(nlogn),這是按照更新所有n個值來講的(整體)

2、空間複雜度:

o(n)(一維)

o(n*m)(二維)

接下來就是以上操作的具體實現的**:

等等,先給出一些陣列

c表示樹狀陣列,a表示原序列

好了,let『s go

1.樹的節點轉移(位運算)//關於這個函式的作用和這樣做的原因,在上面提到的書中有講到

int lowbit(int

x)

2,單點修改

與線段樹相同的是,樹狀陣列如果修改了某乙個點的話,勢必會影響到上層區間的維護的值,那麼單點修改的關鍵就是怎麼維護上層區間的維護的值

下面我給出乙個函式:

void add(int d,int

x)}

3.區間修改

這個涉及到了差分陣列的運用

有關差分陣列和這一部分的數學證明,我在一下鏈結種給出:

void qujian_update(int* arr,int x,int

d)}

4.區間查詢

int query(int* arr,int

x)

return

ret;

}

現在,我給出乙份完整的函式**:

第乙份:沒有區間修改的樹狀陣列

#includeusing

namespace

std;

int c[20

];int lowbit(int x)//

作用:返回查詢結點的下標

int sum(int x)//

返回1~x的陣列的字首和

return

ret;

}void add(int x,int d)//

即能夠起到修改區間的作用,又能夠起到構建樹狀陣列(二叉索引樹)的作用

}int query(int l,int r)//

作用:查詢l~r的區間和,注意:sum[l,r]=c[r]-c[l-1];

intmain()

string

s;

while(cin>>s)

else

if(s=="

add")//

修改的命令,在a[x]上加上d => a[x]=a[x]+d

else

if(s=="

change

")//

單點更新=>a[x]=d

}return0;

}

第二份:帶區間修改的樹狀陣列

#include#define mem(a,b) memset(a,b,sizeof(a))

#define maxn 1200000

#define mod 123456789

using

namespace

std;

typedef

long

long

ll;int

c1[maxn],n,c2[maxn],a[maxn];

int lowbit(int

x)void add(int d,intx)}

void qujian_update(int* arr,int x,intd)}

int query(int* arr,int

x)

return

ret;

}int

main()

string

s;

while(cin>>s)

else

}return0;

}

bit還可以用來維護區間,還可以統計逆序數(維護比當前數字小的個數和總和)

陣列基操三連(4)

給定乙個長度為n的整型陣列arr,其中有n個互不相等的自然數1 n 請實現arr的排序 但是不要把下標0 n 1位置上的數值通過直接賦值的方式替換成1 n。要求 時間複雜度為o n 額外空間複雜度為o 1 思路 從左向右檢查,檢查到需要換的以後,就直接把它放到該去的位置,然後被換掉的數,位置肯定也不...

C set multiset 容器的基操

set構造和賦值 有序不可重複 setname 預設建構函式 set const set name 拷貝建構函式 set operator const set name void test01 set大小和交換 size 返回容器中元素的數目 empty 判斷是否為空 swap set 交換兩個集合...

HDU 水餃基情 二維樹狀陣列

該題就是簡單的二維樹狀陣列,保留乙份棋盤的最新狀態即可,樹狀陣列裡面就只保留在原有基礎上增加或者減少的某一種餃子的數量。如下 include include include using namespace std char op 5 char g 1050 1050 int cc 1050 1050...