“玲珑杯”ACM比赛 Round #19 B -- Buildings

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<iostream>
#include<queue>
#include<map>
#include<cmath>
#include<set>
#include<stack>
#define ll long long
#define pb push_back
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)>(y)?(y):(x))
#define cls(name,x) memset(name,x,sizeof(name))//0或-1
#define fs first
#define sc second
#define mp make_pair
#define L(x) (1<<x)
using namespace std;
const int inf=1e9+10;
const ll llinf=1e16+10;
const int maxn=2e5+10;
const int maxm=2e5+10;
const int mod=1e9+7;
int n,k;
int dp[2][maxn][20];
int h[maxn];
int query(int L,int R)
{
    int x=log(R-L+1)/log(2);
    int t1=max(dp[0][L][x],dp[0][R-L(x)+1][x]);
    int t2=min(dp[1][L][x],dp[1][R-L(x)+1][x]);
    return t1-t2;
}
int main()
{
    //freopen("in.txt","r",stdin);
    while(~scanf("%d %d",&n,&k))
    {
        for(int i=1;i<=n;i++)
            scanf("%d",&h[i]);
        for(int i=1;i<=n;i++)
            dp[0][i][0]=dp[1][i][0]=h[i];
        for(int j=1;L(j)<=n;j++)
            for(int i=1;i+L(j)-1<=n;i++)
            {
                dp[0][i][j]=max(dp[0][i][j-1],dp[0][i+L(j-1)][j-1]);
                dp[1][i][j]=min(dp[1][i][j-1],dp[1][i+L(j-1)][j-1]);
            }
        ll ans=0;
        for(int i=1;i<=n;i++)
        {
            int l=i,r=n;
            int res=i;
            while(l<=r)
            {
                int mid=(l+r)/2;
                int t=query(i,mid);
                if(t<=k)
                {
                    res=max(res,mid);
                    l=mid+1;
                }
                else r=mid-1;
            }
            ans+=res-i+1;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

 

posted @ 2017-07-30 14:46  爱种树的码农  阅读(149)  评论(0编辑  收藏  举报