1149 - Buildings
Time Limit:2s Memory Limit:128MByte
Submissions:617Solved:159
DESCRIPTION
There are nn buildings lined up, and the height of the ii-th house is hihi.
An inteval [l,r][l,r](l≤r)(l≤r) is harmonious if and only if max(hl,…,hr)−min(hl,…,hr)≤kmax(hl,…,hr)−min(hl,…,hr)≤k.
Now you need to calculate the number of harmonious intevals.
INPUT
The first line contains two integers
n(1≤n≤2×105),k(0≤k≤109)n(1≤n≤2×105),k(0≤k≤109).The second line contains
nn integers
hi(1≤hi≤109)hi(1≤hi≤109).
OUTPUT
Print a line of one number which means the answer.
SAMPLE INPUT
3 1
1 2 3
SAMPLE OUTPUT
5
HINT
Harmonious intervals are:
[1,1],[2,2],[3,3],[1,2],[2,3][1,1],[2,2],[3,3],[1,2],[2,3].
SOLUTION
给你一个长度为N的序列,求有多少个区间,使得区间内最大值-最小值<=k;
思路:
我们知道,如果我们确定了左端点L的话,随着右端点R的增加,会使得最大值越来越大,最小值越来越小,也就是差会越来越大,所以我们这里包含一个单调性。
我们可以O(n)枚举左端点,然后二分右端点然后RMQ预处理能够查询区间的最大值和最小值。
过程维护一个最终位子Pos,那么Pos-L+1就是当前左端点对答案的贡献。
Ac代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cmath>
using namespace std;
int maxsum[250000][30];
int minsum[250000][30];
int a[250000];
int n,k;
void rmq_init()
{
for(int j = 1; (1<<j) <= n; ++j)
for(int i = 1; i + (1<<j) - 1 <= n; ++i)
{
maxsum[i][j] = max(maxsum[i][j-1],maxsum[i+(1<<(j-1))][j-1]);
minsum[i][j] = min(minsum[i][j-1],minsum[i+(1<<(j-1))][j-1]);
}
}
int Get_cha(int l, int r)
{
int k = log2(r-l+1);
int Max = max(maxsum[l][k], maxsum[r-(1<<k)+1][k]);
int Min = min(minsum[l][k], minsum[r-(1<<k)+1][k]);
return Max - Min;
}
int main()
{
while(~scanf("%d%d",&n,&k))
{
for(int i = 1; i <= n;++i)
{
scanf("%d",&a[i]);
maxsum[i][0] = a[i];
minsum[i][0] = a[i];
}
rmq_init();
long long ans = 0;
int l , r;
for(int i = 1; i <= n; ++i)
{
int l=i;
int r=n;
int pos=-1;
while(r-l>=0)
{
int mid=(l+r)/2;
if(Get_cha(i,mid)<=k)
{
pos=mid;
l=mid+1;
}
else r=mid-1;
}
ans += pos - i+1;
}
printf("%lld\n",ans);
}
}