玲珑学院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;
}
大致题意:给你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;
}
相关文章推荐
- 1149 - Buildings(RMQ+二分)
- 【二分+RMQ】玲珑oj 1149 - Buildings
- 玲珑 1149 - Buildings 【rmq+二分】
- 玲珑杯 1149 - Buildings(二分+RMQ)
- “玲珑杯”ACM比赛 Round #19 B.Buildings【二分+RMQ】
- HDU 5726 求gcd=k的区间的个数 (二分+RMQ)
- POJ 2452 Sticks Problem [RMQ+二分]
- 浙江理工大学新生赛 B巴比伦花园 rmq+二分
- gym101102D Rectangles (rmq+二分)
- UVALive 6609 Minimal Subarray Length rmq+二分or单调队列
- Bzoj 3339: Rmq Problem && Bzoj 3585: mex 莫队,树状数组,二分
- 玲珑学院OJ 1095 Six and One【暴力预处理+剪枝+二分查询】
- CSU1553 Good subsequence —— 二分 + RMQ/线段树
- Codeforces 514 D R2D2 and Droid Army(RMQ+二分)
- HDU3486----Interviewe----二分+一维RMQ
- hdu 3486 Interviewe 二分+RMQ
- 【打CF,学算法——四星级】CodeForces 689D Friends and Subsequences (RMQ+二分)
- Codeforces Round #361 (Div. 2) D. Friends and Subsequences (二分+RMQ)
- 2016 ACM/ICPC Asia Regional Dalian Online 1008 Function 二分+RMQ
- 【HDU 3486】【二分+RMQ】 Interviewe 【最小化区间个数m,使得每个区间最大值和大于k】