樹狀陣列 逆序類題目

2021-07-16 10:51:54 字數 1408 閱讀 5763

題意: 給出長度為n的序列,每次只能交換相鄰的兩個元素,問至少要交換幾次才使得該序列為遞增序列?

題解:其實就是求逆序對的數量。可以用樹狀陣列來求。雖然數的大小為 999,999,999,但是數的規模只有500,000,所以可以對資料進行離散化,之後就可以用樹狀陣列來求了。

**:#include #include #include #include using namespace std;

const int max=500000+5;

typedef long long ll;

int bit[max];

int a[max];

int tmp[max];

int n;

int sum(int x)

return sum;

}void add(int x,int value)

}int main()

cout<

題意:給定乙個序列,對該序列的n種排列(排列如下)的每種排列的逆序數求最大值:

a1, a2, ..., an-1, an  

a2, a3, ..., an, a1  

a3, a4, ..., an, a1, a2 

...  

an, a1, a2, ..., an-1 

題解:我們可以分為n步,每次都將第乙個元素移動到最後乙個,這樣原來的逆序對變為順序對,原來的順序對變為逆序對,所以逆序對減少的數量為(比他小的數的個數)減去(比他大的數的個數),即cnt-(n-1-cnt)=2*cnt-n+1,cnt為比當前數小的數,cnt可以用樹狀陣列求出,但是因為每次操作的都是第乙個數,並且數只有1-n,所以cnt就等於a[i]-1。cnt-(n-1-cnt)=2*cnt-n+1=2*a[i]-n-1。進行n步求出逆序對減少的數量的最大值用總的逆序對數減去這個值即可。

**:

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

const int max=5000+5;

const int inf=0x3f3f3f3f;

typedef long long ll;

int a[max];

int rs[max];

int bit[max];

int n;

int sum(int x)

return s;

}void add(int x,int v)

}int main()

{ int n;

while(scanf("%d",&n)!=eof)

{memset(bit,0,sizeof(bit));

n=n;

int tol=0;

for(int i=0;i

樹狀陣列求逆序對(逆序數)

逆序數 也叫逆序對 在乙個排列中,如果一對數的前後位置與大小順序相反,即前面的數大於後面的數,那麼它們就稱為乙個逆序。乙個排列中逆序的總數就稱為這個排列的逆序數。無重複的數 include include include include include include using namespace...

樹狀陣列 題目詳解

樹狀陣列直接搜狗百科就行 不行再去b站 巨佬寫的 includeusing namespace std const int maxn 1e5 int f maxn int n int lowbit int x void update int i,int x int query int n retur...

樹狀陣列求逆序數

逆序數就是數中各位在它前面有多少個數比它大,求出這些元素個數之和。今天看了個樹狀陣列,可以很好的解決這個問題,普通方法需要o n 2 複雜度,用樹狀陣列只需要o nlongn 樹狀陣列實際上還是乙個陣列,只不過它的每個元素儲存了跟原來陣列的一些元素相關的結合值。若a為原陣列,定義陣列c為樹狀陣列。c...