题目链接:http://poj.org/problem?id=3685

Matrix
Time Limit: 6000MS   Memory Limit: 65536K
Total Submissions: 7378   Accepted: 2187

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

 
 
 
题解:
1.二分这个数mid,然后计算有多少对(i,j),使得F= i^2 + 100000 × i + j^2 - 100000 × j + i × j <= mid。如果符合,则缩小mid,否则增大mid。
2.问:怎么计算有多少对(i,j)使得 F <= mid 呢?
答:根据观察,式子“F =  i^2 + 100000 × i + j^2 - 100000 × j + i × j”为二元二次方程,当i确定时,F就成了关于j的一元二次方程。所以枚举i,然后计算 有多少个整数j,使得 F = j^2 + (i-1e5)*j + i^2 + i*1e5 - mid <= 0。根据高中的知识,我们需要求解出函数F的两个零点x1和x2(1<=x1<=x2<=n),然后再从区间[x1,x2]取出整数,即得到了满足约束的多对(i,j)。
 
 
 
正确代码:(求最小的数,使得小于等于它的数的个数>=m。即为题目所求)
 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
#define ms(a,b) memset((a),(b),sizeof((a)))
using namespace std;
typedef long long LL;
const double EPS = 1e-;
const int INF = 2e9;
const LL LNF = 2e18;
const int MAXN = 1e3+; LL n, m; bool test(LL tmp)
{
LL sum = ;
for(LL i = ; i<=n; i++) //枚举i。当i已确定时, 剩下的式子就是关于j的一元二次方程。求解两个根。
{
LL a = , b = i-, c = 1LL*i*i+1LL*i*-tmp;
if(1LL*b*b-4LL*a*c<) continue; //无实数根时, 下一个i
LL x1 = max( 1LL, (LL)ceil((-b-sqrt(1LL*b*b-4LL*a*c))/(*a)) ); //左根向上取整,最小只能为1。
LL x2 = min( 1LL*n, (LL)floor((-b+sqrt(1LL*b*b-4LL*a*c))/(*a)) ); //右根向下取整,最大只能为n
sum += max( 0LL, x2-x1+ ); //区间内有多少个整数
}
return sum>=m;
} int main()
{
int T;
scanf("%d", &T);
while(T--)
{
scanf("%lld%lld", &n, &m);
LL l = -2e10, r = 2e10;
while(l<=r) //二分答案
{
LL mid = (l+r)>>;
if(test(mid))
r = mid - ;
else
l = mid + ;
}
printf("%lld\n", l);
}
}

错误代码:(求最大的数,使得小于它的数的个数<m。为题目所求的上一个数)

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
#define ms(a,b) memset((a),(b),sizeof((a)))
using namespace std;
typedef long long LL;
const double EPS = 1e-;
const int INF = 2e9;
const LL LNF = 2e18;
const int MAXN = 1e3+; LL n, m; bool test(LL tmp)
{
LL sum = ;
for(LL i = ; i<=n; i++) //枚举i。当i已确定时, 剩下的式子就是关于j的一元二次方程。求解两个根。
{
LL a = , b = i-, c = 1LL*i*i+1LL*i*-tmp;
if(1LL*b*b-4LL*a*c<=) continue;
LL x1 = max( 1LL, (LL)ceil((-b-sqrt(1LL*b*b-4LL*a*c))/(*a)) ); //左根向上取整,最小只能为1。
LL x2 = min( 1LL*n, (LL)floor((-b+sqrt(1LL*b*b-4LL*a*c))/(*a)) ); //右根向下取整,最大只能为n
sum += max( 0LL, x2-x1+ ); //区间内有多少个整数
}
return sum<m;
} int main()
{
int T;
scanf("%d", &T);
while(T--)
{
scanf("%lld%lld", &n, &m);
LL l = -2e10, r = 2e10;
while(l<=r) //二分答案
{
LL mid = (l+r)>>;
if(test(mid))
l = mid + ;
else
r = mid - ;
}
printf("%lld\n", r);
}
}

POJ3685 Matrix —— 二分的更多相关文章

  1. POJ3685 Matrix(嵌套二分)

    同行元素递减,同列元素递增,采用嵌套二分的方法 #include<cstdio> #include<iostream> #include<cstdlib> #inc ...

  2. Codeforces 549H. Degenerate Matrix 二分

    二分绝对值,推断是否存在对应的矩阵 H. Degenerate Matrix time limit per test 1 second memory limit per test 256 megaby ...

  3. POJ 3685 Matrix 二分 函数单调性 难度:2

      Memory Limit: 65536K Total Submissions: 4637   Accepted: 1180 Description Given a N × N matrix A, ...

  4. POJ 3685 Matrix (二分套二分)

    Matrix Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 8674   Accepted: 2634 Descriptio ...

  5. Matrix (二分套二分

    Given a N × N matrix A, whose element in the i-th row and j-th column Aij is an number that equals i ...

  6. poj 3685 Matrix 二分套二分 经典题型

    Matrix Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 5724   Accepted: 1606 Descriptio ...

  7. POJ 3685:Matrix 二分

    Matrix Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 5489   Accepted: 1511 Descriptio ...

  8. 74. Search a 2D Matrix(二分查找,剑指offer 1)

    Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the follo ...

  9. hdu 2119 Matrix(二分匹配)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2119 Matrix Time Limit: 5000/1000 MS (Java/Others)    ...

随机推荐

  1. SpringBoot消失的Web.xml

    Filter 过滤器作为web.xml中重要的一部分,有着相当高的出场率,SpringBoot会默认注册几个Filter ApplicationContextHeaderFilter Characte ...

  2. Python 可变对象与不可变对象

    1. 不可变(immutable):int.字符串(string).float.(数值型number).元组(tuple) 可变(mutable):字典型(dictionary).列表型(list) ...

  3. 如何新建.htaccess文件

    如何新建.htaccess文件 (1)新建文本文档,即txt文件: (2)把重写代码写进去: (3)然后选择[另存为],命名为.htaccess即可.

  4. yii 之数据库关联查询

    <?php namespace app\controllers; use yii\web\Controller; use app\models\Customer; class CustomerC ...

  5. laravel控制器

    //访问MemberController下的info的方法 //方法一//访问路径http://localhost/Laravel/public/member/infoRoute::get('memb ...

  6. IOC基本理解

    什么是IOC? IOC全称为控制反转(Inversion Of Control),别名依赖注入(Dependency Injection). 控制反转即指我们获取依赖的方式发生了反转. 假设存在如下情 ...

  7. python decode unicode encode

    字符串在Python内部的表示是unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码,即先将其他编码的字符串解码(decode)成unicode,再从unicode编码(en ...

  8. 创建ROS工作空间和包

    一.创建工作空间 mkdir -p ~/openni_ws/src cd ~/openni_ws catkin_make        //在catkin工作空间(openni_ws)下catkin_ ...

  9. codeforces #472(div 1)

    B(two point) 题意: 给出长度为n的非递减数组E[1..n],对于所有三元组(i,j,k),1<=i<j<k<=n且Ek-Ei<=U,我们需要计算出最大的(E ...

  10. Java开发笔记(一百零一)通过加解锁避免资源冲突

    前面介绍了如何通过线程同步来避免多线程并发的资源冲突问题,然而添加synchronized的方式只在简单场合够用,在一些高级场合就暴露出它的局限性,包括但不限于下列几点:1.synchronized必 ...