今天剛學了樹狀陣列,理解還不是很透徹,寫點東西加深理解、記憶c陣列表示樹狀陣列,a陣列表示普通的陣列
下面用乙個模板題來講解:洛谷 樹狀陣列1
乙個很常見也很簡單的單點修改和區間查詢問題。
在學樹狀陣列前有兩種比較常見的解法:
單點修改直接修改值,區間查詢時間複雜度是o(n)
。
使用字首和優化區間查詢,這樣可以把查詢的時間複雜度優化到o(1)
,但是單點修改的複雜度會上公升到o(n)
。
而使用樹狀陣列的話兩者的時間複雜度都是o(logn)
。
先來看單點修改,顯然,結合上面給出的性質,修改了樹狀陣列c[i]
的值之後,所有涵蓋了c[i]的元素全都要變,又因為c[i]
的上一元素c[j]
,有i+lowbit(i)=j,那麼我們只需不斷向上遞推,把所有包含i的元素都修改即可。
再來看區間查詢,上面的最後一條性質也已經說到樹狀陣列字首和的規律,我們要求[a,b]
的區間和,只需用 sum[b]-sum[a-1] 即可。
//
#include
using
namespace std;
#define
lllong
long
#define
mem(a, b)
memset
(a, b,
sizeof
(a))
#define
lowbit
(a)(a &
(-a))#
define
mod1000000007
#define
endl
"\n"
int n, m;
int c[
2000005];
void
update
(int i,
int k)
//更新樹狀陣列
}int
getsum
(int i)
//求出[1,i]的區間和
return ans;
}int
main()
while
(m--
)return0;
}
由於剛剛上手,可能會有錯誤~ 樹狀陣列 區間修改 單點查詢
說一下差分 現在我們有乙個從小到大的數列a a 1 3 6 8 9 然後還有乙個差分陣列b b 1 2 3 2 1 對應 1,3 1,6 3,8 6,9 8,相信某些同學絕已經看出端倪了.這裡b i a i a i 1 我令a 0 0,故b 1 a 1 int now 0,temp scanf d ...
樹狀陣列區間修改,單點查詢
普通的單點修改單點查詢就不講了,從區間修改和單點查詢講起。原來的值存在a裡面,多建立個陣列c1,注意 c1 i a i a i 1 那麼求a i 的值的時候a i a i 1 c1 i a i 2 c1 i c1 i 1 c1 1 c1 2 c1 i 所以就用c1建立樹狀陣列,便可以很快查詢a i ...
樹狀陣列(區間修改,單點查詢)
如題,已知乙個數列,你需要進行下面兩種操作 1.將某區間每乙個數數加上x 2.求出某乙個數的值 輸入格式 第一行包含兩個整數n m,分別表示該數列數字的個數和操作的總個數。第二行包含n個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。接下來m行每行包含2或4個整數,表示乙個操作,具體如下 操...