poj3264---Balanced Lineup

tips:

  1.位运算--左移k位==乘以2^k

  2.+-的优先级高于<<

  3.dp自底向上求解

  4.数组大小第二维log(n)

  5.ref:紫书P197和度娘的ppt

//有点归并排序的味道,分治两两合并,不过是自底向上
//#include<bits/stdc++.h>
//多重循环嵌套想想意义就好理解哪个变量为什么应该在外层
#include<cstdio>
#include<algorithm>
using namespace std;
const int M=50010;
int dMin[M][20];
int dMax[M][20];
int n,q;
int a[M];
int L,R;
void RMQ_min_init(int a[]){
    for(int i=1;i<=n;i++) dMin[i][0]=a[i];
    for(int j=1;(1<<j)<=n;j++){//区间长度
        for(int i=1;i+(1<<j)-1<=n;i++){
            dMin[i][j]=min(dMin[i][j-1],dMin[i+(1<<j-1)][j-1]);//减号的优先级高于位运算
        }
    }
}
int RMQ_min_Q(int L, int R){
    int k=0;
    while((1<<(k+1))<= (R-L+1)) k++;
    return min(dMin[L][k],dMin[R-(1<<k)+1][k]);
}
void RMQ_max_init(int a[]){
    for(int i=1;i<=n;i++) dMax[i][0]=a[i];
    for(int j=1;(1<<j)<=n;j++)
        for(int i=1;i+(1<<j)-1 <= n; i++)//防止数组越界
            dMax[i][j]=max(dMax[i][j-1],dMax[i+(1<<(j-1))][j-1]);
}
int RMQ_max_Q(int L,int R){
    int k=0;
    while((1<<k+1)<= (R-L+1)) k++;
    return max(dMax[L][k],dMax[R-(1<<k)+1][k]);
}
int main(){
    while(scanf("%d%d",&n,&q)!=EOF){
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        RMQ_min_init(a);
        RMQ_max_init(a);
        for(int i=0;i<q;i++){
            scanf("%d%d",&L,&R);
            int ans1=RMQ_min_Q(L,R);
            int ans2=RMQ_max_Q(L,R);
            printf("%d\n",ans2-ans1);
        }

    }


    return 0;
}
View Code

//https://wenku.baidu.com/view/57c9a018ff4733687e21af45b307e87100f6f87f.html

猜你喜欢

转载自www.cnblogs.com/SUMaywlx/p/9461133.html