搜索 - hdu5289 Assignment

来源:互联网 发布:个人怎样做网络销售 编辑:程序博客网 时间:2024/06/08 03:54

题目:

http://acm.hdu.edu.cn/showproblem.php?pid=5289


题意:

给定一个序列,及界限值k,问该序列中存在多少个区间,满足区间内任意两个数字之差的绝对值小于k


思路:

利用RMQ算法,用nlogn的时间复杂度先算出每个区间的最大最小值

枚举每个区间的左值L,二分搜索最大的区间右值R

则最大区间[L,R]的贡献为R-L+1


代码:

#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<math.h>#include<algorithm>#include<vector>#include<queue>#include<stack>#include<map>#include<set>#include<functional>#pragma comment(linker, "/STACK:102400000,102400000")//C++using namespace std;const double PI = 3.141592653589793238462643383279502884197169399;const int MAXINT = 0x7fffffff;const int MAXSIZE = 100000 + 5;int arr[MAXSIZE];int dmin[MAXSIZE][32],dmax[MAXSIZE][32];void RMQ_init(int A[],int len){    //int n=A.size();    for (int i=0;i<len;++i){        dmin[i][0] = A[i];        dmax[i][0] = A[i];    }    for (int j=1;(1<<j)<=len;++j)        for (int i=0;i+(1<<j)-1<len;++i){            dmin[i][j] = min(dmin[i][j-1],dmin[i+(1<<(j-1))][j-1]);            dmax[i][j] = max(dmax[i][j-1],dmax[i+(1<<(j-1))][j-1]);        }    return ;}int RMQ_min(int L, int R){    int k=0;    while (1<<(k+1) <=  R-L+1) k++;    return min(dmin[L][k],dmin[R-(1<<k)+1][k]);}int RMQ_max(int L, int R){    int k=0;    while (1<<(k+1) <=  R-L+1) k++;    return max(dmax[L][k],dmax[R-(1<<k)+1][k]);}bool RMQ_check(int L, int R, int k){    if (RMQ_max(L,R)-RMQ_min(L,R) < k)        return true;    else return false;}int main(){    int total;    cin>>total;    while (total--){        memset(arr,0,sizeof(arr));        memset(dmin,0,sizeof(dmin));        memset(dmax,0,sizeof(dmax));        int n,k;        scanf("%d %d",&n,&k);        for (int i=0;i<n;++i) scanf("%d",arr+i);        RMQ_init(arr,n);        //cout<<RMQ_min(0,3)<<endl;        long long ans=0;        for (int i=0;i<n;++i){            int l = i, r = n-1;            while (l<=r){                //cout<<"i&r&l: "<<i<<" "<<l<<" "<<r<<endl;                int mid = (l+r)>>1;                if (RMQ_check(i,mid,k)){                    l = mid+1;                }                else r = mid-1;            }            //cout<<"l&r: "<<i<<" "<<l-1<<endl;            ans+=l-i;        }        cout<<ans<<endl;    }    return 0;}


0 0
原创粉丝点击