蛮有趣的一道题。
先来说说题意,大概是:对一个数组a,定义符合条件的二元组
(i,j)
表示恰好存在
k
个整数,满足
一上来有些懵逼,不妨先找找规律。
我们知道,假定存在
k
个这样的整数,那么首先
接下来的问题就是如何找到
对数组排序之后,我们可以遍历一遍整个数组,然后对每一个数求一下在
[L+(k−1)∗x,L+k∗x−1]
范围内有多少数即可。
最后考虑如何实现。由于我们只是统计个数,所以我们可以二分查找出
l=L+(k−1)∗x
,
r=L+k∗x
第一个大于等于这两个数的数所在的位置相减即可。可以采用algorithm库的lower_bound实现。
当然这样有个问题,就是对k = 0的情况应当有一些特判,此时我们发现如果
a[i]
是
x
的倍数,区间就是
AC代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long LL;
LL a[100003], ans;
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
LL n, x, k;
cin>>n>>x>>k;
for(int i = 1; i <= n; ++i) cin>>a[i];
sort(a + 1, a + n + 1);
for(int i = 1; i <= n; ++i) {
LL L = (a[i] % x) ? ((a[i] / x + 1) * x) : a[i];
LL l = L + (k - 1) * x, r = L + k * x;
if(!k) l = a[i];
ans += lower_bound(a + 1, a + n + 1, r) - lower_bound(a + 1, a + n + 1, l);
}
cout<<ans<<endl;
return 0;
}