#include <iostream>
#include <stdio.h>
#include <cmath>
using namespace std;
const int maxn=1000010;
const int N=1010;
int data[N];
int f[maxn][20];
int sz;
/*f[i][j]表示 i...2^j-1的最大值,即從第i個數開始連續2^j個數的最大值
2^len>sz -> len*lg2>lgsz j在[1,len]之間
*/
void ST(bool isUp)
{
for(int i=0;i<sz;i++)
f[i][0]=data[i];
int maxlen=(int)(log((double)sz)/log(2.0));
//從小到大劃分,開始比較連續兩個之間的大小關係
for(int len=1;len<=maxlen;len++)
{
//枚舉終點
for(int from=0;from+(1<<len)-1<sz;from++)
{
//由鐘點和後續區間得到起點
int to=from+(1<<(len-1));
//記錄大小值
if(!isUp)
f[from][len]=min(f[from][len-1],f[to][len-1]);
else
f[from][len]=max(f[from][len-1],f[to][len-1]);
//cout<<"["<<from<<","<<from+(1<<len)-1<<"]"<<": "<<f[from][len]<<" ";
}
cout<<endl;
}
}
//l...r -> l...l+2^len-1 + r-2^len+1...r-2^len+1-1+2^len -> l...l+2^len-1 + r-2^len+1...r
int RMQ_min(int l,int r)
{
int len=(int)(log((double)(r-l+1))/log(2.0));
return min(f[l][len],f[r-(1<<len)+1][len]);
}
int RMQ_max(int l,int r)
{
int len=(int)(log((double)(r-l+1))/log(2.0));
return max(f[l][len],f[r-(1<<len)+1][len]);
}
int main()
{
while(cin>>sz)
{
for(int i=0;i<sz;i++)
cin>>data[i];
ST(true);
int l,r;
while(cin>>l>>r)
{
if(l+r==0)
break;
cout<<RMQ_max(l,r)<<endl;
}
}
return 0;
}
Node:RMQ問題之ST算法
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.