給定乙個長度為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 表示數字的...