HDU

来源:互联网 发布:javascript setdate 编辑:程序博客网 时间:2024/05/27 14:13

pairs

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3431 Accepted Submission(s): 1229

Problem Description

John has n points on the X axis, and their coordinates are (x[i],0),(i=0,1,2,,n1). He wants to know how many pairs<a,b> that|x[b]x[a]|k.(a<b)

Input

The first line contains a single integer T (about 5), indicating the number of cases.
Each test case begins with two integers n,k(1≤n≤100000,1≤k≤109).
Next n lines contain an integer x[i](109x[i]109), means the X coordinates.

Output

For each case, output an integer means how many pairs<a,b> that |x[b]x[a]|k.

Sample Input

2
5 5
-100
0
100
101
102
5 300
-100
0
100
101
102

Sample Output

3
10

Source

BestCoder Round #31

题意: 首先是多组样例,给你一个n和k,代表数组中有n个数(可不是严格升序,不要被样例迷惑),设数组为x数组,问你存在多少对坐标<a,b>,使得x[b] - x[a] <= k。范围:1n105,1k109

分析:首先考虑可不可以进行排序,答案是肯定的,因为它要求的只是下标的对数,而不是真正值的对数,然后有序性已经搞定,这时考虑尺取法,先是右指针向后移动直到x[r]-x[l] >= k,还需要特判下是否相等,如若相等话 ans += (r-l);否则 ans += (r-l-1),为什么呢,自己手动模拟下即可,然后l++,其实就是变一点的板子题啦。
然后呢发现这个关系后,其实我们利用二分也是可以的,我们枚举左端点,然后二分下右端点,当然也得改特判的特判咯

注意:答案可能很大哦,记得来long long

比较:
这里写图片描述
这里写图片描述
可以发现还是尺取稍微快点。

尺取参考代码

//尺取#include<bits/stdc++.h>#define ll long longusing namespace std;const int N = 1e5 + 10;ll a[N];int main(){    ios_base::sync_with_stdio(0);    int T;cin>>T;    while(T--){        int n;ll k;cin>>n>>k;        for(int i = 1;i <= n;i++) cin>>a[i];        sort(a+1,a+n+1);        if(a[n]-a[1] <= k){cout<<n*(n-1)/2<<endl;continue;}        ll ans = 0;        int l,r;        ll t = 0;        l = r = 1;        while(true){            while(a[r] - a[l] < k && r < n) r++;            if(r == n && a[r] - a[l] <= k){ ans += 1ll*(r-l)*(r-l+1)/2;break;}            else if(a[r] - a[l] == k) ans += 1ll*(r-l);            else if(a[r] - a[l] > k) ans += 1ll*(r-l-1);            l++;            if(l == n)break;        }        cout<<ans<<endl;    }    return 0;}

二分参考代码

#include<bits/stdc++.h>#define ll long longusing namespace std;const int N = 1e5 + 10;ll a[N];int main(){    ios_base::sync_with_stdio(0);    int n;ll k;    int T;cin>>T;    while(T--){    cin>>n>>k;    for(int i = 1;i <= n;i++) cin>>a[i];    sort(a+1,a+1+n);    ll ans = 0;    for(int i = 1;i < n;i++){        int t = lower_bound(a+1,a+n+1,a[i]+k) - a;        if(a[t] - a[i] == k) ans += 1ll*(t-i);        else ans += 1ll*(t-i-1);    }    cout<<ans<<endl;}    return 0;}
  • 如有错误或遗漏,请私聊下UP,thx
原创粉丝点击