ST求RMQ
思路
f[i][k]
表示一个从i起始、长度为
2k
的区间中的最值
易得一个状态转移方程:
f[i][k]=max{f[i][k−1]f[i+2k−1][k−1]
查询[l,r]区间最值:
ans=max{f[l][k]f[r+1−2k][k]
时间复杂度:
- 初始化 O(Nlog2N)
- 查询 O(1)
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
const int MAXN=100;
struct ST
{
int f[MAXN][32];
void init(int * na,int len)
{
int i,k;
for(i=1;i<=len;i++) f[i][0]=na[i];
for(k=1;(1<<k)<=len;k++)
for(i=1;i+(1<<k)-1<=len;i++)
f[i][k]=min(f[i][k-1],f[i+(1<<(k-1))][k-1]);
}
int calRMQ(int l, int r)
{
int k=log(r-l+1)/log(2);
return min(f[l][k],f[r+1-(1<<k)][k]);
}
} st;