HDU 5178 pairs【二分】||【尺取】
<题目链接>
题目大意:
给定一个整数序列,求出绝对值小于等于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\n",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\n",ans); } }
2019-03-04
作者:is_ok
出处:http://www.cnblogs.com/00isok/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。