学习了一下其他代码后,利用一点数学特性可以改进一下算法,有序序列满足 列尾-列头 ≤ k,那么对数就是 n * (n-1) / 2
#include <iostream>
#include <algorithm>
#define MAXN 100000
using namespace std;
int main() {
ios::sync_with_stdio(false);
long long num[MAXN];
int T, n;
long long k, result;
cin >> T;
while (T--) {
result = 0;
cin >> n >> k;
for (int i = 0; i < n; i++)
cin >> num[i];
sort(num, num+n);
if (num[n-1] - num[0] <= k) {
cout << n * (n-1) / 2 << endl;
continue;
}
for (int i = n-1; i >= 0; i--) {
long long a = num[i] - k;
int pos = lower_bound(num, num+i+1, a) - num;
if (pos == 0 && num[i] - num[pos] <= k) {
result += 1LL * (i+1) * i / 2; // pos == 0
break;
}
result += 1LL * (i - pos);
}
cout << result << endl;
}
}