什麼叫逆序數
對於某乙個數來說,它的逆序數等於在它之前有多少個比它大的數
對於某乙個序列來說,逆序數等於所有數的逆序數之和 例如
序列 5 1 5 2
逆序數 0 1 0 2
序列的逆序數 1+2=3
來看逆序數的求法
首先將定義乙個結構體,存數列的值和下標,然後按數值從大到小(數值相同按下標從大到小)sort一下
然後建立樹狀陣列,從最大的元素開始,將其標記,即 add(p【i】.id,1)
利用其query(i)查詢當前1----i的和
對於第i大的數,由於之前所有比它大的數已經標記,所以query(i)就是當前數的逆序數
例如 5 6 3 8 2 其排序之後即是 2 3 5 6 8 將求對應的值的逆序數的問題轉化成了求下標對應的逆序數按求逆
1 2 3 4 5 5 3 1 2 4
序數的方法,先求下標的逆序數 即: 0 + 1 + 2 + 2 + 1 = 6 ,答案即是序列的逆序數,
換一種思路來看, 為了避免加入順序而導致逆序數的不正確,所以從後面開始逆序,因為已經轉化成下標的逆序
所以只需看下標即可, 5 3 1 2 4 對於4的逆序只有5,在c[5]+1,
對於2的逆序有5,3,在c[5]+1,c[3]+1
其餘類似。。。。。
然後對於3來說的樹狀陣列求1~3的和,即是求以3為逆序數(此例是1,2)的數的個數,
同理對於 i 來求1~i 之間的和,就是來求以 i 為逆序數的數的個數,最後求個總和,也就是所要求的該數列的逆序數。
**:
#include#include#includeusing namespace std;
int c[100010];
typedef struct nodeenode;
node maze[10010];
bool cmp(node u,node v)
return sum;
}int main()
sort(maze+1,maze+n+1,cmp);
int sum=0;
for(i=n;i>=1;i--)
printf("%d\n",sum); }
return 0;
}
也是樹狀陣列,不過要離散化處理
所謂的離散化就是將陣列排個序,例如從小到大排序,
那麼將第一小記做1,第二小記做2,那麼就算是離散化了
(離散,字面意思,分離,散開,分成乙個個的小塊,當然每個塊不能相同)
這個處理的話就是這樣
序列 5 1 5 2
離散化陣列 3 1 3 2
這樣從最小的數開始建立樹狀陣列(標記)
那麼i-query(b【i】)就是當前數的逆序數(i為當前第i個的數,b【i】是當前數是第幾小,
query詢問的是1------i有多少個標記的數(小於等於當前數的數),i-query(b【i】)自然是大於當前數 的數 的個數)
例如例項:maze[i].x: 2 5 7 3 4 排序後為 maze[i].x 2 3 4 5 7
maze[i].num 1 2 3 4 5 maze[i].num 1 4 5 2 3
離散化後為: maze[i].x 2 3 4 5 7 按照num的順序走就是:
maze[i].num 1 4 5 2 3 maze[i].num 1 2 3 4 5
b[maze[i].num] 1 2 3 4 5 b[maze[i].num] 1 4 5 2 3
對於這個例子,maze[i].num 從1~n開始遍歷,先add(1),改變字尾和,將比1大的c[i]都加1,
然後add(4),將比4 大的位置都加1
。。。。。以此類推
然後每一次query(b[i]),就代表在i之前有多少比 b[i] 小的數的個數,因為 i 代表b[i] 的位置,即前面有幾個數
所以 i-query(b[i]) ,就代表 b[i] 之前有幾個比它大的數的個數。
補充乙個
離散化三部曲:
1. 陣列 ha 儲存所有存在過的資料,sort排序
2. 對ha陣列進行去重,重複的資料只保留乙個。unique去重(unique函式前提有序)
3. 查詢某個數字離散化之後對應的數字,lower_bound查排名 **
#include#include#include#include#define ll long long
using namespace std;
int n,c[100010];
int lowbit(int x)
void add(int k,int num)}
int query(int k)
return sum;
}typedef struct nodee
node;
node maze[100010];
bool cmp(node u,node v)
void merge_sort(int a, int low, int high)
}void merge(int a, int low, int mid, int high)
}while(i <= mid)
while(j <= high)
for(k = 0, i = low; i <= high; i++, k++)
}
方法四
直接數 的就不寫了
逆序數的幾種求法
求乙個數列的逆序數 逆序對 數列a 1 a 2 a 3 中的任意兩個數a i a j i,如果a i a j 那麼我們就說這兩個數構成了乙個逆序對 逆序數 乙個數列中逆序對的總數 如數列3 5 4 8 2 6 9 5,4 是乙個逆序對,同樣還有 3,2 5,2 4,2 等等 那麼如何求得乙個數列的逆...
逆序數的幾種求法
求乙個數列的逆序數 逆序對 數列a 1 a 2 a 3 中的任意兩個數a i a j i,如果a i a j 那麼我們就說這兩個數構成了乙個逆序對 逆序數 乙個數列中逆序對的總數 如數列3 5 4 8 2 6 9 5,4 是乙個逆序對,同樣還有 3,2 5,2 4,2 等等 那麼如何求得乙個數列的逆...
逆序數的求法
求乙個數列的逆序數 逆序對 數列s 1 a 2 a 3 中的任意兩個數s i s j is j 那麼我們就說這兩個數構成了乙個逆序對 逆序數 乙個數列中逆序對的總數 5,4 是乙個逆序對,同樣還有 3,2 5,2 4,2 等等 那麼如何求得乙個數列的逆序數呢?方法1 乙個乙個的數 最簡單也是最容易想...