hdu1394 線段樹求逆序數

2021-10-19 17:46:28 字數 1204 閱讀 8973

題意

給出一串數字a,可以進行如下操作:將該串數字第乙個數字a0放到該串數字的最後位置,形成新的數字串,求操作過程中最小逆序數。

思路1)求一串數字的逆序數:

暴力法:對每乙個數字x,判斷x與x之前出現了多少個比x大的數字。複雜度為o(nn).

利用線段樹:因為數字串出現的數字只能在區間0~n,可以利用線段樹對出現的數字進行統計。對每個x,查詢區間 [x+1,n-1] 已經有多少個被計數的數字,它們的合計就是逆序數。

2)用初始的逆序數推到移動第乙個數到最後之後的逆序數

設初始逆序數為sum,

若去掉第乙個數m,那麼逆序數減少:m,

把m放到後面,逆序數增加:n - 1 - m,

所以:sum = sum - m + n - 1 - m = sum - 2m + n - 1。

ac**:

#include

#include

#include

#include

#include

#include

using

namespace std;

const

int maxn =

5e3+3;

int tree[maxn<<2]

;//最底層的葉子節點對應0~n-1相應數字,每次輸入乙個數字,就要計數

#define lson l, mid, rt<<1

#define rson mid+1, r, rt<<1|1

void

build

(int l,

int r,

int rt)

void

update

(int val,

int l,

int r,

int rt)

//val對應的葉節點以及區間加一。

intquery

(int l,

int r,

int l,

int r,

int rt)

//查詢對應區間的計數

intmain()

int ans = sum;

for(

int i =

1; i < n; i++

)printf

("%d\n"

, ans);}

return0;

}

hdu 1394 線段樹求逆序數

線段樹求逆序數 求小逆序數 神奇 題意 給定乙個序列,對該序列的n種排列 排列如下 的每種排列 0 n 1 的逆序數求最小值 a1,a2,an 1,an a2,a3,an,a1 a3,a4,an,a1,a2 an,a1,a2,an 1 思路 先求出初始序列的逆序數,可以歸併,這裡用的是線段數求。設當...

hdu1394線段樹求逆序數

這個吧,就是這麼回事。你把每乙個數都插在相應的點上。然後,query來計算a i 道n的插得點個數,因為你是按順序插得。先插的而且還在後面。那麼一定構成逆序數。然後用sum儲存一下。還有逆序數的計算第乙個數放到最後,比他小的有x 1個,比他大的有n x個。然後給移到後面,逆序數增加n x 個,比x小...

hdu 1394 求逆序數(線段樹求)

題意描述 給你乙個有0 n 1數字組成的序列,然後進行這樣的操作,每次將最前面乙個元素放到最後面去會得到乙個序列,那麼這樣就形成了n個序列,那麼每個序列都有乙個逆序數,找出其中最小的乙個輸出!解析 求出a1,a2,an 1,an的逆序數之後,就可以遞推求出其他序列的逆序數。假設要把a1移動到an之後...