pairs
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 96 Accepted Submission(s): 38
Problem Description
John has
n points on the X axis, and their coordinates are (x[i],0),(i=0,1,2,…,n−1). He wants to know how many pairs<a,b> that |x[b]−x[a]|≤k.(a<b)
Input
The first line contains a single integer
T (about 5), indicating the number of cases.
Each test case begins with two integers n,k(1≤n≤100000,1≤k≤109).
Next n lines contain an integer x[i](−109≤x[i]≤109), means the X coordinates.
Each test case begins with two integers n,k(1≤n≤100000,1≤k≤109).
Next n lines contain an integer x[i](−109≤x[i]≤109), means the X coordinates.
Output
For each case, output an integer means how many pairs
<a,b> that |x[b]−x[a]|≤k.
Sample Input
2
5 5
-100
0
100
101
102
5 300
-100
0
100
101
102
Sample Output
3
10
Source
首先将所给的坐标从大到小排序,则此题转化为:对排序后的新数列,对每个左边的x[a]找到它右边最远的x[b]使得x[b]-x[a]<=k,累计所有的b-a的和即可。
这里要做一个小优化,否则直接暴搜会TLE:
用一个数组pos[i]记录x[i]右边最远的x[b]的b值,由于x[b]是单调递增的,所以找pos[i+1]时只要将b从pos[i]继续往右找即可。
另外答案结果非常大,应用long long来保存
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 5 using namespace std; 6 7 int main() 8 { 9 int kase; 10 scanf ("%d", &kase); 11 while (kase--) 12 { 13 int n, k; 14 long long ans = 0; 15 int num[100200], pos[100200]; 16 scanf ("%d %d", &n, &k); 17 for (int i = 0; i < n; i++) 18 { 19 scanf ("%d", &num[i]); 20 } 21 sort (num, num + n); 22 for (int i = 0; i < n; i++) 23 { 24 if (i == 0) 25 { 26 for (int j = i + 1; j <= n; j++) 27 if ( (j < n && num[j] - num[i] > k) || (j == n)) 28 { 29 pos[i] = j - 1; 30 ans += j - i - 1; 31 break; 32 } 33 } 34 else 35 { 36 for (int j = pos[i - 1]; j <= n; j++) 37 if ( (j < n && num[j] - num[i] > k) || j == n) 38 { 39 pos[i] = j - 1; 40 ans += j - i - 1; 41 break; 42 } 43 } 44 } 45 printf ("%I64d\n", ans); 46 } 47 return 0; 48 }