题目链接: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. msp430项目编程56

    msp430综合项目---扩展项目六56 1.电路工作原理 2.代码(显示部分) 3.代码(功能实现) 4.项目总结

  2. AC日记——[SDOI2009]晨跑 bzoj 1877

    1877: [SDOI2009]晨跑 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 2131  Solved: 1142[Submit][Status][ ...

  3. 深入爬虫书scrapy 之json内容没有写入文本

    settings.py设置 ITEM_PIPELINES = { 'tets.pipelines.TetsPipeline': 300, } spider代码 xpath后缀添加.extract() ...

  4. MySql 初始化权限脚本

    刚装好MySql后无法用客户端工具连接,通过命令行登录后,运行下面的脚本: GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'     IDENTIFIED BY 'y ...

  5. Effective C++ Item 47 请使用 traits classes 表现类型信息

    本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:Traits classes 使得"类型相关信息"在编译期可用.它 ...

  6. CentOS安装Openfire服务

    原文::http://xiao987334176.blog.51cto.com/2202382/979677 系统是全新新安装的系统.版本号是Centos 5.6 x86 同步北京时间 # ntpda ...

  7. weexapp 开发流程(一)开发环境配置

    1.创建项目 weexpack create weexapp 2.安装必要插件 npm i jwt-simple vue-resource vue-router vuex vuex-router-sy ...

  8. C++写动态站点之HelloWorld!

    演示样例源码下载地址:Fetch_Platform.7z 更复杂的代码可參考本博客BBS的实现 简单的说.动态站点就是能够动态变更的站点.动态变化的内容通常来自后端数据库.例如以下省略万字(动态站点) ...

  9. 学习Android之第六个小程序新浪微博(二)(ListView和TabActivity)

    效果图例如以下: 选项卡的使用: 1.继承TabActivity 2.声明TabHost变量,通过方法getTabHost()获取并赋值. (TabHost  tabHost =getTabHost( ...

  10. Java学习之String StringBuffer StringBuilder区别

    1.String:对象长度是不可变的,是线程安全. 2.StringBuffer:对象长度是可变的,是线程安全. 3.StringBuilder:对象长度是可变,不是线程安全.