RMQ问题
RMQ(区间最值查询)问题有多种解法
ST表的主要功能就是处理RMQ问题。记录一个区间内的最大最小值,dp[i][j]表示,从i位置开始的2^j个数中的最大值。查询时将该区间分为两段,保证这两段覆盖查询范围即可
void init()
{
for(int j=0;(1<<j)<=n;j++){
for(int i=1;(i+(1<<j)-1)<=n;i++){
if(j) dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
else dp[i][j]=num[i];
}
}
}
int query(int a,int b)
{
int k=log2(b-a+1);
return max(dp[a][k],dp[b-(1<<k)+1][k]);
}
树状数组也可用于解决RMQ问题。相较于ST表,树状数组还可以对数字进行单点修改维护。树状数组的做法,用于RMQ问题可能并不是那么直观,需要对代码进行适当修改,可以把目标区间尝试进行分段。
int lowbit(int x)
{
return x&(-x);
}
void add(int k,int v)
{
while(k<=n){
tree[k]+=v;
k+=lowbit(k);
}
}
int getmax(int a,int b)
{
if(b>a){
if(b-lowbit(b)>a) return max(tree[b],getmax(a,b-lowbit));
else return max(num[y],getmax(a,b-1));
}
return num[a];
}
线段树,相较于树状数组还多了区间修改维护的功能,但是也更复杂。酌情选择。具体代码见关于树状数组和线段树的博客,稍微改一下就可以用


浙公网安备 33010602011771号