hdu 5289 Assignment (rmq模版)

来源:互联网 发布:越狱苹果抹除所有数据 编辑:程序博客网 时间:2024/05/17 01:24
/*rmq模版*/#include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>#include<iostream>using namespace std;const int MAXN = 100100;int n,query;int A[MAXN];int FMin[MAXN][20],FMax[MAXN][20];void Init(){    int i,j;    for(i=1; i<=n; i++)        FMin[i][0]=FMax[i][0]=A[i];    for(i=1; (1<<i)<=n; i++)  //按区间长度递增顺序递推    {        for(j=1; j+(1<<i)-1<=n; j++)  //区间起点        {            FMin[j][i]=min(FMin[j][i-1],FMin[j+(1<<(i-1))][i-1]);            FMax[j][i]=max(FMax[j][i-1],FMax[j+(1<<(i-1))][i-1]);        }    }}int Querymax(int l,int r)//区间最大{    int k=(int)(log(double(r-l+1))/log((double)2));    return max(FMax[l][k],FMax[r-(1<<k)+1][k]);}int Querymin(int l,int r)//区间最小{    int k=(int)(log(double(r-l+1))/log((double)2));    return min(FMin[l][k],FMin[r-(1<<k)+1][k]);}int main(){    int i,a,k,t;    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&k);        for(i=1; i<=n; i++)            scanf("%d",&A[i]);        Init();        __int64 ans=0;        int  map=2;        for(i=1; i<=n; i++)///枚举左端点 二分右端点        {            int left=map;            int right=n;            while(left<=right)            {                int mid=(left+right)/2;                int maxx=Querymax(i,mid);                int minn=Querymin(i,mid);                if(maxx-minn<k)                {                    map=mid+1;                    left=mid+1;                }                else                    right=mid-1;            }            // printf("%d %d\n",i,left-1);            ans+=(left-1)-i+1;        }        printf("%I64d\n",ans);    }    return 0;}

0 0
原创粉丝点击