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

hdu 5178 pairs

时间:2016-04-12 22:13:37      阅读:181      评论:0      收藏:0      [点我收藏+]

标签:

pairs

 问题描述
John 在X轴上拥有nn个点,他们的坐标分别为$(x[i],0),(i=0,1,2,…,n-1)$。 他想知道有多少对< a,b ><a,b>满足|x[b]-x[a]| \leq k(a < b)x[b]x[a]k(a<b)。
输入描述
第一行包含一个正整数TT(大约5),表示有多少组数据。
对于每一组数据,先读入两个数n,k(1 \leq n \leq 100000,1 \leq k \leq {10}^{9})n,k(1n100000,1k10?9??)。
接下来nn行,分别输入x[i]({-10}^{9} \leq x[i] \leq {10}^{9},x[i]x[i](10?9??x[i]10?9??,x[i]为整数)。
输出描述
对于每组数据,输出一行表示有多少对< a,b ><a,b>满足|x[b]-x[a]| \leq kx[b]x[a]k。
输入样例
2
5 5
-100
0
100
101
102
5 300
-100
0
100
101
102
输出样例
3
10

很显然不能使用两重循环,先排序,对于每一个坐标,向右找到最右的而且满足条件的位置,那么这点的答案为两点之间的所有点,对于找点,二分可得
 
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
typedef long long LL;
const int Max=100000+10;
int a[Max];
int main()
{
    int T;
    for(scanf("%d",&T);T;T--)
    {
        int n,k;
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        sort(a+1,a+1+n);
        LL ans=0;
        for(int i=1;i<=n;i++)
        {
            int l=i+1,r=n;
            while(l<=r)
            {
                int mid=(l+r)>>1;
                if(abs(a[i]-a[mid])<=k) l=mid+1;
                else  r=mid-1;
            }
            ans+=l-1-i;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}

 

 
 

hdu 5178 pairs

标签:

原文地址:http://www.cnblogs.com/zsyacm666666/p/5384551.html

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