您的位置:首页 > 产品设计 > UI/UE

“玲珑杯”ACM比赛 Round #19 B.Buildings【二分+RMQ】

2017-07-29 17:30 615 查看
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

“玲珑杯”ACM比赛 Round #19

题目大意:

给你一个长度为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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息