POJ 3685

Matrix
Time Limit: 6000MS   Memory Limit: 65536K
Total Submissions: 4428   Accepted: 1102

Description

Given a N × N matrix A, whose element in the i-th row and j-th column Aij is an number that equals i2 + 100000 × i + j2 - 100000 × j + i × j, you are to find the M-th smallest element in the matrix.

Input

The first line of input is the number of test case.
For each test case there is only one line contains two integers, N(1 ≤ N ≤ 50,000) and M(1 ≤ M ≤ N × N). There is a blank line before each test case.

Output

For each test case output the answer on a single line.

Sample Input

12

1 1

2 1

2 2

2 3

2 4

3 1

3 2

3 8

3 9

5 1

5 25

5 10

Sample Output

3
-99993
3
12
100007
-199987
-99993
100019
200013
-399969
400031
-99939

Source

 
首先二分第m小的数,由公式易得每列的数是按照从小到大排列的,因此可二分,两次二分即可。
 
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 
 6 using namespace std;
 7 
 8 typedef long long ll;
 9 
10 int n;
11 ll m;
12 
13 ll cal(ll i,ll j) {
14         return i * i + j * j + (i - j) * 100000 + i * j;
15 }
16 
17 bool judge(ll x) {
18         ll sum = 0;
19         for(int j = 1; j <= n; ++j) {
20                 int l = 0,r = n;
21                 while(l < r){
22                         int mid = (l + r + 1) / 2;
23                         if(cal(mid,j) <= x) {
24                                 l = mid;
25                         } else {
26                                 r = mid - 1;
27                         }
28                 }
29                 sum += l;
30         }
31 
32         return sum >= m;
33 
34 }
35 
36 void solve() {
37         ll l = -1e12,r = 1e12;
38 
39         //printf(" n = %d l = %lld r = %lld\n",n,l,r);
40 
41         while(l < r) {
42                 ll mid = (l + r) >> 1;
43                 if(judge(mid)) r = mid;
44                 else l = mid + 1;
45         }
46 
47 
48 
49       printf("%I64d\n",l);
50 }
51 
52 int main() {
53        // freopen("sw.in","r",stdin);
54 
55         int t;
56         scanf("%d",&t);
57 
58         while(t--) {
59                 scanf("%d%I64d",&n,&m);
60                 solve();
61         }
62 
63         return 0;
64 }
View Code

 

posted @ 2014-03-19 20:05  hyx1  阅读(402)  评论(0编辑  收藏  举报