思想:
F[i, j] 指代由第i個數出發, 到第i+2^j個數,這段區間[i, i+2^j]的最值, F[i, 0] => 本身 (構造需要接近O(n) )
查詢:
若查詢區間[s, e]最值, 則可根據上述F求出
int nlog = (log(double(e-s+1))/log(2.0) => 求區間[s, e]的長度>=2^m中的 m值
如 區間【s, e】最大值 = max(F[s][nlog], F[e-(1<<nlog)+1][nlog])
F[s][nlog] => 指區間[s, s+2^nlog]的最值 其中s+2^nlog<=e;
F[e-(1<<nlog)+1][nlog] => 區間 [e-2^nlog+1, e] 其中 e-2^nlog+1>=s
已知兩個區間如下圖
即兩個區間是相交的且兩個區間的並集 = [s, e]
Code:
void st(){
int len = strlen(num);
rep(i, 0, len){
F[i][0] = num[i];
}
int nlog = (int)(log((double)len)/log(2.0));
for(int j=1; j<=nlog; j++){
for(int i=0; i+(1<<j)-1<len; i++){
F[i][j] = min(F[i][j-1], F[i+(1<<(j-1))][j-1]);
}
}
return ;
}
int RMQ(int s, int e){
int nlog = (int)(log(double(e-s+1))/log(2.0));
return min(F[s][nlog], F[e-(1<<nlog)+1][nlog]);
}