zoukankan      html  css  js  c++  java
  • hdu5289 RMQ+二分

    RMQ预处理最大值,最小值,然后对于每一点,二分可能满足的区间长度,长度-1就是该店开始的区间满足的个数。

    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #define maxn 100010
    #define LL __int64
    int dp1[maxn][20],n,a[maxn],dp2[maxn][20];
    int min(int x,int y)
    {return x<y?x:y;}
    int max(int x,int y)
    {return x>y?x:y;}
    void rmq()
    {
        int i,j;
        for(i=1;i<=n;i++)
        {
            dp1[i][0]=a[i];
            dp2[i][0]=a[i];
        }
        for(j=1;j<=17;j++)
        {
            for(i=1;i+(1<<j)-1<=n;i++)
            {
                dp1[i][j]=min(dp1[i][j-1],dp1[i+(1<<(j-1))][j-1]);
                dp2[i][j]=max(dp2[i][j-1],dp2[i+(1<<(j-1))][j-1]);
            }
        }
    }
    int ok(int m,int l,int k)
    {
        int r=l+m-1;
        int t=(int)(log(m*1.0)/log(2.0));
        int minnum=min(dp1[l][t],dp1[r-(1<<t)+1][t]);
        int maxnum=max(dp2[l][t],dp2[r-(1<<t)+1][t]);
        if(maxnum-minnum<k)
            return 1;
        return 0;
    }
    int main()
    {
        int t,i,j,k;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&k);
            for(i=1;i<=n;i++)
                scanf("%d",&a[i]);
            rmq();
            LL ans=0;
            for(i=1;i<=n;i++)
            {
                int l=1,r=n-i+1,m;//枚举长度
                while(l<=r){
                    m=(l+r)>>1;
                    if(ok(m,i,k))
                    {
                        l=m+1;
                    }
                    else r=m-1;
                }
                ans+=l-1;
            }
            printf("%I64d
    ",ans);
        }
    }
  • 相关阅读:
    沟通的5个步骤
    安家博客园,发表感想
    postman 简单教程-实现简单的接口测试
    Postman的基本使用
    面试题-如何测试一个APP
    Fiddler快捷方式导出jmeter脚本,傻瓜式
    Servlet学习(三)
    scala学习(一)
    白底抠图
    Servlet学习(二)
  • 原文地址:https://www.cnblogs.com/sweat123/p/4862555.html
Copyright © 2011-2022 走看看