樹狀陣列入門(求和)

2021-08-07 04:50:48 字數 1464 閱讀 1353

輸入乙個數列a1,a2….an(1<=n<=100000),在數列上進行m(1<=m<=100000)次操作,操作有以下兩種:

(1)格式為c i x,其中c為字元"c",i和x(1<=i<=n,|x|<=10000)都是整數,表示把把a[i]改為x

(2)格式為q l r,其中q為字元"q",l和r表示詢問區間為[l,r](1<=l<=r<=n),表示詢問a[l]+…+a[r]的值。

第一行輸入n(1<=n<=100000),表述數列的長度,接下來n行,每行乙個整數(絕對值不超過10000)依次輸入每個數

;接下來輸入乙個整數m(1<=m<=100000),表示運算元量,接下來m行,每行為c i x或者q l r。

對於每個q l r 的操作輸出答案。

512

3453

q 2 3

c 3 9

q 1 4

5

16

圖大家自己上網找,這裡解釋樹狀陣列的構造

假如有兩個陣列,其中乙個是a陣列,另乙個是樹狀陣列t陣列

樹狀陣列類似字首和,但是效率要高得多

t[1]=a[1],t[2]=t[1]+a[2],t[3]=a[3],t[4]=t[2]+t[3],t[5]=a[5],t[6]=t[2]+a[6],t[7]=a[7],t[8]=t[7]+t[6]+t[4];

然後大家可以發現乙個規律,樹狀陣列t字尾為奇數就是陣列a中的本身,轉成二進位制後就很直觀了

就拿8舉個例子,8轉成二進位制後是1000

k代表的是轉成二進位制之後的出現0的位置,二進位制最右一位是2^0,那麼我們可以發現(n=8)n-2^k恰好就是t陣列加上的

就像8二進位制第乙個出現0的位置是第0個,那麼n-2^0=8-1=7,t[8]確實加了t[7]。

這是不是偶然呢?顯然是不可能的,不信我們繼續看,8二進位制第二個0出現在第1個位置,那麼n-2^1=8-2=6,t[8]也確實加了t[6],這樣一來n-2^2=8-4=4,0走完了,t[8]也加完了,這個是真實存在的現象,然後也會很好記憶,如果還有疑惑可以自己去推其他的

下面給出此題**:

#includeusing namespace std;

int maxn=100010;

int n,m;int a[100010];

int c[100010];

char s[2];

int lowbit(int p)

void add(int p,int num)

return;

}int query(int p)

return tmp;

}int main()

scanf("%d",&m);

for(int i=1;i<=m;i++)

else

}

return 0;

}

樹狀陣列入門(求和)

輸入乙個數列a1,a2 an 1 n 100000 在數列上進行m 1 m 100000 次操作,操作有以下兩種 1 格式為c i x,其中c為字元 c i和x 1 i n,x 10000 都是整數,表示把把a i 改為x 2 格式為q l r,其中q為字元 q l和r表示詢問區間為 l,r 1 l...

樹狀陣列 區間求和

樹狀陣列 是乙個查詢和修改複雜度都為log n 的資料結構,假設陣列a 1.n 那麼查詢a 1 a n 的時間是 log n 級別的。所以如果要解決 陣列中的元素不斷被修改,怎麼才能快速地獲取陣列中連續m個數的和 這個問題的話,用樹狀陣列就再好不過了 首先,什麼是樹狀陣列呢?樹狀陣列就是用另外乙個陣...

樹狀陣列1 樹狀陣列入門

仔細看一下,發現tree的每乙個節點的高度並不是隨意的,而是由它轉成二進位制之後末尾連續零的數量決定的,連續零的數量加1,就是高度,例如 3 11 零的數量為0,加1等於1,所以它的高度就是1 6 110 零的數量為1,加1等於2,所以它的高度就是2 8 1000 零的數量為3,加1等於4,所以它的...