Codeforces - AI robots

题目链接:Codeforces - AI robots


稍微想一下,应该能想到,如果我们按照半径r排序,那么我们就只需要统计我们能到达的点,然后就不用考虑相互到达的问题了。

然后因为k很小,所以我们暴力对每一个IQ建立权值线段树,然后依次查找即可。

用CDQ分治,也能解决。


AC代码:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e5+10,M=N*60;
int n,k,m,up=1e9;	unordered_map<int,int> mp;
struct node{int x,r,q;}t[N];	long long res;
int rt[N],sum[M],lc[M],rc[M],cnt;
vector<int> v;
inline int get(int x){return lower_bound(v.begin(),v.end(),x)-v.begin()+1;}
int cmp(node a,node b){return a.r>b.r;}
void change(int &p,int l,int r,int x){
	if(!p)	p=++cnt;
	if(l==r){sum[p]++;	return;}
	int mid=l+r>>1;
	if(x<=mid)	change(lc[p],l,mid,x);
	else	change(rc[p],mid+1,r,x);
	sum[p]=sum[lc[p]]+sum[rc[p]];
}
int ask(int p,int l,int r,int ql,int qr){
	if(!p)	return 0;
	if(l==ql&&r==qr)	return sum[p];
	int mid=l+r>>1;
	if(qr<=mid)	return ask(lc[p],l,mid,ql,qr);
	else if(ql>mid)	return ask(rc[p],mid+1,r,ql,qr);
	else return ask(lc[p],l,mid,ql,mid)+ask(rc[p],mid+1,r,mid+1,qr);
}
signed main(){
	cin>>n>>k;
	for(int i=1;i<=n;i++)	
		scanf("%d %d %d",&t[i].x,&t[i].r,&t[i].q),v.push_back(t[i].q);
	sort(v.begin(),v.end()); v.erase(unique(v.begin(),v.end()),v.end()); 
	sort(t+1,t+1+n,cmp);
	for(int i=0;i<v.size();i++)	mp[v[i]]=1;
	for(int i=1;i<=n;i++){
		for(int j=t[i].q-k;j<=t[i].q+k;j++){
			if(!mp[j])	continue;
			res+=ask(rt[get(j)],0,up,max(0,t[i].x-t[i].r),min(up,t[i].x+t[i].r));
		}
		change(rt[get(t[i].q)],0,up,t[i].x);
	}
	cout<<res;
	return 0;
}
发布了604 篇原创文章 · 获赞 242 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/104391265
今日推荐