codeforces 1046 a A. AI robots( cdq分治 )

A. AI robots

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

In the last mission, MDCS has successfully shipped NN AI robots to Mars. Before they start exploring, system initialization is required so they are arranged in a line. Every robot can be described with three numbers: position (xixi), radius of sight (riri) and IQ (qiqi).

Since they are intelligent robots, some of them will talk if they see each other. Radius of sight is inclusive, so robot can see other all robots in range [xi−ri,xi+ri][xi−ri,xi+ri]. But they don't walk to talk with anybody, but only with robots who have similar IQ. By similar IQ we mean that their absolute difference isn't more than KK.

Help us and calculate how many pairs of robots are going to talk with each other, so we can timely update their software and avoid any potential quarrel.

Input

The first line contains two integers, numbers N(1≤N≤105)N(1≤N≤105) and K(0≤K≤20)K(0≤K≤20).

Next NN lines contain three numbers each xi,ri,qi(0≤xi,ri,qi≤109)xi,ri,qi(0≤xi,ri,qi≤109) — position, radius of sight and IQ of every robot respectively.

Output

Output contains only one number — solution to the problem.

Example

input

Copy

3 2
3 6 1
7 3 10
10 5 8

output

Copy

1

Note

The first robot can see the second, but not vice versa. The first robot can't even see the third. The second and the third robot can see each other and their IQs don't differ more than 2 so only one conversation will happen.

题意: 现在有n人在一条直线上,每个人有一个可以看见的距离,并且每个人都有一个智商值。 每个人只和互相能看见的人并且智商差不能超过k 的人交流,  问你有多少对人在交流。

思路: 这个题转化一下就是n个线段,每个线段有个中点,问你该线段覆盖到的有效中点数(有效就是满足智商问题)。那么我首先对半径R 按从小到大的顺序排序(这样保证了在分治的时候找到的每一对都是互相能看见的),然后在分治的时候,对智商排序,只考虑对于左区间,右区间有多少能和他交流的就可以了。

样例:

4 2
5 10 2
7 3 4
2 5 3
4 2 5

2 2
7 3 4
4 2 5

代码:

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
const int N =1e5+5;

int n;
ll K;
int c[3*N];
int lim=3*N;
int cc;
ll dis[3*N];
ll ans;

struct node
{
    ll x,y;
    ll L,R,r;
}a[N];

int lowbit(int x)
{
    return x&(-x);
}

void update(int x,ll val)
{
    for(;x<lim;x+=lowbit(x)){
        c[x]+=val;
    }
}

ll query(int x)
{
    ll sum=0;
    for(;x>0;x-=lowbit(x)){
        sum+=c[x];
    }
    return sum;
}

void clearr(int x)
{
    for(;x<lim;x+=lowbit(x)){
        if(c[x]==0) break;
        c[x]=0;
    }
}

bool cmp2(node a,node b)
{
    return a.y<b.y;
}


void cdq(int l,int r)
{
    if(l==r)
        return ;
    int mid=l+r>>1;
    cdq(l,mid),cdq(mid+1,r);
    int p1,p2;
    p1=p2=mid+1;
    //cout<<"p1 "<<p1<<" p2 "<<p2<<endl;
    for(int i=l;i<=mid;i++){
        while(p2<=r&&a[p2].y<=a[i].y+K){
            update(a[p2].x,1);
            p2++;
        }
        while(p1<p2&&a[p1].y<a[i].y-K){
            update(a[p1].x,-1);
            p1++;
        }
        //cout<<"p1 "<<p1<<" p2 "<<p2<<endl;
        ans+=query(a[i].R)-query(a[i].L-1);
    }
    //cout<<"l "<<l<<" r "<<r<<" ans "<<ans<<endl;
    for(int i=p1;i<p2;i++) clearr(a[i].x);
    inplace_merge(a+l,a+mid+1,a+r+1,cmp2);
}

bool cmp1(node a,node b)
{
    return a.r<b.r;
}

int main()
{
    scanf("%d %lld",&n,&K);
    cc=0;
    for(int i=1;i<=n;i++){
        scanf("%lld %lld %lld",&a[i].x, &a[i].r, &a[i].y);
        dis[++cc]=a[i].x;
        dis[++cc]=a[i].x-a[i].r;
        dis[++cc]=a[i].x+a[i].r;
    }

    sort(dis+1,dis+cc+1);
    cc=unique(dis+1,dis+cc+1)-(dis+1);

    for(int i=1;i<=n;i++){
        int in=lower_bound(dis+1,dis+cc+1,a[i].x-a[i].r)-dis;
        a[i].L=in;
        in=lower_bound(dis+1,dis+cc+1,a[i].x+a[i].r)-dis;
        a[i].R=in;
        in=lower_bound(dis+1,dis+cc+1,a[i].x)-dis;
        a[i].x=in;
    }
    /*
    cout<<"*****"<<endl;
    for(int i=1;i<=n;i++){
        printf("%lld %lld %lld\n",a[i].L,a[i].x,a[i].R);
    }
    */
    sort(a+1,a+n+1,cmp1);
    cdq(1,n);
    printf("%lld\n",ans);

    return 0;
}

/*

4 2
5 10 2
7 3 4
2 5 3
4 2 5

2 2
7 3 4
4 2 5


*/

猜你喜欢

转载自blog.csdn.net/yjt9299/article/details/82821221
今日推荐