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 ≤ 105, 0 ≤ 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 xi, ri and fi (1 ≤ xi, ri ≤ 109, 1 ≤ 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
3 2
1 3 10
3 2 5
4 10 8
1
3 3
1 3 10
3 2 5
4 10 8
2
5 1
1 3 2
2 2 4
3 2 1
4 2 1
5 3 3
2
5 1
1 5 2
2 5 4
3 5 1
4 5 1
5 5 3
5
https://www.cnblogs.com/mlystdcall/p/6351344.html
【转】:
首先整理一下条件:
每个点有三个属性,x,r,f
统计有多少对点i,j满足 min(ri,rj) >= |xi-xj| 且 |fi-fj| <= k,这样的点对被称作是“坏的”
对r值取min是个烦人的条件,于是我们把点按照r值从大到小排序,按照r值从大到小的顺序依次考虑每个点
这样对于每个点,我们只考虑它之前出现的点,也就是r值比他大的点,和他能不能组成“坏的”点对
这样的话,因为一个点i之前所有的点j的r值都比他大,所以 min(ri,rj) = ri
然后我们重新看一下问题:
按照指定的顺序依次加入点,每次加入一个点i,考虑它之前加入的所有点j,有多少个点满足 |xi-xj| <= ri 且 |fi-fj| <= k
再转化一下:
对于每个点i,考虑有多少个它之前的点j满足 xi-ri <= xj <= xi+ri 且 fi-k <= fj <= fi+k
我们把x和f这两个属性看做二维平面中的横纵坐标,问题就变成了:
向一个平面中添加一个点,查询指定矩形内点的个数
这是一个经典的三维偏序问题,可以用 线段树套线段树 或者 CDQ分治 来做
---------------------------------------------分界线--------
自己:
注意到K比较小,我们也可以用二分暴力求矩形内部有多少个点。
(本来像练习CDQ分治的,但是太懒了,所以暴力了。
而且学到了维护有序的vector的方法,也不错的。
#include<bits/stdc++.h> using namespace std; const int maxn=100020; vector<int>G[10020]; struct in{ int x,r,f; }s[maxn]; bool cmp(in w,in v){ return w.r>v.r; } long long ans; int main() { int N,K,i,j; scanf("%d%d",&N,&K); for(i=1;i<=N;i++) scanf("%d%d%d",&s[i].x,&s[i].r,&s[i].f); sort(s+1,s+N+1,cmp); for(i=1;i<=N;i++){ for(j=max(1,s[i].f-K);j<=s[i].f+K;j++) ans+=upper_bound(G[j].begin(),G[j].end(),s[i].x+s[i].r)-lower_bound(G[j].begin(),G[j].end(),s[i].x-s[i].r); int pos=upper_bound(G[s[i].f].begin(),G[s[i].f].end(),s[i].x)-G[s[i].f].begin(); G[s[i].f].insert(G[s[i].f].begin()+pos,s[i].x); } printf("%I64d ",ans); return 0; }