逆序對(歸併排序)

2022-06-29 11:36:13 字數 1130 閱讀 8076

作為程式設計師的小q,他的數列和其他人的不太一樣,他有

個數。老闆問了小q一共 m次,每次給出乙個整數

, 要求小q把這些數每

分為一組,然後把每組進行翻轉,小q想知道每次操作後整個序列中的逆序對個數是多少呢?

輸入描述:

第一行乙個數
第二行

個數,表示初始的序列

第三行乙個數

第四行m個數表示

輸出描述:

m行每行乙個數表示答案。

輸入例子1:

2

2 1 4 3

41 2 0 2

輸出例子1:

066

0

例子說明1:

初始序列2 1 4 3

->

第一次:1 2 3 4 -> 逆序對數為0

->

第二次:4 3 2 1 -> 逆序對數為6

->

第三次:4 3 2 1 -> 逆序對數為6

->

第四次:1 2 3 4 -> 逆序對數為0

這道題目一眼看上去就是歸併排序,但是序列可以翻轉,我們就要想到逆序對的乙個特點:逆序對=總數-有序對。

我們先記錄每一層有多少個逆序對,並且可以發現乙個規律:上層數不受下層影響,但是下層數受到上層數影響,於是我們可以先預處理所有數的逆序對,每一次詢問只用改變下層數的值,然後統計求和,時間複雜度為o(n*2^n+nm)。

**如下:

#include typedef long long ll;

using namespace std;

const int maxn=(1<<20)+5;

ll n,nn,m,a[maxn],b[maxn],f[25],z[25],c[maxn];

void msort(ll a,ll l,ll r,ll d,ll g)

return 0;

}

逆序對 (歸併排序)

逆序對的nlogn方法,改進後的歸併排序 給定排列p,求排列的逆序對數量。p的長度 100000。要求o nlogn 定義歸併排序過程merge l,r merge l,r merge l,mid merge mid 1,r count l,mid,mid 1,r 只需要考慮左右兩段之間造成的逆序對...

歸併排序 逆序對

按照劉汝佳說的,歸併排序分三步 1.劃分問題,即把序列分成元素盡量相等的兩半 2.遞迴求解 3.合併子問題 其實就是把乙個序列不斷的二分,直到只有兩個元素的時候,然後排序,然後返回,再排序。先上 include using namespace std long long a 100005 t 100...

歸併排序(逆序對)

現在我們在競賽中最常用的排序是快速排序,c 只要乙個sort就搞定,但非常明顯,歸併排序的時間複雜度是最優的而且非常穩定,但是人們經常把它用在求逆序對個數上面。那麼下面我用乙個這樣的題來講一下歸併排序。點這裡看題目和樹狀陣列解法。歸併排序是將數列a l,h 分成兩半a l,mid 和a mid 1,...