1. 程式人生 > >HDU 5178 pairs【二分】||【尺取】

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

family 分析 air 運行 解釋 else 技術分享 宋體 tps

<題目鏈接>

題目大意:

給定一個整數序列,求出絕對值小於等於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【二分】||【尺取】