线性平面最近点对

news/2024/9/28 23:20:03

讲述一种期望线性复杂度的平面最近点对算法。

  1. 将点打乱
  2. 对于小常数 \(D\),暴力计算前 \(D\) 个点的平面最近点对。
  3. 考虑从前 \(i-1\) 个点推出前 \(i\) 个点的平面最近点对:
    • 设前 \(i-1\) 个点的平面最近点对距离为 \(s\),将平面以 \(s\) 为边长划分成若干网格,用哈希表记录每个网格内的点。
    • 检查第 \(i\) 个点所在的网格及其周围共 \(9\) 个网格内的点是否能更新答案,注意到检查的点的数量是 \(O(1)\) 的,因为每个网格最多有 \(4\) 个点。
    • 若答案更新,重构网格。前 \(i\) 个点的平面最近点对包含第 \(i\) 个点的概率为 \(O\left(\frac{1}{i}\right)\),重构网格的代价为 \(O(i)\),故每个点的期望代价为 \(O(1)\)

若给定的点有重,可能算法效率会减小,建议特判。

#include <algorithm>
#include <cmath>
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <random>
#include <unordered_map>
#include <utility>
#include <vector>
#define x first
#define y second
#define M 1000
using namespace std;int n;
double ans = HUGE_VAL;
vector<pair<int, int>> vec;
unordered_map<uint64_t, vector<pair<int, int>>> grid;inline uint64_t h(unsigned a, unsigned b) {return (uint64_t)a << 32 | (uint64_t)b;
}void gen() {static const int s0 = 290797, m = 50515093;int i = 1, last = s0, s;for (; (int)vec.size() < n; ++i, last = s) {s = (long long)last * last % m;if (i & 1)vec.push_back(make_pair(last + m, s + m));}
}void pre() {int m = min(n, M);for (int i = 0; i < m; ++i)for (int j = i + 1; j < m; ++j)ans = min(ans, hypot(vec[i].x - vec[j].x, vec[j].y - vec[i].y));
}void remake(int m) {grid.clear();for (int i = 0; i <= m; ++i) {int a = floor(vec[i].x / ceil(ans)), b = floor(vec[i].y / ceil(ans));grid[h(a, b)].push_back(make_pair(vec[i].x, vec[i].y));}
}bool has_same() {unordered_set<uint64_t> ust;for (auto &&[u, v] : vec) {uint64_t hs = mapping(u, v);if (!ust.insert(hs).second)return true;}return false;
}int main() {mt19937 rnd;rnd.seed(random_device()());ios::sync_with_stdio(false);cin.tie(0);cin >> n;for (int i = 0; i < n; ++i) {int a, b;cin >> a >> b;vec.push_back(make_pair(a, b));}if (has_same()) {ans = 0;goto jump;}shuffle(vec.begin(), vec.end(), rnd);prework();remake(min(n, M) - 1);for (int i = M; i < n; ++i) {int a = floor(vec[i].x / ceil(ans)), b = floor(vec[i].y / ceil(ans));double ret = ans;for (int dx = -1; dx <= 1; ++dx)for (int dy = -1; dy <= 1; ++dy) {int s = a + dx, t = b + dy;if (grid.count(h(s, t)) == 0)continue;for (auto &&[u, v] : grid[h(s, t)])ret = min(ret, hypot(vec[i].x - u, vec[i].y - v));}if (ret < ans)ans = ret, remake(i);elsegrid[h(a, b)].push_back(make_pair(vec[i].x, vec[i].y));}
jump:cout << fixed << setprecision(4) << ans << "\n";return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/65958.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

极客大挑战2023-pwn-nc_pwntools WriteUp

主要考查点 Pwntools工具的基本使用方法 解题思路 1.nc 连接题目,得到提示:根据题目,要求发送一个100长度的字符串,而且末尾需要为Syclover bA*92 + bSyclover 2.发送第一个请求后进入第二步要求短时间内计算一个复杂算式,自己算是肯定不可能的,所以pwntools的recv来接收…

PbootCMS后台访问地址及默认帐号密码

如果你在使用PbootCMS时遇到关于后台默认账号密码的问题,以下是一些关键信息: PbootCMS 后台默认访问路径访问路径:你的域名/admin.php将“你的域名”替换为实际的网址。后台初始账号密码初始账号:admin 初始密码:admin示例 假设你的域名为 example.com,则后台访问路径为…

docker 创建私有仓库,并且设置用户名和密码

1. 拉取仓库 docker pull registry2. 安装密码生成工具 sudo apt-get install apache2-utils3. 生成用户名和密码 htpasswd -Bc /etc/docker/registry/passwords dzq4. 启动仓库docker run -d -p 5000:5000 --restart=always --name registry \-e REGISTRY_AUTH=htpasswd…

PbootCMS简单安装教程 – pbootcms基本使用教程

为了帮助用户顺利安装并使用PbootCMS系统,以下是详细的安装步骤和注意事项: 1. 环境要求PHP版本:PbootCMS系统默认采用SQLite数据库,需要PHP 5.4及以上版本,最新系统需要PHP 7.0及以上版本。 服务器环境:确保服务器环境正确配置,使用PHP环境。2. 安装前的准备环境配置:…

pbootcms目录结构解释说明及权限设置

为了确保PbootCMS能够正常运行,需要对一些关键目录设置正确的权限。以下是具体的目录权限设置说明: 1. 数据库目录 (data) 可写路径:/data 权限:755 或 777 命令:bashchmod 755 /path/to/pbootcms/data2. 运行时目录 (runtime) 及子目录可写路径:/runtime 权限:755 或 7…

pbootcms二次开发必须要了解的后台目录结构

下面是PbootCMS后台目录结构的整理表格,方便二次开发人员参考:目录 描述apps 应用目录 admin 后台应用 api API接口应用 common 公共目录 home 前台应用config 配置目录 config.php 系统配置文件 database.php 数据库配置文件 route.php 自定义路由配置…

pbootcms模板 后台升级程序后导致网站打不开 Parse error: syntax error, unexpec

当你在升级PbootCMS模板后台后遇到网站打不开的问题,并且出现如下错误: Parse error: syntax error, unexpected :, expecting { in /www/wwwroot/****/core/function/helper.php on line 745这通常是因为PHP版本不兼容导致的。PbootCMS 3.2版本要求PHP 7及以上版本。以下是具…

小模型(SLM)的效率、性能和潜力

关于小语言模型 小语言模型(slm)是为在桌面、智能手机和可穿戴设备上进行资源高效部署而设计的。 其目标是使先进的机器智能能够为每个人所使用和负担得起,就像人类认知的普遍性一样。 小语言模型(slm)已经广泛集成到商业设备中。例如,最新的谷歌和三星智能手机内置了大型语言…