<题目链接>
题目大意:
给定一个整数序列,求出绝对值小于等于k的有序对个数。
解题分析:
$O(nlong(n))$的二分很好写,这里就不解释了。本题尺取$O(n)$也能做,并且效率很不错。
尺取:
#include <bits/stdc++.h> using namespace std; int arr[int(1e5+5)]; int main(){ int T,n,k;scanf("%d",&T); while(T--){ scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) scanf("%d",&arr[i]); sort(arr+1,arr+1+n); long long ans=0; for(int l=1,r=1;l<=n;++l){ while(r+1<=n && arr[r+1]-arr[l]<=k)r++; //因为需要判断后面的arr[r+1]是否符合条件,从而决定r是否要右移,所以这里用的是r+1 ans+=r-l; } printf("%lld ",ans); } }
二分:
#include <bits/stdc++.h> using namespace std; int arr[int(1e5+5)]; int main(){ int n,k,T;scanf("%d",&T);while(T--){ scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) scanf("%d",&arr[i]); sort(arr+1,arr+1+n); long long ans=0; for(int i=1;i<=n;i++){ int cur=arr[i]+k; int l=1,r=n; while(l<=r){ int mid=l+r>>1; if(arr[mid]<=cur)l=mid+1; //找到差值小于等于k的坐标最右的数 else r=mid-1; } ans+=l-1-i; //因为最后符合的情况是运行l=mid+1指令,所以最后答案mid的值为l-1 } printf("%lld ",ans); } }
2019-03-04