pbds科普:
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
// 定义可以存储重复元素的 pbds multiset
typedef tree<
int, // 键类型
null_type, // 值类型(null_type 表示集合)
std::less_equal<int>, // 比较函数(允许重复)
rb_tree_tag, // 使用红黑树
tree_order_statistics_node_update // 支持 order_of_key 和 find_by_order
> pbds_multiset;
思路
题意转化:,满足两个不等式的点数
, 计算
的点数
预处理出数组,
集合:pbds_multiset ms
将二维偏序问题转化为一维,通过对第一维排序。
- 对查询离线,按
排序。对数组
按
排序
- 遍历到
的时候用集合存好
的所有点对应的
- 计算出这个集合元素
的数量,
ms.order_of_key(k2)
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
// 定义可以存储重复元素的 pbds multiset
typedef tree<
int, // 键类型
null_type, // 值类型(null_type 表示集合)
std::less_equal<int>, // 比较函数(允许重复)
rb_tree_tag, // 使用红黑树
tree_order_statistics_node_update // 支持 order_of_key 和 find_by_order
> pbds_multiset;
using i64 = long long;
void solve() {
pbds_multiset ms;
int n,q;
std::cin >> n >> q;
std::deque<std::array<int,2>>vec;
for (int i = 0; i < n; i++){
int x,y;
std::cin >> x >> y;
vec.push_back({y - x, y + x});
}
std::vector<std::tuple<int,int,int>>query;
for (int i = 0; i < q; i++){
int k1,k2;
std::cin >> k1 >> k2;
query.emplace_back(k1,k2,i);
}
std::sort(query.begin(),query.end());
std::sort(vec.begin(),vec.end());
std::vector<int>ans(q);
for (auto[k1,k2,id] : query){
while (vec.size()){
auto[v1,v2] = vec.front();
if (v1 >= k1){
break;
}
vec.pop_front();
ms.insert(v2);
}
ans[id] = ms.order_of_key(k2);
}
for (auto x : ans){
std::cout << x << '\n';
}
}
signed main() {
std::cin.tie(0)->sync_with_stdio(false);
// std::cout<<std::fixed<<std::setprecision(10);
int t = 1;
// std::cin>>t;
while (t--)
solve();
return 0;
}