樹狀陣列求逆序數

2021-08-22 00:20:54 字數 1472 閱讀 8022

1、什麼是逆序數?

在乙個排列中,如果一對數的前後位置與大小順序相反,即前面的數大於後面的數,那麼它們就稱為乙個逆序。乙個排列中逆序數的總數就是這個排列的逆序數。

2、用樹狀陣列求逆序數的總數

2.1該背景下樹狀陣列的含義

我們假設乙個陣列a[n],當a[n]=0時表示數字n在序列中沒有出現過,a[n]=1表示數字n在序列中出現過。a對應的樹狀陣列為c[n],則c[n]對應維護的是陣列a[n]的內容,即樹狀陣列c可用於求a中某個區間的值的和。

樹狀陣列的插入函式(假設為 void insert(int i,int x) )的含義:在求逆序數這個問題中,我們的插入函式通常使用為insert( i , 1 ),即將陣列a[i]的值加1 (a陣列開始應該初始化為0,所以也可以理解為設定a[ i ]的值為1,即將數字i 加入到序列的意思 )。,同時維護c陣列的值。

樹狀陣列中區間求和函式(假設函式定義為: int getsun(int i ) )的含義:該函式的作用是用於求序列中小於等於數字 i 的元素的個數。這個是顯而易見的,因為樹狀陣列c 維護的是陣列a的值,則該求和函式即是用於求下標小於等於 i 的陣列a的和,而陣列a中元素的值要麼是0要麼是1,所以最後求出來的就是小於等於i的元素的個數。

所以要求序列中比元素a大的數的個數,可以用i - getsum(a)即可( i 表示此時序列中元素的個數)。

2.2如何使用樹狀陣列求逆序數總數

首先來看如何減小問題的規模:

要想求乙個序列 a b c d,的逆序數的個數,可以理解為先求出a b c的逆序數的個數k1,再在這個序列後面增加乙個數d,求d之前的那個序列中值小於d的元素的個數k2,則k1+k2即為序列a b c d的逆序數的個數。

舉個例子加以說明:

假設給定的序列為 4 3 2 1,我們從左往右依次將給定的序列輸入,每次輸入乙個數temp時,就將當前序列中大於temp的元素的個數計算出來,並累加到ans中,最後ans就是這個序列的逆序數個數。

序列的變化(下劃線為新增加元素)

序列中大於新增加的數字的個數

操作初始化時序列中乙個數都沒有

往序列中增加4,統計此時序列中大於4的元素個數

往序列中增加3,統計此時序列中大於3的元素個數

往序列中增加2,統計此時序列中大於2的元素個數

往序列中增加1,統計此時序列中大於1的元素個數

當所有的元素都插入到序列後,即可得到序列的逆序數的個數為1+2+3=6.

2.3 c++實現**如下:

#include #include using namespace std;

#define n 1010

int c[n];

int n;

int lowbit(int i)

int insert(int i,int x)

return 0;

}int getsum(int i)

return sum;

}void output()

cout<——來自 熊貓 [

樹狀陣列求逆序數

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

樹狀陣列求逆序數

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

樹狀陣列 求逆序數

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