题目链接:

https://cn.vjudge.net/problem/POJ-3579

题目大意:

求的是一列数所有相互之间差值的序列的最中间的值是多少。

解题思路:

可以用二分套二分的方法求解第m大,和POJ-3685类似,这里的模板也差不多

枚举第m大x,判断小于等于x的数目是不是大于m,如果大于m说明x >= 第m大,调整区间r = mid - 1

不然l = mid + 1

此处是大于m而不是小于m是因为一个数可能出现多次,那么小于等于中间的数目可能就比m大

在计算小于等于x的数目的时候,用upperlower函数求解即可

一开始TLE是因为左右区间没选好,应该选给定的数字中的最大值减最小值作为右区间

 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long ll;
const ll INF = 1e9 + ;
const int maxn = 1e6 + ;
ll a[maxn], n, m; ll ok(ll mid)
{
ll ans = ;
for(int i = ; i < n; i++)//此处不等于n是由于到了n没有比它更大的了,加上=也无妨
{
if(a[i] + mid >= a[n])//可以加速一点
{
ans += n - i;
continue;
}
int t = upper_bound(a + i, a + n + , a[i] + mid) - a;//这里用区间a+i而不是a+1可以加速求解
ans += t - - i;
}
return ans;
}
int main()
{
while(scanf("%lld", &n) != EOF)
{
for(int i = ; i <= n; i++)scanf("%lld", &a[i]);
sort(a + , a + n + );
m = n * (n - ) / ;
m = (m + ) / ;//求出第m个
ll l = , r = a[n] - a[], ans;
while(l <= r)
{
ll mid = (l + r) / ;
if(ok(mid) >= m)//小于等于mid的数字个数 >= m 说明mid>=最优解
{
ans = mid;
r = mid - ;
}
else l = mid + ;
}
printf("%lld\n", ans);
}
return ;
}

最新文章

  1. 基于命令行编译打包phonegap for android应用 分类: Android Phonegap 2015-05-10 10:33 73人阅读 评论(0) 收藏
  2. 解决PHP大文件上传问题
  3. 算法与数据结构之交换(SWAP)排序
  4. C++内嵌汇编代码,简单文件加密
  5. Java 8 VM GC Tunning Guild Charter 9-b
  6. SQL练习之求解填字游戏
  7. php 将pdf转成图片且将图片拼接
  8. x86汇编语言实践(2)
  9. FX-玩列表
  10. 从函数式编程到Ramda函数库(二)
  11. Docker简单使用
  12. Setting Tomcat Heap Size (JVM Heap) in Eclipse
  13. [洛谷P1731][NOI1999]生日蛋糕(dfs)(剪枝)
  14. Redis的使用(待更新)
  15. 深度学习原理与框架-Tensorflow卷积神经网络-神经网络mnist分类
  16. springboot 整合redis redis工具类
  17. hive外部表删除遇到的一个坑
  18. python操作mysql数据库实现增删改查
  19. 5 -- Hibernate的基本用法 -- 要点
  20. linux Valgrind使用说明-内存泄漏

热门文章

  1. maven-javadoc-plugin
  2. Web API 解决跨域问题
  3. DP Intro - Tree DP
  4. (转)shell脚本之文件测试操作符及整数比较符
  5. Oracle 角色及其权限
  6. Git使用教程,感觉比较全,所以【转载】
  7. 小程序中搜索文件,阅览pdf,分享文件链接,评论表情符号
  8. 关于MySQLServer5.6配置问题
  9. c#中日期的处理
  10. .net使用redis入门笔记