突然想起樹狀陣列了,因為突然想起之前從來沒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 ...