st表很像线段树,但线段树既能查询和修改,而st表只能查询。
首先我们先用二维数组建立一个表,st[i][j]表内存的是从第i位开始1<<j范围内的best(st[i][j-1],st[i+(1<<j-1)][j-1])
由上面的公式可知st[i][j]是由st[i][j-1],st[i+(1<<j-1)][j-1]更新而来的,我们可以将st[i][j]分成两段,由1<<j=2*(1<<j-1)可得一段是st[i][j-1],另一段则是st[i+(1<<j-1)][j-1]。
然后再用log以2为底n的对数对输入的长度做处理,其中可以用if(1 << Log2[i]+1 == i) Log2[i] ++做判断。
例题:poj3264
description
For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer John decides to organize a game of Ultimate Frisbee with some of the cows. To keep things simple, he will take a contiguous range of cows from the milking lineup to play the game. However, for all the cows to have fun they should not differ too much in height.
Farmer John has made a list of Q (1 ≤ Q ≤ 200,000) potential groups of cows and their heights (1 ≤ height ≤ 1,000,000). For each group, he wants your help to determine the difference in height between the shortest and the tallest cow in the group.
input
Line 1: Two space-separated integers, N and Q.
Lines 2..N+1: Line i+1 contains a single integer that is the height of cow i
Lines N+2..N+Q+1: Two integers A and B (1 ≤ A ≤ B ≤ N), representing the range of cows from A to B inclusive.
output
Lines 1..Q: Each line contains a single integer that is a response to a reply and indicates the difference in height between the tallest and shortest cow in the range.
sample input
6 3
1
7
3
4
2
5
1 5
4 6
2 2
sample output
6
3
0
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 50010
int stmax[maxn][],stmin[maxn][],Log2[maxn];
int n,q;
void init()
{
for(int j = ; (<<j) <= n; j ++)
for(int i = ; i +(<<j)- <= n ; i ++){
stmax[i][j] = max(stmax[i][j-],stmax[i+(<<j-)][j-]);
stmin[i][j] = min(stmin[i][j-],stmin[i+(<<j-)][j-]);
}
Log2[] = ;
for(int i = ; i <= n; i ++)
{
Log2[i] = Log2[i-];
if( << Log2[i]+ == i) Log2[i] ++;
}
} int query(int l,int r)
{
int len = r - l + ;
int k = Log2[len];
int maxx = max( stmax[l][k],stmax[r-(<<k)+][k]);
int minn = min( stmin[l][k],stmin[r-(<<k)+][k]);
return maxx - minn;
} int main()
{
int l,r;
scanf("%d%d",&n,&q);
for(int i = ; i <= n; i ++)
{
scanf("%d",&stmax[i][]);
stmin[i][] = stmax[i][];
}
init();
while(q--){
scanf("%d%d",&l,&r);
printf("%d\n",query(l,r));
}
}