[CF1045G]AI robots

Posted by Dispwnl on February 27, 2019

题目

题目大意

给定$n$个一维数轴上的点,每个点有两个值$r_i,q_i$,位于$x_i$,定义两个点$i,j$能匹配为$x_i-r_i\le x_j\le x_i+r_i,x_j-r_j\le x_i\le x_j+r_j$,且$\vert q_i-q_j\vert\le k$,$k$为给定的值

求有多少对点可以匹配

Example

input

3 2
3 6 1
7 3 10
10 5 8

output

1

题解

如果先按$r$排序,这样如果前面的能和后面的匹配,后面的也一定能和前面的匹配

如果把区间$[l,r]$分成$[l,mid]$和$[mid+1,r]$,只用考虑前后面区间对前面每个点的影响,每个区间按$q$值排序,这样前面区间的每个点对应着后面区间的一段连续的点(指$q$值相差不超过$k$),且端点单调递增,这个可以双指针移动解决,然后树状数组区间查询$[x_i-r_i,x_i+r_i]$

开始先按$q$排序再处理$r$,然后遇到$r$相等的情况就自闭了……

代码

# include<iostream>
# include<cstring>
# include<cstdio>
# include<algorithm>
# define LL long long
using namespace std;
const int MAX=3e5+5;
struct p{
	int x,id;
	bool operator< (const p &a)
	const{
		return x<a.x;
	}
}A[MAX];
int n,k,cnt,ID,Mr;
LL ans;
int s[MAX],nL[MAX],nR[MAX],nX[MAX],L[MAX],R[MAX],X[MAX],q[MAX],_[MAX],id[MAX],_id[MAX],a[MAX],b[MAX];
bool cmp(int a,int b) {return _[a]<_[b];}
int lowbit(int x) {return x&-x;}
void change(int x,int d)
{
	for(int i=x;i<=ID;i+=lowbit(i))
	  s[i]+=d;
}
int ask(int x)
{
	int ans=0;
	for(int i=x;i;i-=lowbit(i))
	  ans+=s[i];
	return ans;
}
int ask(int l,int r) {return ask(r)-ask(l-1);}
int read()
{
	int x(0);
	char ch=getchar();
	for(;!isdigit(ch);ch=getchar());
	for(;isdigit(ch);x=x*10+ch-48,ch=getchar());
	return x;
}
void Solve(int l=1,int r=n)
{
	if(l==r) return;
	int mid=(l+r>>1),_L=mid+1,_R=mid+1;
	Solve(l,mid),Solve(mid+1,r);
	for(int i=l;i<=r;++i)
	  id[i]=_id[i];
	for(int i=l;i<=mid;++i)
	  {
	  	while(_L<=r&&q[id[_L]]<q[id[i]]-k) change(X[id[_L]],-1),++_L;
	  	while(_R<=r&&q[id[_R]]<=q[id[i]]+k) change(X[id[_R]],1),++_R;
	  	ans+=ask(L[id[i]],R[id[i]]);
	  }
	while(_L<_R) change(X[id[_L]],-1),++_L;
	for(int i=l,L=l,R=mid+1;i<=r;++i)
	  {
	  	if(L<=mid&&(q[id[L]]<=q[id[R]]||R>r)) _id[i]=id[L],++L;
	  	else if(R<=r&&(q[id[L]]>q[id[R]]||L>mid)) _id[i]=id[R],++R;
	  }
}
int main()
{
	n=read(),k=read();
	for(int i=1;i<=n;++i)
	  _id[i]=i,nX[i]=read(),Mr=max(Mr,_[i]=read()),q[i]=read(),A[++cnt]=(p){nX[i],i},A[++cnt]=(p){nL[i]=max(nX[i]-_[i],0),i},A[++cnt]=(p){nR[i]=nX[i]+_[i],i};
	sort(A+1,A+1+cnt),A[0].x=-1;
	for(int i=1;i<=cnt;++i)
	  {
	  	if(A[i].x!=A[i-1].x) ++ID;
	  	if(nX[A[i].id]==A[i].x) X[A[i].id]=ID;
	  	if(nL[A[i].id]==A[i].x) L[A[i].id]=ID;
	  	if(nR[A[i].id]==A[i].x) R[A[i].id]=ID;
	  }
	return sort(_id+1,_id+1+n,cmp),Solve(),printf("%I64d",ans),0;
}