Processing math: 100%

CF1045G:AI robots(CDQ分治)

Description

火星上有n个机器人排成一行,第i个机器人的位置为xi,视野为ri,智商为qi。我们认为第i个机器人可以看到的位置是[xiri,xi+ri]。如果一对机器人相互可以看到,且它们的智商qi的差距不大于k,那么它们会开始聊天。 为了防止它们吵起来,请计算有多少对机器人可能会聊天。

Input

第一行读入n,k

后面n行每行xi,ri,qi

Output

一行答案。

Sample Input

3 2
3 6 1
7 3 10
10 5 8

Sample Output

1

Solution

当时比赛的时候sugar给我讲了个平衡树做法还没写出来……

不过CDQ做起来的确简单……

先把机器人按视野半径从大到小排序,那么后面的如果能看到前面的,那么前面的一定也能看到后面的,方便我们CDQ用前面的去更新后面的性质。

CDQ里面按智商排序。可以发现对于当前CDQ处理的右半边,随着右边指针右移,左边合法的智商范围是一个长度不变且单调向右的区间,所以可以用单调队列优化。

里面sort并不会影响复杂度……因为就算写了归并复杂度还是nlog2n

Code

复制代码
 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #define N (300009)
 6 #define LL long long
 7 using namespace std;
 8 
 9 struct Que{int x,r,q;}a[N];
10 int n,k,b_num,b[N],c[N];
11 LL ans;
12 
13 inline int read()
14 {
15     int x=0,w=1; char c=getchar();
16     while (c<'0' || c>'9') {if (c=='-') w=-1; c=getchar();}
17     while (c>='0' && c<='9') x=x*10+c-'0', c=getchar();
18     return x*w;
19 }
20 
21 bool cmp1(Que a,Que b)
22 {
23     return a.r>b.r;
24 }
25 
26 bool cmp2(Que a,Que b)
27 {
28     return a.q<b.q;
29 }
30 
31 int getid(int x)
32 {
33     return lower_bound(b+1,b+b_num+1,x)-b;
34 }
35 
36 void Update(int x,int k)
37 {
38     for (; x<=b_num; x+=(x&-x)) c[x]+=k;
39 }
40 
41 int Query(int x)
42 {
43     int ans=0;
44     for (; x; x-=(x&-x)) ans+=c[x];
45     return ans;
46 }
47 
48 void CDQ(int l,int r)
49 {
50     if (l==r) return;
51     int mid=(l+r)>>1;
52     CDQ(l,mid); CDQ(mid+1,r);
53     int L=l,R=l-1;
54     for (int i=mid+1; i<=r; ++i)
55     {
56         while (R+1<=mid && a[R+1].q<=a[i].q+k) Update(getid(a[R+1].x),1), ++R;
57         while (L<=mid && a[L].q<a[i].q-k) Update(getid(a[L].x),-1), ++L;
58         ans+=Query(getid(a[i].x+a[i].r))-Query(getid(a[i].x-a[i].r)-1);
59     }
60     for (int i=L; i<=R; ++i) Update(getid(a[i].x),-1);
61     sort(a+l,a+r+1,cmp2);
62 }
63 
64 int main()
65 {
66     n=read(); k=read();
67     for (int i=1; i<=n; ++i)
68     {
69         int x=read(),r=read(),q=read();
70         b[++b_num]=x; b[++b_num]=x+r; b[++b_num]=x-r;
71         a[i]=(Que){x,r,q};
72     }
73     sort(b+1,b+b_num+1); b_num=unique(b+1,b+b_num+1)-b-1;
74     sort(a+1,a+n+1,cmp1); CDQ(1,n);
75     printf("%lld\n",ans);
76 }
复制代码
posted @   Refun  阅读(261)  评论(0编辑  收藏  举报
编辑推荐:
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
阅读排行:
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· Ai满嘴顺口溜,想考研?浪费我几个小时
· Browser-use 详细介绍&使用文档
· 软件产品开发中常见的10个问题及处理方法
点击右上角即可分享
微信分享提示