内容
用于求静态区间最值。
以最大值为例:
设 f i , j ( 1 ≤ i ≥ , 0 ≤ j ≥ 23 ) f_{i,j} ( 1 \leq i \geq \text{ , } 0 \leq j \geq 23) fi,j(1≤i≥ , 0≤j≥23) 表示为区间 i i i 至 i + ( 1 < < j ) − 1 i+(1<<j)-1 i+(1<<j)−1 的最大值。
有 f i , j = max ( f i , j − 1 , f i + ( 1 < < j − 1 ) , j − 1 ) f_{i,j} = \max( f_{i,j-1} \text{ , } f_{i+(1<<j-1),j-1} ) fi,j=max(fi,j−1 , fi+(1<<j−1),j−1)
求 区间 l l l 至 r r r 的最大值
设 c = l o g ( r − l + 1 ) c=log(r-l+1) c=log(r−l+1)
最大值为 max ( f l , c , f r − ( 1 < < c ) + 1 , c ) \max ( f_{l,c} \text{ , } f_{r-(1<<c)+1,c}) max(fl,c , fr−(1<<c)+1,c) (可能重复覆盖,也可能刚好覆盖,不过不会影响最大值)
C o d e Code Code
int main()
{
memset(f,-1,sizeof(f));
n=read();
m=read();
for(int i=1; i<=n; i++)
f[i][0]=read();
for(int j=1; j<=23; j++)
{
for(int i=1; i+(1<<j)-1<=n; i++)
{
f[i][j]=max(f[i][j-1],f[i+(1<<j-1)][j-1]);
}
}
for(int i=1; i<=m; i++)
{
int l=read(),r=read();
int c=log2(r-l+1);
printf("%d\n",max(f[l][c],f[r-(1<<c)+1][c]));
}
}