時間限制: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樣例輸出0121 1
31 3 2
分析:可以用數狀陣列儲存每個數出現的次數,比如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 的逆序數就...