题目链接: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. cf682E Alyona and Triangles

    You are given n points with integer coordinates on the plane. Points are given in a way such that th ...

  2. Linux之VMware虚拟机取消DHCP

    1.点击编辑项 2.选择VMnet1  点击更改设置 3.选择VMnet1 去掉使用本地DHCP服务  点击应用 原文地址:https://blog.csdn.net/star_in_shy/arti ...

  3. MVC 上传文件的方法

    这两天又开始研究MVC了,期间断断续续已经搞了好久了,可是都没坚持下来.囧!这次一定坚持搞出来一个名堂. 废话少说,直接上代码. 前台引擎采用Razor @model System.Web.HttpP ...

  4. [C/C++] 结构体内存对齐用法

    一.为什么要内存对齐 经过内存对齐之后,CPU的内存访问速度大大提升; 内存空间按照byte划分,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内 ...

  5. (4)Swing布局

    一.FlowLayout-流布局 新增第一个组件后默认在第一行的居中位置,之后 组件按照加入的先后顺序按照设置的对齐方式从左向右排列 二.borderLayout-边框布局 容器划分为东.西.南.北. ...

  6. c++ 高效并发编程

    高效并发编程 并发编程的基本模型包括,通过消息机制来管理运行顺序的message passing, 通过互斥保护共享的shared memory. 线程同步的基本原则 最低限度共享变量,考虑使用imm ...

  7. python socket非阻塞及python队列Queue

    一. python非阻塞编程的settimeout与setblocking+select 原文:www.th7.cn/Program/Python/201406/214922.shtml 侧面认证Py ...

  8. Windows下部署多个Tomcat

    编辑bin/startup.bat SET JAVA_HOME=...(JDK所在路径) SET CATALINA_HOME=...(Tomcat解压的路径) 编辑server.xml文件 <! ...

  9. ActiveMQ消息的延时和定时投递

    ActiveMQ对消息延时和定时投递做了很好的支持,其内部启动Scheduled来对该功能支持,也提供了一个封装的消息类型:org.apache.activemq.ScheduledMessage,只 ...

  10. 64-bit Itanium与x64

    64-bit Itanium是什么意思 64-bit Itanium,指的是intel 安腾处理器,intel安腾处理器是Intel的某一代处理器,当然是在酷睿(即core)这一代之前出来的. ora ...