二分查詢 POJ3579 Median

2021-09-29 22:47:25 字數 1412 閱讀 5316

給定乙個長度為n的正整數序列a,現有a中的所有元素任意兩兩做差,形成乙個長度為cn2

c_n^2

cn2​

的序列b,求出b的中位數。

其中,1<=n<=1e5, 0直接求出這些差值、排列、選中位數,顯然會超時,其時間複雜度為o(n^2 log n^2),其中求值為o(n^2), 排列為o(m log m)。

二分查詢的框架中,查詢結果為符合check()條件的第乙個位置

while

(l

中位數的直觀定義為數列中最中間的數,準確定來說就是數列排序後位置在最中間(當n為奇數時,中間為n/2+1,;當n為偶數時,中間為n/2《題目中定義》),換言之,也就是說,大於中位數的數佔一半,小於中位數的數也佔一半。但這樣不夠精準,因為可能和中位數相等的數有很多個。準確定義,應該是

大於中位數的數應少於等於總數的一半

數列a

中位數mid

大於mid的數量

1 2 3* 4 53*2

1 2* 2 2 32*1

1 2* 2 3 42*2

1 2 3* 3 53*1

雖然最終找到的中位數的位置不一定為最中間的哪乙個,但並不影響。

鑑於以上分析,中位數可以通過二分查詢找出來,查詢區間為[0 , max_a - max_b +1)

接下來應該研究的是如何確定大於某個數dif的數量

若設當前需要檢驗的差值diff=xj-xi,那麼每次固定乙個xi,找到所有比xj大的x元素,也就是所有比(diff+xi)大的x元素,每找到乙個元素意味著找到了乙個比diff大的差值,當xi遍歷後就能找到所有比diff大的差值,判斷比diff大的差值個數是否少於等於m/2個,如果true。

#include

#include

#include

typedef

long

long ll;

using

namespace std;

const

int maxn=

1e5+10;

int n;

ll m;

int a[maxn]

;bool

check

(int dif)

intmain()

printf

("%d\n"

,l);

}return0;

}

POJ 3579 Median 二分 思維

給你一些數,然後求這些數相互之間差的絕對值,然後絕對值排序,找到中間那個數。我反正一直開始是沒有想到這個題竟然可以用二分來做。二分列舉答案,假設列舉值為mid,然後就是在排好序的序列中對每乙個num i 找到在i之後,有多少個大於num i mid的數的個數 數列裡的值比num i mid大,說明該...

Poj3579Median二分查詢第K大

題目鏈結 題目 給定一組數x ix i xi 我們可以得到c n 2 c n,2 c n,2 個差值 xi xj i x i x j i j xi x j i,問求這些差值組成的數列中第k kk個 k c n,2 2 k c n,2 2 k c n 2 2 是多少。思路比較常見的二分題目。首先對輸入...

POJ 3579 Median 尺取 二分

給n數字,x1,x2,xn,我們計算每對數字之間的差值 xi xj 1 i j n 我們能得到 c n,2 個差值,現在我們想得到這些差值之間的中位數。如果一共有m個差值且m是偶數,那麼我們規定中位數是第 m 2 小的差值。input輸入包含多測 每個測試點中,第一行有乙個nthen n 表示數字的...