CF1045G AI robots

题目大意就不说了

这道题可以用CDQ分治做

但是,如何选择CDQ分治的维度一直是CDQ分治的难点所在

这道题我们有三种选择

1.让智商高的数智商低的

2.让看的近的数看的远的

3.让靠右的数靠左的

但是,1和3都不好满足让这两个机器人分别都能看到的要求(因为不保证所以的机器人的视野范围相同)

所以我们以其视野范围当做第一维(从大到小排序)

之后我们发现对于左边\(i\)

右边满足其智商限制的一定是一个区间,之后这个区间我们可以用双指针维护

之后将这个区间里的数加入权值树状数组查询

另外由于至于范围很大

我们要离散化,但是离散化\(a_i-r_i\)和\(a_i+r_i\)也应当离散化

所以数组开三倍,之前因为这个RE了

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cctype>
using namespace std;
const int N = 5e5 + 3;
struct node{
int xi;
int ri;
int qi;
}a[N];
int b[N];
int n,k;
long long ans;
struct BIT{
int c[N << 1];
inline void ins(int x,int v){for(;x <= b[0];x += x & -x) c[x] += v;}
inline int query(int x){
int res = 0;
for(;x;x -= x & -x) res += c[x];
return res;
}
}T;
inline bool cmp1(node x,node y){
if(x.ri != y.ri) return x.ri > y.ri;
if(x.qi != y.qi) return x.qi < y.qi;
return x.xi < y.xi;
}
inline bool cmp2(node x,node y){
if(x.qi != y.qi) return x.qi < y.qi;
return x.xi < y.xi;
}
inline int read(){
int v = 0,c = 1;char ch = getchar();
while(!isdigit(ch)){
if(ch == '-') c = -1;
ch = getchar();
}
while(isdigit(ch)){
v = v * 10 + ch - 48;
ch = getchar();
}
return v * c;
}
inline void solve(int l,int r){
if(l == r) return ;
int mid = (l + r) >> 1;
solve(l,mid);solve(mid + 1,r);
sort(a + l,a + mid + 1,cmp2);sort(a + mid + 1,a + r + 1,cmp2);
int L = l,R = l - 1;
for(int i = mid + 1;i <= r;++i){
while(R + 1 <= mid && a[R + 1].qi <= a[i].qi + k) T.ins(a[R + 1].xi,1),R++;
while(L <= mid && a[L].qi < a[i].qi - k) T.ins(a[L].xi,-1),L++;
int from = lower_bound(b + 1,b + b[0] + 1,b[a[i].xi] - a[i].ri) - b;
int to = lower_bound(b + 1,b + b[0] + 1,b[a[i].xi] + a[i].ri) - b;
ans += T.query(to) - T.query(from - 1);
}
for(int i = L;i <= R;++i) T.ins(a[i].xi,-1);
}
int main(){
n = read(),k = read();
for(int i = 1;i <= n;++i){
a[i].xi = read();
a[i].ri = read();
a[i].qi = read();
b[++b[0]] = a[i].xi - a[i].ri;
b[++b[0]] = a[i].xi + a[i].ri;
b[++b[0]] = a[i].xi;
}
sort(b + 1,b + b[0] + 1);
b[0] = unique(b + 1,b + b[0] + 1) - b - 1;
for(int i = 1;i <= n;++i) a[i].xi = lower_bound(b + 1,b + b[0] + 1,a[i].xi) - b;
sort(a + 1,a + n + 1,cmp1);
solve(1,n);
printf("%I64d\n",ans);
return 0;
}

最新文章

  1. 带你玩转Visual Studio
  2. [日常训练]yayamao的神题
  3. TCP三次握手原理详解
  4. ConvertFrom-String 命令研究
  5. Oracle 11g客户端在Linux系统上的配置步骤详解
  6. 在ecshop顶部会员信息提示区显示会员等级
  7. JavaScript的事件对象_概述/this
  8. 关于Android中获取Intent里的数据
  9. POJ 2728 Desert King 01分数规划,最优比率生成树
  10. 深入理解Java内存模型(二)——重排序
  11. Codeforces Round #256 (Div. 2) C. Painting Fence 或搜索DP
  12. 【LightOJ1282】Leading and Trailing(数论)
  13. 常用到的html页面布局和组件: 自己用
  14. Python内置函数(48)——ord
  15. vue实现商品累计效果
  16. 将Long类型转为字母数字组合的jar包---Hashids
  17. mongodb 初学 意外 连接服务器异常(Connection refused)
  18. Spring Boot 静态资源映射与上传文件路由配置
  19. ./adb: error while loading shared libraries: libncurses.so.5:
  20. 【前端积累】javascript事件

热门文章

  1. python批量导出项目依赖包及批量安装的方法
  2. JavaScript--查看代码运行效率console.time()与console.timeEnd()用法
  3. 微信小程序组件——bindtap和catchtap的区别
  4. Android实战:手把手实现“捧腹网”APP(一)-----捧腹网网页分析、数据获取
  5. TCP之单项通信
  6. Transformer的PyTorch实现
  7. mysql 字段名和关键字冲突
  8. 第一次作业:C++ 函数重载
  9. Ubuntu 开机自动挂载磁盘
  10. 洛谷P4136 谁能赢呢? 题解 博弈论