NYOJ 117 求逆序數 (樹狀陣列)

2022-08-22 01:33:12 字數 1479 閱讀 1627

時間限制:2000 ms  |  記憶體限制:65535 kb

難度:5

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

現在,給你乙個n個元素的序列,請你判斷出它的逆序數是多少。

比如 1 3 2 的逆序數就是1。

輸入第一行輸入乙個整數t表示測試資料的組數(1<=t<=5)

每組測試資料的每一行是乙個整數n表示數列中共有n個元素(2〈=n〈=1000000)

隨後的一行共有n個整數ai(0<=ai<1000000000),表示數列中的所有元素。

資料保證在多組測試資料中,多於10萬個數的測試資料最多只有一組。

輸出輸出該數列的逆序數

樣例輸入

2

21 1

31 3 2

樣例輸出01

分析:可以用數狀陣列儲存每個數出現的次數,比如c[1]=3 代表目前為止 1出現了三次

sum(a[i].val)表示小於等於它的數目      i表示目前為止總的數目

這樣的話 i-sum(a[i].val) 就表示目前為止 大於a[i].val的數目 

把每次的結果累加起來就可以了

但是這裡的話資料範圍較大

需要進行離散化,這裡離散化的時候有個特點,用排序前的編號代表它們的值

這樣的話,如果排序前已經有序,排序那麼編號一定依次遞增,那麼對於每個編號,

在該編號前,大於它的,就是一對逆序數.問題就轉化為了對編號進行樹狀陣列操作

需要注意的是:排序的時候 相同的值編號靠前的先排,因為我們需要先訪問編號靠前的.

#include 

#include

#include

#include

#include

using

namespace

std;

typedef

long

long

ll;const

int maxn=1000010

;int

c[maxn];

intn;

inta[maxn];

intcnt;

struct

node

r[maxn];

intcmp(node x,node y)

int lowbit(int

x)void add(int i,int

value)

}int sum(int

i)

return

sum;

}int

main()

sort(r+1,r+n+1

,cmp);

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

printf(

"%lld\n

",ans);

}return0;

}

NYOJ 117 求逆序數 (樹狀陣列)

時間限制 2000 ms 記憶體限制 65535 kb 難度 5 描述 在乙個排列中,如果一對數的前後位置與大小順序相反,即前面的數大於後面的數,那麼它們就稱為乙個逆序。乙個排列中逆序的總數就稱為這個排列的逆序數。現在,給你乙個n個元素的序列,請你判斷出它的逆序數是多少。比如 1 3 2 的逆序數就...

nyoj117求逆序數

時間限制 2000 ms 記憶體限制 65535 kb 難度 5 描述 在乙個排列中,如果一對數的前後位置與大小順序相反,即前面的數大於後面的數,那麼它們就稱為乙個逆序。乙個排列中逆序的總數就稱為這個排列的逆序數。現在,給你乙個n個元素的序列,請你判斷出它的逆序數是多少。比如 1 3 2 的逆序數就...

NYOJ117 求逆序數

時間限制 2000 ms 記憶體限制 65535 kb 難度 5 描述 在乙個排列中,如果一對數的前後位置與大小順序相反,即前面的數大於後面的數,那麼它們就稱為乙個逆序。乙個排列中逆序的總數就稱為這個排列的逆序數。現在,給你乙個n個元素的序列,請你判斷出它的逆序數是多少。比如 1 3 2 的逆序數就...