CodeForces 762E. Radio stations

In the lattice points of the coordinate line there are n radio stations, the i-th of which is described by three integers:

  • xi — the coordinate of the i-th station on the line,
  • ri — the broadcasting range of the i-th station,
  • fi — the broadcasting frequency of the i-th station.

We will say that two radio stations with numbers i and j reach each other, if the broadcasting range of each of them is more or equal to the distance between them. In other words min(ri, rj) ≥ |xi - xj|.

Let's call a pair of radio stations (i, j) bad if i < j, stations i and j reach each other and they are close in frequency, that is, |fi - fj| ≤ k.

Find the number of bad pairs of radio stations.

Input

The first line contains two integers n and k (1 ≤ n ≤ 1050 ≤ k ≤ 10) — the number of radio stations and the maximum difference in the frequencies for the pair of stations that reach each other to be considered bad.

In the next n lines follow the descriptions of radio stations. Each line contains three integers xiri and fi (1 ≤ xi, ri ≤ 1091 ≤ fi ≤ 104) — the coordinate of the i-th radio station, it's broadcasting range and it's broadcasting frequency. No two radio stations will share a coordinate.

Output

Output the number of bad pairs of radio stations.

Examples
input
3 2
1 3 10
3 2 5
4 10 8
output
1
input
3 3
1 3 10
3 2 5
4 10 8
output
2
input
5 1
1 3 2
2 2 4
3 2 1
4 2 1
5 3 3
output
2
input
5 1
1 5 2
2 5 4
3 5 1
4 5 1
5 5 3
output
5
题意:题目中给的那几个式子,求满足要求的对数

题解:two-pointer枚举右端点(显然按x排序),那左端点的指针呢?

左端点用另一种排序方式:按x+r排序,即能到的最远的x排序,这样就可以two-pointer了

对于一个右端点,我们通过暴力枚举f-k到f+k之间的数查找,然后就只需要查找x[j]>=x[i]-r[i]的即可

由于x特别大,用动态开点线段树直接解决

#include <bits/stdc++.h>

using namespace std;

const int MAXN = 100010;
const int MAXM = MAXN * 30;
const int MAXF = 10010;
const int INF = 1e9;

inline int read()
{
	int sc = 0; char ch = getchar();
	while( ch < '0' || ch > '9' ) ch = getchar();
	while( ch >= '0' && ch <= '9' ) sc = sc * 10 + ch - '0', ch = getchar();
	return sc;
}

int ls[MAXM], rs[MAXM], v[MAXM], root[MAXF], n, m, rank[MAXN], tot;

long long ans;

struct node
{
	int x, r, f;
	bool operator < ( const node & b ) const { return x < b.x; }
}a[MAXN];

bool cmp(int x, int y) { return a[ x ].x + a[ x ].r < a[ y ].x + a[ y ].r; }

inline void modify(int &x, int l, int r, int pos, int val)
{
	if( !x ) x = ++tot;
	v[ x ] += val;
	if( l == r ) return ;
	int mid = l + r >> 1;
	if( pos <= mid ) modify( ls[ x ], l, mid, pos, val );
	else modify( rs[ x ], mid + 1, r, pos, val );
}

inline int query(int x, int l, int r, int pos)
{
	if( !x ) return 0;
	if( l >= pos ) return v[ x ];
	int mid = l + r >> 1;
	if( pos <= mid ) return query( ls[ x ], l, mid, pos ) + v[ rs[ x ] ];
	return query( rs[ x ], mid + 1, r, pos );
}

int main()
{
	n = read(), m = read();
	for( int i = 1 ; i <= n ; i++ ) a[ i ].x = read(), a[ i ].r = read(), a[ i ].f = read(), rank[ i ] = i;
	sort( a + 1, a + n + 1 ); sort( rank + 1, rank + n + 1, cmp );
	for( int i = 1, j = 1 ; i <= n ; i++ )
	{
		while( j <= n && a[ rank[ j ] ].x + a[ rank[ j ] ].r < a[ i ].x ) modify( root[ a[ rank[ j ] ].f ], 1, INF, a[ rank[ j ] ].x, -1 ), j++;
		for( int k = max( 1, a[ i ].f - m ) ; k <= min( 10000, a[ i ].f + m ) ; k++ ) ans += query( root[ k ], 1, INF, max( a[ i ].x - a[ i ].r , 1 ) );
		modify( root[ a[ i ].f ], 1, INF, a[ i ].x, 1 );
	}
	cout << ans << endl;
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值