标签:
rmq(int i,int j,int a)表示查询a数组i到j区间的内容中的最大/最小值核心部分为二分区间以及st预处理算法
先说st预处理算法吧
int dp[i][j];//表示以i开始 长度为2^j的区间里面元素的最大值
那么 dp[i][0] 就表示a[i]本身了 那么dp[i][j]怎么求呢? 我们将需要求的区间二分 2^k为区间二分后的长度 k的求法如下
int k=log(double(n+1))/log(2.0);//n为数组的长度
那么 dp[i][j]=max(dp[i][j-1],dp[i+(1<<j)][j-1]); 这就是st的状态转移方程 也是区间的二分思想 既然我们dp[j]需要dp[j-1]的状态那么 我们写两层循环的时候j的值是顺序的 i的值按循序遍历即可
for(int j=1;j<=k;j++)
{
for(int i=1;i+(1<<j)-1<=n;i++) dp[i][j]=max(dp[i][j-1],dp[i+(1<<j)][j-1]);
}
然后是总的rmq
给个题目吧 hdu 3183
int k=log(double(n+1))/log(2.0);//n为数组的长度
int dp[i][j];//表示以i开始 长度为j的区间里面元素的最大值
for(int i=1;i<=n;i++) dp[i][0]=a[i];//dp的初始化问题
for(int j=1;j<=k;j++)
{
for(int i=1;i+(1<<j)-1<=n;i++) dp[i][j]=max(dp[i][j-1],dp[i+(1<<j)][j-1]);
}
int rmq(int i,int j)
{
int k=log(double(i+j))/log(2.0);
return max(dp[i][k],dp[j-(1<<k)+1][k]);
}
标签:
原文地址:http://www.cnblogs.com/z1141000271/p/5754389.html