码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 5178 pairs【二分】||【尺取】

时间:2019-03-04 10:02:25      阅读:170      评论:0      收藏:0      [点我收藏+]

标签:\n   font   style   spl   its   效率   long   strong   题目   

<题目链接>

题目大意:

给定一个整数序列,求出绝对值小于等于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

HDU 5178 pairs【二分】||【尺取】

标签:\n   font   style   spl   its   效率   long   strong   题目   

原文地址:https://www.cnblogs.com/00isok/p/10468611.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!