ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

RMQ总结

2022-01-18 19:32:42  阅读:158  来源: 互联网

标签:总结 RMQ 求解 int 31111 mid 测量点 logn


RMQ可以用多种算法求解,可以用ST表来实现o(1)的静态求解,也可以用线段树来实现o(logn)的求解,更可以用树状数组实现o(logn*logn)即o(logn^2)的求解。

这里有一道例题,运用二分+RMQ求解,因为是静态的所以可以用ST表快速求解。

【GDOI2005】河床 (Standard IO) Time Limits: 1000 ms Memory Limits: 65536
KB Detailed Limits

Description
  地理学家们经常要对一段河流进行测量分析。他们从上游开始向下游方向等距离地选择n(<=30000)个点测量水位深度。得到一组数据d1,d2,…,dn,回到实验室后数据分析员根据需要对数据进行分析,发掘隐藏在数据背后的规律。最近,乌龙博士发现某种水文现象与河床地势有关,于是他指示他手下的分析员要找出一段河流中最大高低起伏差不超过k(k<=100)的最长一段。这看似一个复杂的问题,由于任务紧急,分析员来求助于你,并告诉你博士的所有数据都精确到个位。

Input
  输入文件有两行:第一行是整数n,k,分别表示测量点的个数和博士要求的最大水深差(也就是河床地势差)。第二行有n个整数,表示从上游开始依次得到的水位深度
di(1<=i<=n,0<=di<=32767)。

Output   输出文件只有一行,是整数m,表示最长一段起伏不超过k的河流长度,用测量点个数表示。

Sample Input 6 2 5 3 2 2 4 5

Sample Output 4

Data Constraint

Hint   提示:从第二个测量点到第五个测量点之间的那段:3 2 2 4,他们起伏最大时4-2=2。

#include<bits/stdc++.h>
using namespace std;
int n,k,i,j,d[31111],gax[31111],dp[31111],gin[31111],dpback[31111],ans,fx[111111][21],fn[111111][21];
int rmqx(int x,int y)
{
	int z=(int)(log(y-x+1)/log(2));
	return max(fx[x][z],fx[y-(1<<z)+1][z]);
}
int rmqn(int x,int y)
{
	int z=(int)(log(y-x+1)/log(2));
	return min(fn[x][z],fn[y-(1<<z)+1][z]);
}
bool check(int xx,int yy)
{
	int maxn=rmqx(xx,yy),minn=rmqn(xx,yy);
	if(maxn-minn<=k) return true;
	else return false;
}
int main()
{
	scanf("%d%d",&n,&k);
	for(i=1;i<=n;i++)
	{
		scanf("%d",&d[i]);
		fx[i][0]=fn[i][0]=d[i];
	}
	ans=0;
	for(j=1;1<<j<=n;j++)
		for(i=1;i+(1<<j)-1<=n;i++)
			fx[i][j]=max(fx[i][j-1],fx[i+(1<<j-1)][j-1]);
	for(j=1;1<<j<=n;j++)
		for(i=1;i+(1<<j)-1<=n;i++)
			fn[i][j]=min(fn[i][j-1],fn[i+(1<<j-1)][j-1]);
	for(i=1;i<=n;i++)
	{
		int l=i,r=n,mid;
		while(l<r)
		{
			if(r-l==1)
			{
				if(check(i,r))
				{
					l=r;
					break;
				}
				else
				{
					r=l;
					break;
				}
			}
			mid=(l+r)/2;
			if(check(i,mid))
			{
				l=mid;
			}
			else
			{
				r=mid-1;
			}
		}
		if(ans<l-i+1) ans=l-i+1;
	}
	printf("%d\n",ans);
}

标签:总结,RMQ,求解,int,31111,mid,测量点,logn
来源: https://blog.csdn.net/qq_52028570/article/details/122566691

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有