樹狀陣列求逆序數 poj 2299

2021-06-26 19:21:13 字數 2100 閱讀 3469

突然想起樹狀陣列了,因為突然想起之前從來沒a掉的那個樹狀陣列求逆序數的題,大概意思就是求乙個陣列用氣泡排序排序後的交換次數,因為資料量為5萬,所以o(n*n)的冒泡模擬肯定是超時的,所以題目的解法可以有兩種,一種是歸併排序,歸併排序的乙個應用正是求逆序數,而另乙個就是樹狀陣列了。

思想就是通過將數乙個乙個的插入到樹狀陣列中,每次統計這個數之前比它大的數的sum值,所以這裡樹狀陣列裡每次add更新的是比這個數大的數的個數而不是數的值。因為資料裡面給的範圍是99999999,特別大,所以說需要離散化一下。一開始看別的人的本來我也討厭離散化的,可惜看著資料量覺得不離散化好像過的費勁(現在看看離散化也沒太煩)。為啥需要離散化呢?比如給你5個數,

99999999,1,2,3,4.

這些數里,第乙個數需要用的樹狀陣列為c[99999999]這麼大,就是這個意思,開不了這麼大-_-#,那麼我們可以用乙個結構體node,裡面有倆值,乙個存輸入的值,乙個存這個值的下標:

struct node

;

node p[510000];//離散化的陣列
那麼我們每次輸入的時候就輸入到p[i].data,並且p[i].pos = i;

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

然後我們將這個離散化的陣列按照    數值   從小到大排序。

bool cmp(node a,node b)

sort(p+1,p+n+1,cmp);
再用乙個陣列a[510000]來儲存排序後的離散化陣列

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

a[ p[i].pos ] = i;

開始的時候,大家到這一步可能有點蒙,好好想想,其實就是這個意思:你要求的陣列一共不超過500000個,但是如果用樹狀陣列來求,你就需要最大c[9999999]這麼大的,所以我們就將99999999存在p[n].data裡面,這時候n最大就是500000吧,所以達到減少記憶體的目的,這時候上面我給的樣例就是

p[i].data: 1,2,3,4,99999

p[i].pos:  2,3,4,5,1

a[ p[i].pos ]:  1,2,3,4,5

也就是 a[2] = 1,a[3] = 2,a[4] = 3,a[5] = 4,a[1] = 5;

接下來就是將每個數插入到樹狀陣列中,並且每次往add裡增加的數並不是第i個數的數值data,而是+1,也就是說每次sum統計的是比這數小的數,然後我們用這個i-sum(a[i])得到的就是這個數的逆序數啦

我們將答案加上每個數的逆序數即可

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

完整的程式:

#include #include #include #include #include #include #include #include #include using namespace std;

struct node

;long long ans;

node p[510000];//離散化的陣列

int c[510000];//樹狀陣列

int a[510000],n;//存離散化陣列的a陣列

bool cmp(node a,node b)

int lowbit(int x)

void add(int i,int x) }

int sum(int i)

return ans;

}int main(int argc, char *argv)

sort(p+1,p+n+1,cmp);

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

a[p[i].pos] = i;

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

printf("%lld\n",ans);

} return 0;

}

文筆也不好,要是有啥不對的大家一定告訴我t_t (500多ms過的,弱爆了)

poj 2299 求逆序數

在只允許相鄰兩個元素交換的條件下,得到有序序列的交換次數 乙個亂序序列的 逆序數 求其逆序數 從左到右找到每乙個ai的 乙個陣列x x j 1表示此時有j這個數 x j 0表示此時還沒有j這個數 一開始x全部賦值為0 對於每乙個a i 求出 x k 1 k這裡用的樹狀陣列實現的這個過程 輔助陣列c ...

poj 2299 樹狀陣列求逆序數 離散化

最初做離散化的時候沒太確定但是寫完發現對的 因為字尾陣列學的時候,這種思維習慣了吧 1 初始化as i i 對as陣列按照num的大小間接排序 2 bs as i i 現在bs陣列就是num陣列的離散化後的結果 3 注意,樹狀陣列中lowbit i i是不可以為0的,0 0 0,死迴圈.includ...

poj 2299 樹狀陣列離散化逆序數 水

include include include include include include include include include include include include include include include define iinf 2000000000 define ...