codeforces 895B XKSegments
题意还是比较简单
n x k
然后n个数
求里面有多少个 ai <=aj ai<=y<=aj 正好有 K个满足 x|y ( i, j )
枚举每个位子 二分最左边能组合的位子 二分最右边能组合的位子
计数
#include<stdio.h> #include<algorithm> #include<string.h> #include<map> #include<iostream> #include<set> #include<math.h> using namespace std; typedef long long ll; #define MAXN 100010 int z[MAXN]; int num1[MAXN],num2[MAXN]; int n,x,k; int clac(int ind1,int ind2) { int d=num2[ind2]-num1[ind1]; return d; } int main() { while(scanf("%d%d%d",&n,&x,&k)!=EOF) { for(int i=1;i<=n;i++) scanf("%d",&z[i]); sort(z+1,z+n+1); for(int i=1;i<=n;i++) { num1[i]=(z[i]-1)/x; num2[i]=z[i]/x; // cout<<num1[i]<<" "<<num2[i]<<endl; } ll sum=0; for(int i=1;i<=n;i++) { int l,r; l=lower_bound(z+1,z+n+1,z[i])-z; r=n; int ans1,ans2; ans1=ans2=-1; while(l<=r) { int mid=(l+r)>>1; int d=clac(i,mid); if(d==k) { ans1=mid; r=mid-1; } else if(d>k) { r=mid-1; } else l=mid+1; } l=lower_bound(z+1,z+n+1,z[i])-z; r=n; while(l<=r) { int mid=(l+r)>>1; int d=clac(i,mid); // cout<<d<<" "<<l<<" "<<r<<endl; if(d==k) { ans2=mid; l=mid+1; } else if(d>k) { r=mid-1; } else l=mid+1; } // cout<<ans1<<" "<<ans2<<endl; if(ans1!=-1) sum=sum+ans2-ans1+1; } cout<<sum<<endl; } return 0; }
posted on 2017-11-27 16:34 HelloWorld!--By-MJY 阅读(199) 评论(0) 编辑 收藏 举报