POJ 3264 RMQ裸题

Posted 掉血菜鸡煮熟中

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 3264 RMQ裸题相关的知识,希望对你有一定的参考价值。

POJ 3264

题意:n个数,问a[i]与a[j]间最大值与最小值之差。   

总结:看了博客,记下了模板,但有些地方还是不太理解。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<bitset>
#include<vector>
#include<set>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define F(i,a,b)  for (int i=a;i<b;i++)
#define FF(i,a,b) for (int i=a;i<=b;i++)
#define mes(a,b)  memset(a,b,sizeof(a))
#define pb push_back
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3fll
typedef long long ll;
const int N = 1e5+10;

int fmaxn[N][20],fminn[N][20];  //fmaxn[i][j]表示从第i个数起连续2^j个数中的最大值。(DP的状态)
void RMQ(int num)   //预处理->O(nlogn)
{
    for(int j=1; j<20; ++j)
        for(int i=1; i<=num; ++i)
        if(i+(1<<j)-1 <= num)
        {
            fmaxn[i][j]=max(fmaxn[i][j-1], fmaxn[i+(1<<(j-1))][j-1]);  //dp推出来的
            fminn[i][j]=min(fminn[i][j-1], fminn[i+(1<<(j-1))][j-1]);
        }
}

int main()
{
    int h,n,m;
    scanf("%d%d", &n,&m);
    FF(i,1,n) {
        scanf("%d", &h);
        fmaxn[i][0]=fminn[i][0]=h;
    }
    RMQ(n);
    int l,r;
    FF(i,1,m) {
        scanf("%d%d", &l,&r);
        //查询
        int lg=floor(log10(double(r-l+1)) / log10(double(2))); 
        //也是推出来的,得出的lg要使F[i][lg]覆盖区域(l,r),并且lg要最小。最后得到maxn,minn如下
        int maxn=max(fmaxn[l][lg], fmaxn[r-(1<<lg)+1][lg]); 
        int minn=min(fminn[l][lg], fminn[r-(1<<lg)+1][lg]);
        
        printf("%d\\n", maxn-minn);
    }

    return 0;
}
View Code

以上是关于POJ 3264 RMQ裸题的主要内容,如果未能解决你的问题,请参考以下文章

POJ 3264 Balanced Lineup

POJ-3264 RMQ

RMQ 模板题 poj 3264

poj 3264 RMQ

poj 3264 Balanced Lineup RMQ问题

poj 3264(RMQ或者线段树)