1. 程式人生 > >codeforces 1046 a A. AI robots( cdq分治 )

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


*/