タイトル効果: N * Nの行列、A [I] [J] = I * I + I + J * 100000 * 100000 * J-I J + J *は、Kは小行列を見つけます。
N <= 5 * 10 ^ 4
ソリューション:
テーブルを作成し、単調から各列の増加をダウンしました。
バイナリサーチの広い範囲で、次に小さいk個のX、およびなどの前半は、x行列HAVEの数よりも少ない数の半分を検索します。
コード:
書式#include <iostreamの> の#include <cstdioを> する#include <CStringの> の#include <アルゴリズム> に#define LL長い長い 使って 名前空間はstdを、 int型T; LL N、M。 LL CAL(LLのX、LLのY) { リターン X * X + 100000 * X + Y * Y- 100000 * Y + X * Y。 } LLのslove(LLのX) { LL JS = 0 。 以下のために(INT iが= 1 ; I <= N; I ++ ) { int型 CNT = 0 ; INT LL = 1、RR = N。 一方、(LL <= RR) { INT MMID =(LL + RR)>> 1 。 もし(CAL(MMID、I)<= X)CNT = MMID、LL = MMID + 1 。 他の RR = mmid- 1 。 } JS = JS + CNT。 } リターンJS。 } int型のmain() { scanf関数(" %のD "、&T)。 しばらく(T-- ) { scanf関数(" %LLD%LLD "、&N、&M)。 LLのANS、L = - (1E12)、R = 1E12。 一方、(L <= r)と { LLミッド =(L + R)>> 1 。 もし(slove(MID)> = M)ANS =中間、R =半ば1 。 他リットル=ミッド+ 1 ; } coutの << ANS << てendl; } リターン 0 ; }