Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
二分好题。。。贴Java代码。带注释//注意到整个表中无论横竖,总是单调的。 //所以可以利用二重二分,时间复杂度 O(n*(log n)^2) //第二重二分选择行或者列来进行都可以。请注意列是递增,行是递减 import java.util.*; public class Main{ static int N; static long M; public static void main(String[] args) { Scanner s = new Scanner(System.in); int T = s.nextInt(); while(T-->0){ N = s.nextInt(); M = s.nextLong(); // 设定第一重二分的上下界 long l = -25000000001l; long r = 25000000001l; while(r-l>1){ long m = (l+r)/2; // 检验该m是否符合条件 if(check(m)){ r = m; }else{ l = m; } } System.out.println(r); } } private static boolean check(long m) { // 计算各列中共有多少个值小于等于m,并加在一起 // 然后判断该总数与M的大小关系 long count = 0; for(int i = 1; i <= N;i++){ // 对表格中的每列进行一次二分,找出该列有多少个数小于等于m并加入count // 也就是说每进行一次第一重二分,都要进行N次第二重二分 count += binary(i,m); } if(count >= M){ return true; }else{ return false; } } private static long binary(long i, long m) { // 对表格中的每列进行一次二分,找出该列有多少个数小于等于m long lb = 0; long rb = N+1; while(rb - lb > 1){ long mb = (lb+rb)/2; long ji = mb*mb + i*i + 100000*mb - 100000*i + mb*i; if(ji <= m){ lb = mb; }else{ rb = mb; } } // 返回该行小于等于m的数的个数 return lb; } } Followed by:
Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator