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

玲珑学院OJ 1149-Buildings-(RMQ+二分)

2017-07-30 16:45 281 查看
题目链接:http://www.ifrog.cc/acm/problem/1149

大致题意:给你n个数,问你这n个数中有多少个子区间的最大值减最小值小于等于k

题目思路:首先预处理一波区间最大最小值,RMQ跑一发即可(具体见代码),之后二分查找当前符合条件的子区间有多少个即可。。。。听说单调队列更省时?

#include<map>
#include<stack>
#include<queue>
#include<vector>
#include<math.h>
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
typedef long long ll;
#define inf 1000000000
#define mod 1000000007
#define maxn 200005
#define INF 9223372036854775807LL
#define lowbit(x) (x&-x)
#define eps 1e-10
int a[maxn],b[maxn],mx[maxn][25],mn[maxn][25],n,k;
void RMQ()
{
int i,j;
memset(mn,127,sizeof(mn));
for(i=1;i<=n;i++)
mx[i][0]=mn[i][0]=a[i];
for(j=1;(1<<j)<=n;j++)
for(i=1;i+(1<<j)-1<=n;i++)
{
mx[i][j]=max(mx[i][j-1],mx[i+(1<<(j-1))][j-1]);
mn[i][j]=min(mn[i][j-1],mn[i+(1<<(j-1))][j-1]);
}
}
bool check(int x,int y)
{
int kk=0;
while((1<<(kk+1))<=y-x+1)
kk++;
int maxs=max(mx[x][kk],mx[y-(1<<kk)+1][kk]);
int mins=min(mn[x][kk],mn[y-(1<<kk)+1][kk]);
if(maxs-mins<=k)
return 1;
return 0;
}
int main(void)
{
ll sum=0;
int i,l,r,mid,ans;
scanf("%d%d",&n,&k);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
RMQ();
for(i=1;i<=n;i++)
{
l=i;r=n;ans=i-1;
while(l<=r)
{
mid=(l+r)/2;
if(check(i,mid))
{
ans=mid;
l=mid+1;
}
else
r=mid-1;
}
sum+=ans-i+1;
}
printf("%d\n",sum);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: