当前位置: 首页 > news >正文

二维数点问题2

二维数点问题

例题

给定二维平面上的 nnn 个点,第 iii 个点的位置用 (ai,bi)(a_i,b_i)(ai,bi) 描述,以及 qqq 次询问,每次询问给定 (x1,y1),(x2,y2)(x_1,y_1),(x_2,y_2)(x1,y1),(x2,y2) 表示一个矩形的左下角和右上角,求矩形内部(包含边界)有多少个点。

题解

问题等价于求有多少个点 (ai,bi)(a_i,b_i)(ai,bi) 同时满足 x1≤ai≤x2x_1\le a_i\le x_2x1aix2y1≤bi≤y2y_1\le b_i\le y_2y1biy2

对于 aia_iai 而言,它需要满足两个 偏序关系(大于等于和小于等于),所以先将这两个偏序关系变成一个,即满足 ai≤x2a_i\le x_2aix2 且满足 ai≥x1a_i\ge x_1aix1 的点的个数,等价于 满足 ai≤x2a_i\le x_2aix2 的点个数 减去 满足 ai≤x1−1a_i\le x_1-1aix11 的点的个数

此时,就可以将询问 (x1,y1,x2,y2)(x_1,y_1,x_2,y_2)(x1,y1,x2,y2) 拆分为 (x1−1,y1,y2)(x_1-1,y_1,y_2)(x11,y1,y2)(x2,y1,y2)(x_2,y_1,y_2)(x2,y1,y2),此后统一表示为 (pos,y1,y2)(pos,y_1,y_2)(pos,y1,y2)

那么就转化为求出有多少个点满足 ai≤posa_i\le posaiposy1≤bi≤y2y_1\le b_i\le y_2y1biy2

我们将所有的三元组 (pos,y1,y2)(pos,y_1,y_2)(pos,y1,y2)pospospos 从小到大排序,且将 点序列 中的点 (ai,bi)(a_i,b_i)(ai,bi)aia_iai 从小到大排序。

对于任意的 (pos,y1,y2)(pos,y_1,y_2)(pos,y1,y2) 可以 O(1)O(1)O(1) 求出 点序列 中最后一个的 aaa 值不大于 pospospos 的位置,此时我们只需要找到前缀序列中,有多少点的 bbb 值满足 y1≤b≤y2y_1\le b\le y_2y1by2

可以维护一个权值树状数组,每个点 (ai,bi)(a_i,b_i)(ai,bi) 只插入 bbb 值,然后进行区间查询即可。

现在已经求出了所有三元组 (pos,y1,y2)(pos,y_1,y_2)(pos,y1,y2) 的答案,问题在于如何组合为原来的询问?

维护一个结构体 nodenodenode,里面存的是三元组,以及三元组所属询问的下标,以及 符号

struct node {int x;int y1;int y2;int id;int op;
}

可以令查询 (x1,y1,x2,y2)(x_1,y_1,x_2,y_2)(x1,y1,x2,y2) 的一个三元组 (x1−1,y1,y2)(x_1-1,y_1,y_2)(x11,y1,y2) 的符号 opopop−1-11,另一个三元组符号是 111

我们计算出了答案,乘上三元组对应的符号并累加到答案数组即可。

还有一个关键的事情就是,这道题需要对 yyy 进行离散化。

