逆序對 (樹狀陣列 歸併排序

2022-08-19 13:54:15 字數 1484 閱讀 6271

陣列前面的乙個元素 大於等於 後面的乙個元素就是乙個逆序對;

樹狀陣列可以快速求字首和,利用這一特性,可以求逆序對個數,見下:

用陣列c[ i ]記錄陣列a[ n ]中i這一元素出現的次數 ,當a[ n ]中元素較大時可以離散化處理。

將a[ n ]從a[n -1]到a[0] 依次存到樹狀陣列中,每存乙個,對存的元素i求一次c[i]的字首和, 這就是當前已掃瞄過的比i小的元素的個數,由於a[n]是倒著掃瞄的,所以此時比i小的元素都對應乙個逆序對,統計之。

#include #include 

#include

using

namespace

std;

int c[600000

];int a[600000] ,b[600000

];int

n;long

long

ans;

int lowbit( int

x)void updata( int x ,intv)}

int getsum( int

x)

returns;}

intmain( )

sort( b ,b + n); //

離散化處理

int sz = unique( b ,b+n) -b;

ans = 0

;

for( int i=n-1 ;i >=0 ;i--)

printf(

"%lld\n

",ans);

}return0;

}

歸併排序求逆序對在lrj的高效演算法設計一章學過,不過又把一些細節忘了:

1) 分治的引數x,y是左閉右開的,就是(n-1是陣列末項下標 (0,n)->( 0,m ),(m ,n )

2)  分治條件y-x>1,因為y是開的,碰不到,y-x==1就是只有乙個元素不能再分的情況了

3) 求逆序對時是 cnt += m-p,有半部分有乙個小的左半部分沒排的(m-p個)都是比他大的

#include #include 

#include

#include

using

namespace

std;

int a[600000

];int b[600000

];int

n;long

long

ans;

void ergesort( int x ,int

y)

for( int i=x ; ib[ i];

return;}

intmain( )

ergesort(

0,n);

//for( int i=0 ;iprintf( "

%lld\n

",ans);

}return0;

}

求逆序對(歸併排序 樹狀陣列)

兩種演算法的時間複雜度都是 o nlogn 但是,有可能樹狀陣列需要離散化!所以,由許多元素共同影響下,歸併排序求逆序對 比 樹狀陣列求逆序對 歸併排序 include define ll long long define n 100005 using namespace std int a n t...

求逆序對 樹狀陣列 歸併排序模板

ps 但資料大的時候,需要離散化陣列會多乙個排序的複雜的,其實還不如歸併找逆序對塊 歸併找逆序對也是o n logn 樹狀陣列 include include include include include include includeusing namespace std const int i...

poj 2299(逆序對(樹狀陣列 歸併排序))

題目鏈結 題目大意 在這個問題中,你必須分析乙個特定的排序演算法。該演算法通過交換兩個相鄰的序列元素來處理n個不同整數的序列,直到序列按公升序排序。對於輸入序列 9 1 0 5 4,通過ultra quicksort輸出 0 1 4 5 9。你的任務是確定ultra quicksort需要執行多少交...