RMQ
RMQ问题:在给定的一个长度位N的区间中,有M个询问,每次询问给出区间[L,R],求出区间段元素的
最大值/最小值。对于RMQ问题很容易想到遍历的做法,将区间[L,R]中的元素遍历一遍,即可寻找到
最大/最小值,但当区间长度较大,询问次数较多,就会耗费大量的时间。RMQ问题可以用线段树和ST
表两种做法,下面介绍ST表。
ST表法:
ST表是用来解决RMQ问题非常高效的方法,通过O(nlong)的预处理之后,可以在O(1)时间
内找到所要的答案。其中预处理就是用到了动态规划的思想。
定义:F(i,j)表示以i为下标的元素为起点,区间长度为2^j的区间最值 此时区间范围是[i,i+2j-1-1]
预处理:容易发现初始状态为 F(i,0),此时该值表示区间[i,i]的最值,F(i,0)=ai;
状态转移:可以将[i,j]分成长度为2j-1的两段,一段为[i,i+2j-1-1],另一端为[i+2j−1,i+2j-1]则
F(i,j)=max{f(i,j-1),f(i+2j-1,j-1)}
代码:
void ST(int n) { for(int i=1;i<=n;i++) //预处理 dp[i][0]=i; for(int j=1;(1<<j)<=n;j++) for(int i=1;i+(1<<j)-1<=n;i++) { int a=dp[i][j-1];int b=dp[i+(1<<(j-1))][j-1]; dp[i][j]=a<b?a:b; } }