RMQ区间最值模板


NYOJ1185


来自kuangbin模板

#include <bits/stdc++.h>
#define N 1010
#define mem(a,x) memset(a,x,sizeof a)
using namespace std;
#define INF 0x3f3f3f3f
const double eps = 1e-8;
typedef long long ll;
const int MAXN = 50010;
int dpmin[MAXN][20];
int dpmax[MAXN][20];
int mm[MAXN];
int mi[MAXN];
void initRMQ(int n,int b[]){
    mm[0] = -1;
    for(int i=1;i<=n;i++){
        mm[i] = ((i&(i-1))== 0 )? mm[i-1]+1: mm[i-1];
        dpmin[i][0] = dpmax[i][0] = b[i];
    }
    for(int j=1;j<=mm[n];j++)
        for(int i=1;i+(1<<j)-1 <=n;i++){
            dpmax[i][j] = max(dpmax[i][j-1] , dpmax[i+(1<<(j-1))][j-1]);
            dpmin[i][j] = min(dpmin[i][j-1] , dpmin[i+(1<<(j-1))][j-1]);
        }

}
int rmqmax(int x,int y){
    int k = mm[y-x+1];
    return max(dpmax[x][k], dpmax[y-(1<<k)+1][k]);
}
int rmqmin(int x,int y){
    int k = mm[y-x+1];
    return min(dpmin[x][k], dpmin[y-(1<<k)+1][k]);
}
int arr[MAXN];
int main(){
    int n;
    int t;scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&arr[i]);
        initRMQ(n,arr);
        int q;scanf("%d",&q);
        while(q--){
            int a,b,c;scanf("%d%d%d",&c,&a,&b);
            if(c == 1)
                printf("%d\n",rmqmin(a,b));
            else if(c == 2)
                printf("%d\n",rmqmax(a,b));
            else
                 printf("%d\n",rmqmax(a,b)+rmqmin(a,b));
        }
    }

    return 0;
}

二维RMQ模板

POJ2019

注意这里不要写错 

((i & (i-1)) == 0)? 注意括号

 mm[0] = -1;
    for(int i=1;i<=500;i++)
        mm[i] = ((i & (i-1)) == 0)? mm[i-1] + 1: mm[i-1];


#include <set>
#include <map>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <bitset>
#define PI acos(-1.0)
#define MOD 1000000009
#define INF 0x3f3f3f3f
#define Lowbit(x) (x & (-x))
#define mem(a,x) memset(a,x,sizeof(a))
#define Read()  freopen("in.txt", "r", stdin);
#define Write() freopen("out.txt", "w", stdout);
#define bitnum(a) __builtin_popcount(a)
using namespace std;
#define INF 0x3f3f3f3f
const double eps = 1e-8;
typedef long long ll;
int val[310][310];
int mm[310];  // 二进制位数减一,使用前初始化
int dpmin[310][310][9][9];
int dpmax[310][310][9][9];
void initRMQ(int n,int m){
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            dpmin[i][j][0][0] = dpmax[i][j][0][0] = val[i][j];
    for(int ii=0;ii<=mm[n];ii++)
        for(int jj=0;jj<=mm[m];jj++)
        if(ii + jj)
            for(int i=1;i + (1<<ii)-1 <=n;i++)
                for(int j=1;j + (1<<jj)-1 <=m;j++){
                    if(ii){
                        dpmin[i][j][ii][jj] =
                        min(dpmin[i][j][ii-1][jj],
                            dpmin[i+(1<<(ii-1))][j][ii-1][jj]);
                        dpmax[i][j][ii][jj] =
                        max(dpmax[i][j][ii-1][jj],
                            dpmax[i+(1<<(ii-1))][j][ii-1][jj]);

                    }
                    else{
                        dpmin[i][j][ii][jj] =
                        min(dpmin[i][j][ii][jj-1],
                            dpmin[i][j+(1<<(jj-1))][ii][jj-1]);
                        dpmax[i][j][ii][jj] =
                        max(dpmax[i][j][ii][jj-1],
                            dpmax[i][j+(1<<(jj-1))][ii][jj-1]);

                    }
                }
}
int rmqmax(int x1,int y1,int x2,int y2)
{
    int k1 = mm[x2-x1+1];
    int k2 = mm[y2-y1+1];
    x2 = x2 - (1<<k1) + 1;
    y2 = y2 - (1<<k2) + 1;
    return max(max(dpmax[x1][y1][k1][k2],dpmax[x1][y2][k1][k2]),max(dpmax[x2][y1][k1][k2],dpmax[x2][y2][k1][k2]));
}
int rmqmin(int x1,int y1,int x2,int y2)
{
    int k1 = mm[x2-x1+1];
    int k2 = mm[y2-y1+1];
    x2 = x2 - (1<<k1) + 1;
    y2 = y2 - (1<<k2) + 1;
    return min(min(dpmin[x1][y1][k1][k2],dpmin[x1][y2][k1][k2]),min(dpmin[x2][y1][k1][k2],dpmin[x2][y2][k1][k2]));
}
int main(){
    mm[0] = -1;
    for(int i=1;i<=500;i++) //初始化mm
        mm[i] = ((i & (i-1)) == 0)? mm[i-1] + 1: mm[i-1];
    int N,B,K;
    while(scanf("%d%d%d",&N,&B,&K) == 3){
        for(int i=1;i<=N;i++)
            for(int j=1;j<=N;j++)
                scanf("%d",&val[i][j]);

        initRMQ(N,N);
        int x,y;
        while(K--){
            scanf("%d%d",&x,&y);
            printf("%d\n",rmqmax(x,y,x+B-1,y+B-1) -
                   rmqmin(x,y,x+B-1,y+B-1));
        }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值