RMQ区间最值模板

来源:互联网 发布:禁用学校还原软件 编辑:程序博客网 时间:2024/06/10 01:15


NYOJ1185


来自kuangbin模板

#include <bits/stdc++.h>#define N 1010#define mem(a,x) memset(a,x,sizeof a)using namespace std;#define INF 0x3f3f3f3fconst 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 0x3f3f3f3fconst 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
原创粉丝点击