数列区间最大值(ST表)
预处理部分
\[\max(a[i,i+2^k-1]) =\max
\left\{
\begin{aligned}
\max&(a[i,i+2^{k-1}-1])\\
\max&(a[i+2^{k-1},i+2^{k-1}+2^{k-1}-1])
\end{aligned}
\right.=
\left\{
\begin{aligned}
\max&(a[i,i+2^{k-1}-1])\\
\max&(a[i+2^{k-1},i+2^k-1])
\end{aligned}
\right.=
\max(a[i,i+2^k-1])
\]
查询部分
\[p=\lfloor \log_{2}{(l+r-1)} \rfloor
\]
\[\max(a[l,r]) = \max
\left\{
\begin{aligned}
\max&(a[l,l^p-1])\\
\max&(a[r-2^p+1,r-2^p+1+2^p-1])
\end{aligned}
\right. = \max
\left\{
\begin{aligned}
\max&(a[l,l^p-1])\\
\max&(a[r-2^p+1,r])
\end{aligned}
\right.
\]
代码
#include<cstdio>
#define max(x,y) (x)>(y)?(x):(y)
using namespace std;
inline int read()
{
int x=0;bool w=true;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=false;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^'0');ch=getchar();}
return w?x:-x;
}
const int N=1e5+5,Q=1e6+5;
int n,q;
int lg2[N],f[N][25];
inline void ST_Init()
{
for(int i=2;i<=n;i++)
lg2[i]=lg2[i>>1]+1;
for(int k=1;k<=lg2[n];k++)
for(int i=1;i+(1<<k)-1<=n;i++)
f[i][k]=max(f[i][k-1],f[i+(1<<k-1)][k-1]);
//max(a[i,i+2^k-1])=max(max(a[i,i+2^(k-1)-1]),max(a[i+2^(k-1),i+2^(k-1)+2^(k-1)-1=i+2^k-1]))
return;
}
inline int ST_query(const int l,const int r)
{
int p=lg2[r-l+1];
return max(f[l][p],f[r-(1<<p)+1][p]);
}
int main()
{
n=read(),q=read();
for(int i=1;i<=n;i++)
f[i][0]=read();
ST_Init();
for(int i=1;i<=q;i++)
{
int x=read(),y=read();
printf("%d\n",ST_query(x,y));
}
return 0;
}
本文采用 「CC-BY-NC 4.0」 创作共享协议,转载请注明作者及出处,禁止商业使用。
作者:Jerrycyx,原文链接:https://www.cnblogs.com/jerrycyx/p/18342706