卧薪尝胆,厚积薄发。
AI robots
Date: Sun Sep 23 07:42:23 CST 2018
In Category:
NoCategory
Description:
$n$
个机器人,第
$i$
个机器人能看到位置在
$[x_i-r_i,x_i+r_i]$
,智商在
$[q_i-k,q_i+k]$
内的所有机器人,问能互相看到的机器人对数。
$1\leqslant n \leqslant 10^5$
Solution:
把位置看成横坐标,智商看成纵坐标,相当于是给定若干等宽矩形,矩形中心有点,问矩形互相包含点的个数。
把所有矩形按长度从大到小,那么如果小的能看到大的,大的也能看到小的,于是可以把点依次加进去,统计一下矩形内点的个数,这个可以
$\text{CDQ}$
分治。
Code:
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<map>
#include<cstring>
using namespace std;
int n,m;
#define MAXN 100010
struct robot
{
int x,r,q;
}s[MAXN];
bool cmp_r(robot a,robot b){return a.r > b.r;}
int a[MAXN],cur = 0;
map<int,int> fr;
struct query
{
int pos,x,y,ytop,ybot,type;
}q[MAXN << 2];
bool cmp_pos(query a,query b){return a.pos < b.pos;}
bool cmp_x(query a,query b)
{
if(a.x == b.x)
{
if(a.type == 0)return true;
else return false;
}
return a.x < b.x;
}
long long ans = 0;
int tot = 0;
struct BIT
{
int c[MAXN];
BIT(){memset(c,0,sizeof(c));}
int lowbit(int x){return x & (-x);}
void add(int p,int k){for(int i = p;i <= cur;i += lowbit(i))c[i] += k;return;}
int query(int p){int res = 0;for(int i = p;i >= 1;i -= lowbit(i))res += c[i];return res;}
}t;
void cdq(int l,int r)
{
if(l >= r)return;
int mid = ((l + r) >> 1);
cdq(l,mid);
sort(q + l,q + mid + 1,cmp_x);
sort(q + mid + 1,q + r + 1,cmp_x);
int i = l,j = mid + 1;
for(;i <= mid && j <= r;)
{
if(q[i].x <= q[j].x)
{
if(q[i].type == 0)
{
t.add(q[i].y,1);
}
++i;
}
else
{
if(q[j].type != 0)
{
ans += q[j].type * (t.query(q[j].ytop) - t.query(q[j].ybot - 1));
}
++j;
}
}
for(int k = j;k <= r;++k)ans += q[k].type * (t.query(q[k].ytop) - t.query(q[k].ybot - 1));
for(int k = l;k < i;++k)
{
if(q[k].type == 0)
{
t.add(q[k].y,-1);
}
}
sort(q + mid + 1,q + r + 1,cmp_pos);
cdq(mid + 1,r);
return;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;++i)
{
scanf("%d%d%d",&s[i].x,&s[i].r,&s[i].q);
a[i] = s[i].q;
}
sort(a + 1,a + 1 + n);
for(int i = 1;i <= n;++i)
if(i == 1 || a[i] != a[i - 1])
fr[a[i]] = ++cur;
fr[0x3f3f3f3f] = 1;
sort(s + 1,s + 1 + n,cmp_r);
for(int i = 1;i <= n;++i)
{
map<int,int>::iterator l;
l = fr.upper_bound(s[i].q + m);--l;
map<int,int>::iterator r;
r = fr.lower_bound(s[i].q - m);
++tot;q[tot] = (query){tot,s[i].x - s[i].r - 1,0,l -> second,r -> second,-1};
++tot;q[tot] = (query){tot,s[i].x + s[i].r,0,l -> second,r -> second,1};
++tot;q[tot] = (query){tot,s[i].x,fr[s[i].q],0,0,0};
}
cdq(1,tot);
cout << ans << endl;
return 0;
}
In tag:
数据结构-CDQ分治
Copyright © 2020
wjh15101051
ღゝ◡╹)ノ♡