#include <bits/stdc++.h>
using namespace std;
//#pragma GCC optimize(2)
#define int long long
#define endl '\n'
#define PII pair<int,int>
#define INF 1e18
const int N = 1e6 + 5;template<typename T>// 单点修改和区间查询的树状数组
struct Fenwick {vector <T> tree;int n;Fenwick(int _n) : n(_n), tree(_n + 2){}// 求 1~x 的前缀和T getsum(int x) {T ans = 0;int L = x;while (x) {ans += tree[x];x = x - lowbit(x);}return ans;}// 区间查询T get_range_sum(int l, int r) {return getsum(r) - getsum(l - 1);}// 单点修改void add(int x, T k) {while (x <= n) {tree[x] += k;x += lowbit(x);}}static inline int lowbit(int x) {return x & (-x);}
};struct node {int x;int y1;int y2;int id;int op;
};void slove () {int n, m;cin >> n >> m;vector <PII> point;vector <int> lsh;map <int, int> mp;for (int i = 1; i <= n; i++) {int x, y;cin >> x >> y;point.emplace_back(x, y);mp[y] = 1;}vector <node> Q;for (int i = 1; i <= m; i++) {int x1, y1, x2, y2;cin >> x1 >> y1 >> x2 >> y2;mp[y1] = 1; mp[y2] = 1;Q.push_back(node{x1 - 1, y1, y2, i, -1});Q.push_back(node{x2, y1, y2, i, 1});}// 离散化
// <----------------------------------------------------> //for (auto i : mp) lsh.emplace_back(i.first);for (int i = 0; i < lsh.size(); i++) mp[lsh[i]] = i + 1;for (int i = 0; i < n; i++) {point[i].second = mp[point[i].second];}for (int i = 0; i < 2*m; i++) {Q[i].y1 = mp[Q[i].y1];Q[i].y2 = mp[Q[i].y2];}
// <----------------------------------------------------> //sort (Q.begin(), Q.end(), [](node A, node B) {return A.x < B.x;});sort (point.begin(), point.end(), [](PII A, PII B) {return A.first < B.first;});vector <int> ans (m + 1);int L = 0, R = 0;Fenwick<int> tree(N);while (R < Q.size()) {while (L < point.size() && point[L].first <= Q[R].x) {tree.add(point[L].second, 1);L ++;}ans[Q[R].id] += Q[R].op * tree.get_range_sum(Q[R].y1, Q[R].y2);R ++;}for (int i = 1; i <= m; i++) cout << ans[i] << endl;
}signed main () {ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);slove();
}
http://www.dtcms.com/a/317017.html

相关文章:

  • 计算机视觉的四项基本任务辨析
  • HPE磁盘阵列管理01——MSA和SMU
  • OpenLayers学习(一)-基础
  • 赛灵思ZYNQ官方文档UG585自学翻译笔记:Quad-SPl Flash 闪存控制器
  • 《Python基础》第3期:使用PyCharm编写Hello World
  • 【力扣 Hot100】 刷题日记
  • linux定时器管理 timer_*系统调用及示例
  • LeetCode 112. 路径总和解题思路详解(BFS算法深入理解)
  • AI模型整合包上线!一键部署ComfyUI,2.19TB模型全解析
  • ES(Elasticsearch)进程掉线(节点脱离集群)问题
  • 协同过滤基础——基线预测器(Baseline Predictors)
  • 深入理解 Ext 系列文件系统:从磁盘物理到文件系统原理
  • QtPromise第三方库的介绍和使用
  • STM32学习笔记2-GPIO的输出模式
  • 宠智灵宠物AI大模型聚焦医疗核心场景,提升临床决策能力
  • Bilateral Reference for High-Resolution Dichotomous Image Segmentation
  • mmsegmentation·数据结构
  • 《零基础入门AI:传统机器学习进阶(从拟合概念到K-Means算法)》
  • 力扣刷题日常(15-16)
  • 深信服GO面试题及参考答案(下)
  • MCP与Function Calling
  • 三极管基本放大电路静态及动态参数计算
  • 【C++】类和对象2
  • nfs(网络文件系统)+autofs(自动挂载服务)
  • 创维智能融合终端DT741_移动版_S905L3芯片_安卓9_线刷固件包
  • I6328A 蓝牙模块 做 串口透传 操作记录
  • pipeline方法关系抽取--课堂笔记
  • 海信IP810N/海信IP811N_海思MV320-安卓9.0主板-TTL烧录包-可救砖
  • 检索召回率优化探究四:基于LangChain0.3集成Milvu2.5向量数据库构建的智能问答系统
  • 【基础】第八篇 Java 位运算符详解:从基础到实战应用