码迷,mamicode.com
首页 > 其他好文 > 详细

RMQ最大值最小值

时间:2017-09-12 23:18:23      阅读:210      评论:0      收藏:0      [点我收藏+]

标签:开始   cst   print   ret   namespace   nan   ems   pac   ons   

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int size = 100010;
int maxx[size][32],minn[size][32];
int n;
void init()
{
    int k = log2(n);
    for(int j = 1;j <= k;j ++)
    {
        for(int i = 1;i <= n;i ++)
        {
            maxx[i][j] = max(maxx[i][j-1],maxx[i+(1<<j-1)][j-1]);   //左边位运算优先级比较低,不用加括号 
            minn[i][j] = min(minn[i][j-1],minn[i+(1<<j-1)][j-1]);   //这里[]内是[i+(1<<(j-1))],因为这个区间的另一部分是从上一部分末端开始。 
        }
    }
}

int find(int l,int r)
{
    int k = log2(r-l+1);
    int maxans = max(maxx[l][k],maxx[r-(1<<k)+1][k]);   //这两个区间可能有重复但是无关紧要,我要求的是最大和最小,就算重复也能求出最大和最小。 
    int minans = min(minn[l][k],minn[r-(1<<k)+1][k]);   //同样,这个区间不会超过原区间的范围,因为分别从两个区间下手,考虑的最大化情况也是分别覆盖区间。 
    return (maxans - minans);
}

int main()
{
    memset(minn,60,sizeof(minn));
    int q;  scanf("%d%d",&n,&q);
    for(int i = 1;i <= n;i ++)
    {
        scanf("%d",&maxx[i][0]);
        minn[i][0] = maxx[i][0];
    }
    init();
    for(int i = 1;i <= q;i ++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        int ans = find(a,b);
        printf("%d\n",ans);
    }
    return 0;
}

 

RMQ最大值最小值

标签:开始   cst   print   ret   namespace   nan   ems   pac   ons   

原文地址:http://www.cnblogs.com/Aragaki/p/7512441.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!