https://yukicoder.me/problems/no/817
前提知識
解説
https://yukicoder.me/submissions/340743
N回操作して、手元にある硬貨を昇順ソートしたときのK番目はなにかという問題。
二分探索の典型テクとして、
【「ある条件でソートしたときのK番目の数を求めよ」というのは、答えの数で二分探索する】
があるので、これを適用しよう。
以下の関数を判定関数とする。
check(x) := x円以下の硬貨の枚数がK枚以上あるか
これで境界線を探したときのng, okのうち、okが答えになる。
check関数では、各操作について、x以下の枚数を足していき、総和がK以上かを判定する。
int N, K, A[101010], B[101010]; //--------------------------------------------------------------------------------------------------- int check(int x) { ll cnt = 0; rep(i, 0, N) { if (A[i] <= x) { cnt += min(B[i], x) - A[i] + 1; } } return K <= cnt; } //--------------------------------------------------------------------------------------------------- void _main() { cin >> N >> K; rep(i, 0, N) cin >> A[i] >> B[i]; int ng = 0, ok = inf; while (ng + 1 != ok) { int md = (ng + ok) / 2; if (check(md)) ok = md; else ng = md; } cout << ok << endl; }