天才的记忆(RMQ,ST表)
作者:互联网
分析
裸的ST表
ST表
初始化
倍增枚举出区间的最大值,f[N] [M]代表,从n开始长度为2^m的区间最值。
查询
[l,r]
1.求出该区间长度最接近的倍增预处理后的长度,k = log(len)/log(2);
2.最大值为
\[Max=max(f[l][k],f[r-2^k+1][k]) \]ACcode
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10,M = 18;
int f[N][M];
int w[N];
int n,m;
//初始化
void init()
{
for(int j=0;j<18;j++)//枚举区间长度
for(int i=1;i+(1<<j)-1<=n;i++)//枚举区间
{
if(!j) f[i][j]=w[i];//如果区间长度为1,则就是它本身
else f[i][j]=max(f[i][j-1],f[i+(1<<j-1)][j-1]);//否则,则最大值为[i,i+2^(j-1)]和[i+2^(j-1),i+2^j]中的最大值
}
}
int query(int l,int r)
{
int len = r-l+1;
int k = log(len)/log(2);//从区间开头,得到的最长的预处理的区间
return max(f[l][k],f[r-(1<<k)+1][k]);//这个区间的最大值,是[l,l+2^k],[r-2^k+1,r]中的最大值
}
int main()
{
scanf("%d", &n);
for(int i=1;i<=n;i++) scanf("%d",&w[i]);
init();
scanf("%d",&m);
while (m -- ){
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",query(l,r));
}
return 0;
}
标签:初始化,RMQ,log,int,最大值,ST,天才,长度 来源: https://www.cnblogs.com/aitejiu/p/15171988.html