pairs
问题描述John 在X轴上拥有nn个点,他们的坐标分别为$(x[i],0),(i=0,1,2,…,n-1)$。 他想知道有多少对< a,b ><a,b>满足|x[b]-x[a]| leq k(a < b)∣x[b]−x[a]∣≤k(a<b)。
输入描述
第一行包含一个正整数TT(大约5),表示有多少组数据。
对于每一组数据,先读入两个数n,k(1 leq n leq 100000,1 leq k leq {10}^{9})n,k(1≤n≤100000,1≤k≤109)。
接下来nn行,分别输入x[i]({-10}^{9} leq x[i] leq {10}^{9},x[i]x[i](−109≤x[i]≤109,x[i]为整数)。
输出描述
对于每组数据,输出一行表示有多少对< a,b ><a,b>满足|x[b]-x[a]| leq k∣x[b]−x[a]∣≤k。
输入样例
2 5 5 -100 0 100 101 102 5 300 -100 0 100 101 102
输出样例
3 10
很显然不能使用两重循环,先排序,对于每一个坐标,向右找到最右的而且满足条件的位置,那么这点的答案为两点之间的所有点,对于找点,二分可得
#include <iostream> #include <algorithm> #include <cstdio> using namespace std; typedef long long LL; const int Max=100000+10; int a[Max]; int main() { int T; for(scanf("%d",&T);T;T--) { int n,k; scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) scanf("%d",&a[i]); sort(a+1,a+1+n); LL ans=0; for(int i=1;i<=n;i++) { int l=i+1,r=n; while(l<=r) { int mid=(l+r)>>1; if(abs(a[i]-a[mid])<=k) l=mid+1; else r=mid-1; } ans+=l-1-i; } printf("%I64d ",ans); } return 0; }