poj 3264 Balanced Lineup (RMQ算法 模板题)

来源:互联网 发布:神州泰岳 知乎 编辑:程序博客网 时间:2024/04/26 15:43

题目大意:给出一串的数字,然后给出一个区间a b,输出从a到b的最大的数和最小的数的差
求区间最值 用rmq 会比线段树更方便更快捷。
预处理时间为logn
查询为o1

banzi

#include <cstdio>#include <cstring>#define N 200005int n,m,st[N][22],log[N];inline int max(int x,int y){return x>y?x:y;}inline int rmq(int l,int r){    if(l>r) return 0;    int k=log[r-l+1];    return max(st[l][k],st[r-(1<<k)+1][k]);}int main(){//  freopen("a.in","r",stdin);    scanf("%d",&n);    for(int i=1;i<=n;++i) scanf("%d",&st[i][0]);    log[0]=-1;    for(int i=1;i<=n;++i) log[i]=log[i>>1]+1;    for(int i=1;i<=log[n];++i)        for(int j=1;j<=n;++j)            if(j+(1<<i-1)<=n) st[j][i]=max(st[j][i-1],st[j+(1<<i-1)][i-1]);    scanf("%d",&m);    while(m--){        int x,y;scanf("%d%d",&x,&y);        printf("%d\n",rmq(x,y));    }    return 0;}
#include <iostream>#include <cstring>#include <cmath>#include <cstdio>using namespace std;int n,m;const int maxn=201000;int a[maxn];int mn[maxn][20];int mx[maxn][20];void init(){  for(int i=1;i<=n;i++)    mn[i][0]=mx[i][0]=a[i];  int k=floor(log((double)n)/log(2.0));  for(int i=1;i<=k;i++)  {    for(int j=n;j>=1;j--)//区间dp逆序处理(只是习惯而已)    {        if(j+(1<<(i-1))<=n)        {            mn[j][i]=min(mn[j][i-1],mn[j+(1<<(i-1))][i-1]);            mx[j][i]=max(mx[j][i-1],mx[j+(1<<(i-1))][i-1]);        }    }  }}int rmq(int i,int j){    int k=floor(log((double)(j-i+1))/log(2.0));    int maxx=max(mx[i][k],mx[j-(1<<k)+1][k]);    int minn=min(mn[i][k],mn[j-(1<<k)+1][k]);    return maxx-minn;}int main(){    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++)        scanf("%d",&a[i]);    init();    for(int i=0;i<m;i++)    {        int x,y;        scanf("%d%d",&x,&y);        printf("%d\n",rmq(x,y) );    }}
0 0