Hdu5178
题意:
题目给你N个点,问有多少对点的长度小于K 。
解法:
首先将所给的坐标从大到小排序,则此题转化为:对排序后的新数列,对每个左边的(x_a)找到它右边最远的 $ x_b $ 使得 $ x_a - x_b leq k $,累计所有的 $ b-a $ 的和即可。
具体实现可以使用二分。
CODE:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N = 1e5 + 5;
#define LL long long
int n, k, T,v[N];
LL ans;
inline int work(int x, int tmp) {
int l = x, r = n, mid = (l + r) >> 1;
while(l <= r) {
if(v[mid] <= tmp)
l = mid + 1;
else r = mid-1;
mid = (l + r) >> 1;
}
return mid;
}
int main () {
scanf ("%d", & T);
while(T--) {
ans = 0;
scanf("%d%d",&n,&k);
for(int i = 1 ; i <= n ; ++i)
scanf ("%d", & v[i]);
sort(v + 1, v + n + 1);
for(int i = 1 ; i <= n ; ++i) {
int tmp = v[i] + k;
ans += (work(i, tmp) - i);
}
printf ("%lld
", ans);
}
return 0;
}