您的位置:首页 > 其它

RMQ -- 不修改的权值的求区间最大最小值

2017-07-26 01:09 302 查看
模板题

//介绍的是RMQ - ST 在线算法.

这篇博客讲的好,不懂就去看

//所以RMQ一般也就在LCA中有点应用,其他运用还是不多,主要学的是思路.

//先放一个板子,解释与AC Code 在下面.

/** @Cain*/
const int maxn = 1e6+5;
int dp[maxn][32];
int n;
void RMQ()
{
for(int j=1;(1<<j)<=n;j++){
for(int i=1;i+(1<<j)-1<=n;i++){
dp[i][j] = min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}
}
}
int Find(int l,int r)
{
int k = log2(r-l+1);
return min(dp[l][k],dp[r-(1<<k)+1][k]);
}
int main()
{
scanf("%d",&n);
// Fill(dp,0);
for(int i=1;i<=n;i++){
scanf("%d",&dp[i][0]);
}
RMQ();
int q; scanf("%d",&q);
while(q--){
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",Find(l,r));
}
}


AC Code(求最大值就类似呗)

/** @Cain*/
const int maxn = 1e6+5;
int dp[maxn][32];// dp[i,j]表示 从 i 开始 到i+2j -1(可能不是很
//清楚,是二的 j 次方再减一)这个区间中的最大值
int n;
void RMQ()
{
for(int j=1;(1<<j)<=n;j++){ //如果你问为什么不把j放在内循环的话,说明你还没有理解到RMQ.
for(int i=1;i+(1<<j)-1<=n;i++){
dp[i][j] = min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);//它是竖着弄的,不是平常讲的时候的是横着的.一个意思.行标在变哒! 也
//就是我们理解的那个的列标在变.
}
}
}

int Find(int l,int r)  //如何去找那两个区间了,从而实现O(1)的时间找出答案.
{   //并且区间应该满足边界是哦们需要的,另一方是可以用2的几次方来表示的.
int k = log2(r-l+1);
return min(dp[l][k],dp[r-(1<<k)+1][k]);  //求出这样的一个k,我们就可以这样表示我们要求的区间了.
}
int main()
{
scanf("%d",&n);
// Fill(dp,0);
for(int i=1;i<=n;i++){
scanf("%d",&dp[i][0]);
}
RMQ();
int q; scanf("%d",&q);
while(q--){
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",Find(l,r));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: