HDU 5178 pairs二分||尺取

Posted 00isok

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
",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

以上是关于HDU 5178 pairs二分||尺取的主要内容,如果未能解决你的问题,请参考以下文章

二分+尺取HDU 6119 小小粉丝度度熊

hdu 6231 -- K-th Number(二分+尺取)

hdu 6119 小小粉丝度度熊 (区间处理+尺取)

Codeforces - 1324D - Pair of Topics(尺取)

POJ3061 Subsequence 尺取or二分

hdu1937 二维尺取