【题解】CF1045G AI Robots
ExplodingKonjac · · 题解
原题链接
本蒟蒻不会cdq分治qwq,写一个不同的解法。
解题思路
首先将问题转化为,对于每一个机器人,有多少个机器人可以和它对话。
然后这里有两个限制条件:智商
Since they are intelligent robots, some of them will talk if they see each other.
这要求两个机器人可以互相看到,那树套树就有些麻烦了,同时也会轻易超出本题小的可怜的250MB内存限制。
我们根据
- 如果视野小的能看到视野大的,那么视野大的一定看得到视野小的,解决了互相看到的问题;
- 可以防止出现十分恶心的数重数漏的问题。
现在我们只剩下了位置和智商两个限制条件。可以写树套树但是空间会炸。
其实题面给了一个非常好的东西
代码实现
#include <bits/stdc++.h>
using namespace std;
int n,k,maxx;
set<int> num;
map<int,int> no;
struct TreeNode
{
int val;
TreeNode *lc,*rc;
TreeNode(): val(0)
{ lc=rc=nullptr; }
};
typedef TreeNode *pNode;
void modify(int p,pNode &i,int l=1,int r=maxx)
{
if(!i) i=new TreeNode;
i->val++;
if(l!=r)
{
int mid=(l+r)>>1;
if(mid>=p) modify(p,i->lc,l,mid);
else modify(p,i->rc,mid+1,r);
}
}
int query(int lq,int rq,pNode i,int l=1,int r=maxx)
{
if(!i) return 0;
if(l>=lq && r<=rq) return i->val;
int mid=(l+r)>>1,res=0;
if(mid>=lq) res+=query(lq,rq,i->lc,l,mid);
if(mid<rq) res+=query(lq,rq,i->rc,mid+1,r);
return res;
}
map<int,pNode> t;
struct Robot
{
int x,r,q;
inline bool operator <(const Robot &b)const
{ return r>b.r; }
}a[100005];
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&a[i].x,&a[i].r,&a[i].q);
num.insert(a[i].x);
num.insert(a[i].x+a[i].r);
num.insert(a[i].x-a[i].r);
}
for(int i: num) no[i]=++maxx;
sort(a+1,a+n+1);
long long ans=0;
for(int i=1;i<=n;i++)
{
int x=no[a[i].x],lb=no[a[i].x-a[i].r],rb=no[a[i].x+a[i].r];
for(int j=a[i].q-k;j<=a[i].q+k;j++)
{
auto tj=t.find(j);
if(tj!=t.end())
ans+=query(lb,rb,tj->second);
}
modify(x,t[a[i].q]);
}
printf("%lld",ans);
return 0;
}