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

POJ 3264 RMQ裸题

时间:2017-01-14 23:04:25      阅读:193      评论:0      收藏:0      [点我收藏+]

标签:连续   pen   ima   target   sed   blank   int   ++   pac   

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裸题

标签:连续   pen   ima   target   sed   blank   int   ++   pac   

原文地址:http://www.cnblogs.com/sbfhy/p/6286190.html

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