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

猜你喜欢

转载自www.cnblogs.com/00isok/p/10468611.html