数列区间最大值(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
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步