關於區間中位數

2021-09-28 22:17:20 字數 1848 閱讀 4657

洛谷某討論

對於一串長度為n(n

<

=2000

)n(n<=2000)

n(n<=2

000)

的序列,對於所有的i,j

(1

<=i

<=n

,i

<=j

<=n

)i,j(1<=i<=n,i<=j<=n)

i,j(

1<=i

<=n

,i<=j

<=n

)區間,求出他們的中位數。

這個ider先在這裡佔坑吧,畢竟感覺這個思路挺好的。

我們可以一開始把整個序列排序,然後對排序後的陣列鍊錶化,並且求出每個點在鍊錶中的下標。

那麼對於固定的l

ll,我們的r

rr從大到小查詢,我們對於[l,

n]

[l,n]

[l,n

]暴力在鍊錶找中位數,然後對於[l,

n−1]

[l,n-1]

[l,n−1

]我們可以把n

nn在鍊錶中刪掉,然後看看中位數向左還是向右,這個是o(1

)o(1)

o(1)

的。然後我們可以o(1

)o(1)

o(1)

將[ l,

n]

[l,n]

[l,n

]的排序鍊錶推到[l+

1,n]

[l+1,n]

[l+1,n

]的排序鍊錶,不過我們需要拷貝陣列,為o(n

)o(n)

o(n)

,當然我朋友的**是遞迴實現,所以不用拷貝。

**來自hyy大神的,當然也是他最先提出這個問題。

注意:至於偶數的中位數,貌似這位神犇的**是取左邊的那個數字

#include

#include

using

namespace std;

const

int n=

2005

;int a[n]

,p[n]

,l[n]

,r[n]

,w[n]

;bool

cmp(

int x,

int y)

int f[n]

[n];

void

dfs(

int i,

int k,

bool bk,

int now)

else

int r1=r[l[j]

],l1=l[r[j]];

//tmp

r[l[j]

]=r[j]

;l[r[j]

]=l[j]

; f[i]

[k-1

]=a[p[now]];

dfs(i,k-

1,bk^

1,now/*目前中位數的位置*/);

r[l[j]

]=r1;l[r[j]

]=l1;}}

void

make

(int n)

else

r[l[j]

]=r[j]

;l[r[j]

]=l[j]

;bk^=1

/*奇偶性質*/

;//刪數

f[i+1]

[n]=a[p[now]];

dfs(i+

1,n,bk,now)

;//處理中位數}}

intmain()

return0;

}

區間中位數兩例

給定陣列 a 1,a 2,dots,a n hihocoder 1849 子陣列的中位數 中位數數定義為排序後第 floor 個數。中位數大於 k 等價於陣列中大於等於 k 的數超過一半。定義陣列 b 1,b 2,dots,b n begin b i begin 1,text,1,text.end ...

維護動態區間的中位數

依次讀入乙個整數序列,每當已經讀入的整數個數為奇數時,輸出已讀入的整數構成的序列的中位數。詳細內容 最樸素寫法,每到奇數時位將前面所有資料排序,找到中位數 每次sort是 o nlog n 一組資料需要sort frac 次,所以複雜度為 o n 2log n include include usi...

中位數的中位數

參照王曉東的演算法設計 中位數的中位數,即將一串數分成n段,求其排好序了的中間那個數,再把這些所有中位數再求一次中位數。for int i 0 i r p 4 5 i 找中位數的中位數,r p 4即上面所說的n 5 int x lineselect a,p,p r p 4 5,r p 4 10 線性...