關於逆序對的題目練習

2021-10-06 21:41:42 字數 3591 閱讀 2651

傳送門

用線段樹寫。快讀+o

2o_2

o2​優化才能卡過去。

#include

using

namespace std;

typedef

long

long ll;

const

int n=

5e5+5;

#define mst(a) memset(a,0,sizeof a)

#define lx x<<1

#define rx x<<1|1

#define reg register

struct nodea[n<<2]

;inline

void

read

(int

&x)voidre(

int x)

void

build

(int x,

int l,

int r)

inline

intquery

(int x,

int l,

int r)

inline

void

update

(int x,

int l,

int r,

int val)

int mid=

(l+r)

>>1;

if(val<=mid)

update

(lx,l,mid,val)

;else

update

(rx,mid+

1,r,val);re

(x);

}int n,num[n]

,b[n]

;int

main()

printf

("%lld\n"

,ans)

;return0;

}

傳送門

題意:給定由0∼n

−1

0\sim n-1

0∼n−1共n

nn個數組成的排列,每次將第乙個數放入序列尾後生成新的排列。求這n

nn個排列的最小逆序數。

思路:只需求出初始序列的逆序對數,其他用遞推即可。

因為0 ∼n

−1

0\sim n-1

0∼n−

1都包含了,所以對於元素x

xx放入序列尾,ans

afte

r=an

sbef

ore+

(n−1

−x)−

xans_=ans_+(n-1-x)-x

ansaft

er​=

ansb

efor

e​+(

n−1−

x)−x

因為比x

xx大的元素有n−1

−x

n-1-x

n−1−

x個。逆序對增加n−1

−x

n-1-x

n−1−

x個,比x

xx小的元素有x

xx個(因為是從0開始的). 所以可以直接o(1

)o(1)

o(1)

求其他序列逆序對數。

#include

using

namespace std;

typedef

long

long ll;

const

int n=

5e3+5;

#define mst(a) memset(a,0,sizeof a)

#define lx x<<1

#define rx x<<1|1

struct nodea[n<<2]

;voidre(

int x)

void

build

(int x,

int l,

int r)

intquery

(int x,

int l,

int r)

void

update

(int x,

int l,

int r,

int val)

int mid=

(l+r)

>>1;

if(val<=mid)

update

(lx,l,mid,val)

;else

update

(rx,mid+

1,r,val);re

(x);

}int n,b[n]

;int

main()

int ans=sum;

for(

int i=

1;i) sum+

=n-b[i]

-b[i]-1

,ans=

min(ans,sum)

;//遞推.

printf

("%d\n"

,ans);}

return0;

}

傳送門

思路:求序列逆序對數。由於資料較大,且不是連續的,所以需要離散化處理一下。用權值線段樹一邊讀,一遍加即可 。

#include

using

namespace std;

typedef

long

long ll;

const

int n=

5e5+5;

#define mst(a) memset(a,0,sizeof a)

#define lx x<<1

#define rx x<<1|1

#define reg register

struct nodea[n<<2]

;inline

void

read

(int

&x)voidre(

int x)

void

build

(int x,

int l,

int r)

inline

intquery

(int x,

int l,

int r)

inline

void

update

(int x,

int l,

int r,

int val)

int mid=

(l+r)

>>1;

if(val<=mid)

update

(lx,l,mid,val)

;else

update

(rx,mid+

1,r,val);re

(x);

}int n,num[n]

,b[n]

;int

main()

printf

("%lld\n"

,ans);}

return0;

}

演算法練習 逆序對

逆序對問題算是很經典了,最簡單的暴力破解時間複雜度o n2 時間複雜度大於o n2 的演算法是非常糟糕了,所以我們採用歸併排序的演算法改動一下,即可獲得o nlogn 的演算法。逆序對定義 數列中如果 i j arr i arr j 則arr i 和arr j 為一對逆序對。逆序對個數 privat...

九度 題目1348 陣列中的逆序對

時間限制 1 秒 記憶體限制 32 兆 特殊判題 否 提交 1569 解決 348 題目描述 在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數。輸入 每個測試案例包括兩行 第一行包含乙個整數n,表示陣列中的元素個數。其中1 n...

關於多執行緒練習的幾個題目

第一題 現有的程式 模擬產生了16個日誌物件,並且需要執行16秒才能列印完這些日誌,請在程式中增加4個執行緒去呼叫parselog 方法來分頭列印這16個日誌物件,程式只需要執行4秒即可列印完這些日誌物件。原始 如下 交給四個執行緒,列印16個日誌物件資訊,啟動四個執行緒容易,但是怎樣將這16個日誌...