二分答案法例题,用于练习二分答案的基本思想非常合适,包括了思维方式转换的内容(以前我们所做的一直是利用二分法求得数组元素对应指针之类,但是现在是直接对答案进行枚举)。

思路是:首先对输入数组进行排序,使得a,b两数组都相对有序。

接下来对每个数字进行二分枚举,之后,通过判断这个数组当前的排名来进行下一步的二分。

对于每个数字排名的方式通过对枚举每一个a数组中的位置来确定,之后二分对应的数组元素的位置得到,时间复杂度是NLOGN;

整个算法时间复杂度是NLOGNLOG(N*N)带入50000计算得到的值大概是两千六百万的样子,实际加上cin.sync_with_stdio(false);跑出来的结果大概是300毫秒的样子。。看上去51nod的服务器还是比较快的。事实上,因为输入数据量大,使用输入优化一定程度上有些奇妙的速度优势。但是其实不加这个优化大概时间在500毫秒,其实也是差不多的。

说实话当时再设计完这个代码的时候超级心虚。。。觉得随便那个常数没搞好就得玩炸了。。。。结果来看危险也许是挺危险,但是也还有一定的容错空间。

最初的再设计出来统计大于某元素数量的方式之后发现复杂度有点小爆炸。。。以至于对于进一步的爆炸设计有些心虚。。。。

当时提出的替代方案是首先从A中枚举在一个数字,让他满足A[K]*B[0]<TARGET&&A[K]*B[N-1]>TARGET

之后进行下一部枚举——找到一个B元素,使得A[k]*B[I]<TARGET&&A[K]*B[I+1]>TARGET

之后使用B[I]反推A[I]。但是发现只这种方法其实要正确实现复杂度反而比之前的方案复杂度更高,因为在反推这一步没法使用二分法——无法凭空确定是哪个A[k]正好能满足要求,也同时无法确定B[I]先去的正确性。。。。于是,GG。

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1105

下面是代码:

 #include<bits/stdc++.h>
using namespace std;
const long long MAXN=;
long long a[MAXN];
long long b[MAXN];
long long n,k;
void init()
{
cin>>n>>k;
for(int i=;i<n;++i)
{
cin>>a[i]>>b[i];
}
sort(a,a+n);
sort(b,b+n);
}
long long calculate(long long key)
{
long long ret=;
for(int i=;i<n;++i)
{
long long tar=key/a[i];
if(tar*a[i]!=key)tar++;
long long pos=lower_bound(b,b+n,tar)-b;
ret+=pos;
}return ret;
}
long long step(long long a,long long b,long long target)
{
if(a==b-)return a;
long long mid=(a+b)/;
long long res=calculate(mid);
if(res<=target)return step(mid,b,target);
else return step(a,mid,target); }
int main()
{
cin.sync_with_stdio(false);
init();
cout<<step(a[]*b[],a[n-]*b[n-]+,n*n-k);
return ;
}

代码其实很好写。。。但是因为没带电脑等等原因,这份代码差不多是大的第四遍了。。。。。。

另外就是发现了一点,加了输入优化反而更慢了,下面是加了输入优化的AC代码:

#include<bits/stdc++.h>
using namespace std;
const long long MAXN=;
long long a[MAXN];
long long b[MAXN];
long long n,k;
void read_(long long &ret)
{
ret=;
char c=;
while((c<''||c>''))c=getchar();
while(c>=''&&c<='')ret*=,ret+=c-'',c=getchar();
}
void init()
{
// cin>>n>>k;
read_(n);
read_(k);
for(int i=;i<n;++i)
{
// cin>>a[i]>>b[i];
read_(a[i]);
read_(b[i]);
}
sort(a,a+n);
sort(b,b+n);
} long long calculate(long long key)
{
long long ret=;
for(int i=;i<n;++i)
{
long long tar=key/a[i];
if(tar*a[i]!=key)tar++;
long long pos=lower_bound(b,b+n,tar)-b;
ret+=pos;
}return ret;
}
long long step(long long a,long long b,long long target)
{
if(a==b-)return a;
long long mid=(a+b)/;
long long res=calculate(mid);
if(res<=target)return step(mid,b,target);
else return step(a,mid,target); }
int main()
{
cin.sync_with_stdio(false);
init();
cout<<step(a[]*b[],a[n-]*b[n-]+,n*n-k);
return ;
}

