K th Number(尺取 二分)

2021-09-27 11:24:24 字數 1090 閱讀 4120

傳送門

釐清題意很重要,給你乙個序列a,再給出k,m,將a中每個區間的第k大元素放入b序列,問b序列的第m大元素是多少。

思路:可以想到一段序列的所有區間數是固定的,每個區間的第k大也都是固定的。假設b序列的第m大元素是x,則可知大於等於x的數有m個,即對於a序列的所有區間第k大,大於x的有m個。這裡就有乙個巧妙的滿足遞增性質的地方,即「區間的第k大 大於 mid 的區間數」,mid越大,這個數越小。因此我們採用二分的方法嘗試mid,一旦找到大於mid的區間數為m個,此時的mid就是答案,mid要從a序列中選取,所以要先排個序。

二分的思路確定之後,要想著怎樣實現judge函式,這裡的方法同樣巧妙–尺取法。左端點為l,右端點為r,初始都為1,然後右端點向右掃瞄,遇到大於等於mid的數就num++,當num等於k時,說明[l,r]區間的第k大大於等於mid,這時可知道一共有n-r+1個區間滿足此條件,且均以l為左端點,這樣掃瞄下去只要o(n)複雜度即可。

關於尺取法的細節:如果num小於k,則右端點繼續擴充套件,如果num大於等於k,則計入答案,左端點擴充套件。若右端點為n且num小於k,則結束掃瞄

#include

#include

using

namespace std;

typedef

long

long ll;

const

int maxn =

1e5+5;

ll n, k, m;

ll a[maxn]

, b[maxn]

;ll judge

(ll x)

else

if(num >= k)

}return res;

}int

main()

sort

(b+1

, b+

1+n)

; ll l =

1, r = n;

ll ans =-1

;while

(l <= r)

else

} cout << ans << endl;

}return0;

}

尺取 二分查詢

尺取法 這是一種比較有趣的方法,想吃子一樣去解決問題。現在我只是知道了可以用陣列來模擬 尺子 加油學習!方法是 陣列模擬 二分查詢 說一 下資料的意思,10個數,從中找出和為15的最短子串。10 5 1 3 5 10 7 4 9 2 8 15 include using namespace std ...

HDU 6231 (二分 尺取)

所求的一定是a陣列中的原素,這點毋庸置疑,所以在a陣列中任意選則其中的乙個數x,若a的所有長度不小於k的連續子串行中第k大數不小於x的子串行一共有ans個,那麼x在所有第k大元素組成的數列中至少是第ans大數 因為ans n r,因為之前的x已經是第k大了,所以加上後面的元素,如果比他小,則沒有影響...

hdu 6231 二分 尺取

題意 給你乙個n個數的陣列,把這個陣列中長度大於等於k的區間中第k大的數取出來組成乙個新陣列,問你這個新陣列第m大是多少。可能有的人和我一樣沒去分開第k大和第k小的關係,比如陣列 1,2,3,4,5 第2大就是4,第2小就是2.思路 我們可以用尺取算出第k大大於等於x的區間個數有多少個。當我們了解這...