题目:点击打开链接
题意:输入n,x,k; 和一个 n 长度的 序列 , 一个二元组的定义如下(i,j)
满足 ai<= y <= aj, 使得y|x的y个数为k个(y为[ai,aj]闭区间的整数)
注意 (i,j) != (j,i) 如果 i!=j的情况下,求出满足这样的二元组的个数
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
int main(){
ll n,x,k,ans=0;
ll a[100005];
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!=0);
ll f1=(l+k-1)*x;
ll f2=f1+x;
if(k==0){
f1=a[i];
f2=l*x;
}
ans+=lower_bound(a+1,a+1+n,f2)-lower_bound(a+1,a+1+n,f1);
}
cout<<ans<<endl;
return 0;
}
考虑无论从左还是右,低的都会对高的有影响。所以我们不用考虑 ij的位置,把全部的排序,排序后,考虑找到 包含k个x的范围 x*k和 x*k+x-1,同时对于k==0的情况下,都比x小的情况是没办法得出左右边界,所以左边界要和a[i] 比较,一定要大于a[i]。为什么是取更大,因为这样不用考虑0 和负数的影响[点击打开链接]