樹狀陣列 求逆序數

2021-08-17 00:02:53 字數 1927 閱讀 4016

一. 樹狀陣列介紹

1)性質

樹狀陣列本質上就是乙個陣列,它與普通陣列不同之處在於它的某些元素維護的是一段區間的資訊,已區間和為例,若i為奇數,則第i個元素就是源資料的第i個元素,若i為偶數,則第i個元素維護的是[i-2^k+1, i]這段區間的和,k代表i的二進位制末尾0的個數。

2)作用

樹狀陣列常用來求解一些查詢區間和相關的問題,還可以用來高效的求解逆序數問題。

二. 樹狀陣列基本操作

1)找到x二進位制下等於1的最低位

int lowbit(int x)
證明:負數在計算機中是以補碼的形式存在的,通過原碼取反加1得到

1. 若x的第一位為1,取反加1後仍為1,1&1=1,即如果x是乙個奇數則lowbit(x)=1

2. 若x的第一位為0,取反加1後等於2,需要進製,若x的第二位也為0,則繼續進製,直到x的某一位為1為止,假設其第i位為1,取反後值為0,0加上進製的1等於1,1&1=1,即如果x是乙個偶數,lowbit(x)=其末尾連續0的個數+1

2)更新操作,將第pos個位置的值加上val

void update(int pos, int val) 

}

3)查詢操作,查詢區間[1, pos]的和

int query(int pos) 

return ans;

}

三. 樹狀陣列求逆序數

1)逆序數問題定義

給乙個1~n的排列,求滿足ia[j]的二元組對數,比如[4,2,1,5,3]這個序列,滿足條件的二元組為,故逆序數是5

2)樹狀陣列求逆序數的原理

首先明確樹狀陣列在此問題中維護資訊是某個區間中數字出現的個數,將源資料按其原本順序插入樹狀陣列,第i個數字插入的方式為將樹狀陣列的第a[i]位設為1,同時更新覆蓋到它的父區間,query(a[i])可求得[1, a[i]]的區間和,這恰好代表第i個數字前小於等於它的個數,等於的只可能是自身,故小於它的有query(a[i])-1個,那麼大於它的顯然就有i-1-(query(a[i])-1) = i-query(a[i])個

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

3)模擬計算過程

源資料下標 1 2 3 4 5

數值 4 2 1 5 3

第一步:

update(4, 1),樹狀陣列:0 0 0 1 0

query(4)=1, 1-query(4)=0

(4是第1個插入的, 其前面沒有1)

第二步:

update(2, 1),樹狀陣列:0 1 0 2 0

query(2)=1, 2-query(2)=1

(2是第2個插入的, 其前面沒有1, 故第1個插入的數字必然比它大, 找到1組逆序<4,2>)

第三步:

update(1, 1),樹狀陣列:1 2 0 3 0

query(1)=1, 3-query(1)=2

(1是第3個插入的, 其前面沒有1, 故前2個插入的數字必然比它大, 找到2組逆序<4,1>, <2,1>)

第四步:

update(5, 1),樹狀陣列:1 2 0 3 1

query(5)=4, 4-query(5)=0

(5是第4個插入的, 其前面有3個1, 故它是當前最大的數字, 不和之前的數構成逆序)

第五步:

update(3, 1),樹狀陣列:1 2 1 4 1

query(3)=3, 5-query(3)=2

(3是第5個插入的, 其前面有2個1, 故前4個數中2個比它大, 2個比它小, 找到2組逆序<4,3>, <5,3>)

累加每步的結果後可得逆序數為5,用樹狀陣列的好處在於update操作和query的操作時間複雜度都為o(logn),非常的巧妙

樹狀陣列求逆序數

逆序數就是數中各位在它前面有多少個數比它大,求出這些元素個數之和。今天看了個樹狀陣列,可以很好的解決這個問題,普通方法需要o n 2 複雜度,用樹狀陣列只需要o nlongn 樹狀陣列實際上還是乙個陣列,只不過它的每個元素儲存了跟原來陣列的一些元素相關的結合值。若a為原陣列,定義陣列c為樹狀陣列。c...

樹狀陣列求逆序數

chikachika說希望和我一起做學園偶像的時候,我真的很開心。watanabeyouwatanabeyou 曜是千歌的青梅竹馬,但是aqoursaqours成立以後,千歌似乎總是與梨子在一起,而把曜冷落了。為了讓千歌知曉自己的心意,曜醬決定做一件大事!她決定把乙個給定的11 nn的排列 1 ai...

樹狀陣列求逆序數

1 什麼是逆序數?在乙個排列中,如果一對數的前後位置與大小順序相反,即前面的數大於後面的數,那麼它們就稱為乙個逆序。乙個排列中逆序數的總數就是這個排列的逆序數。2 用樹狀陣列求逆序數的總數 2.1該背景下樹狀陣列的含義 我們假設乙個陣列a n 當a n 0時表示數字n在序列中沒有出現過,a n 1表...