51nod 1105 二分答案法标准题目的更多相关文章

  1. 51nod 1105 二分好题

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1105 1105 第K大的数 基准时间限制:1 秒 空间限制:131072 ...

  2. 51nod 1799 二分答案(分块打表)

    首先题目等价于求出满足运行二分程序后最后r=k的排列种数. 显然对于这样的二分程序,起作用的只有mid点,mid处的值决定了接下来要递归的子区间. 于是可以一遍二分求出有多少个mid点处的值<= ...

  3. 51NOD 1128正整数分组V2 二分答案

    这道题是典型的二分答案法.但是首先难道这道题的时候我进行了一系列的思考,甚至联想到了之前多校中类似于树状划分的问题...原因是大家都包括N各节点K个输入.. 实际上最开始联想到了应当使用二分法“枚举” ...

  4. 【二分答案】 【POJ3497】 【Northwestern Europe 2007】 Assemble 组装电脑

    Assemble Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3171   Accepted: 1013 Descript ...

  5. POJ 2723 Get Luffy Out(2-SAT+二分答案)

    Get Luffy Out Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8851   Accepted: 3441 Des ...

  6. 51nod 1105 第K大的数 【双重二分/二分套二分/两数组任意乘积后第K大数】

    1105 第K大的数  基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题  收藏  关注 数组A和数组B,里面都有n个整数.数组C共有n^2个整数,分别是A[0] * ...

  7. POJ 3273-Monthly Expense 求分组和的最小的最大值【二分答案】

    题目链接:http://poj.org/problem?id=3273 题目大意:给出一个有n个数据的数组,将其分为连续的m份,找到一种分法,是的m份中最大一份总和最小 解题思路: 直接在答案的区间内 ...

  8. LibreOJ #2006. 「SCOI2015」小凸玩矩阵 二分答案+二分匹配

    #2006. 「SCOI2015」小凸玩矩阵 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

  9. 洛谷P2801 教主的魔法 [分块,二分答案]

    题目传送门 教主的魔法 题目描述 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.…….N. ...

随机推荐

  1. H5移动端原生长按事件

    // 函数名longpress// 参数为: 需长按元素的id.长按之后处理函数func function longPress(id, func,timeout=500) { var timeOutE ...

  2. java+elipse安装及部分问题

    1. elipse下载.安装.jdk环境配置教程: https://www.cnblogs.com/ForestDeer/p/6647402.html 2.eclipse使用教程: https://j ...

  3. hibernate课程 初探单表映射2-4 transaction简介

    1 hibernate是非自动提交.如果transaction不写的话,会只创建表结构而不插入语句.   如果不写transaction而想实现插入的功能的话,需要重写session的dowork方法 ...

  4. 学习笔记:MDN的Web入门

    HTML: 要引用一个父目录的文件,加上两个点. HTML并不是真正的编程语言,它是一种用于定义内容结构的标记语言. 元素(Element):开标签.闭标签与内容相结合,便是一个完整的元素.元素可以用 ...

  5. cf314E. Sereja and Squares(dp)

    题意 题目链接 给你一个擦去了部分左括号和全部右括号的括号序列,括号有25种,用除x之外的小写字母a~z表示.求有多少种合法的括号序列.答案对4294967296取模.合法序列不能相交,如()[],( ...

  6. redis空间键详解

    前言 redis的空间键通知是在2.8.0版本以后加入的,客户端通过发布订阅的方式,订阅某个频道,接收通过某种方式影响redis中数据的事件. 目录: 1.空间键事件分类 2.如何启用redis的空间 ...

  7. 使用kvm制作Eucalyptus镜像(CentOS 6.5为例)

    1.前言 Elastic Utility Computing Architecture for Linking Your Programs To Useful Systems (Eucalyptus) ...

  8. amap -bq 192.168.5.9 80 3306

    amap -bq 192.168.5.9 80 3306 查看运行在指定端口上运行的服务

  9. GitLab-CE-8.9.4 (OpenLogic CentOS 7.2)

    平台: CentOS 类型: 虚拟机镜像 软件包: gitlab-8.9.4 bug tracking collaboration commercial development devops git ...

  10. SVN和Git的区别

    这个地方就简单介绍一下 svn 的模式是: 1.写代码. 2.从服务器拉回服务器的当前版本库,并解决服务器版本库与本地代码的冲突. 3.将本地代码提交到服务器. Git分布式版本管理的模式是: 1.写 ...