这是kuangbin的RMQ,一维的,代码很简洁,附上:
//kuangbin templet(查询最大值) 一维 //若想查最小,看提示更改 const int MAXN= 50000 + 9 ; int dp[MAXN][20];//第二维是范围,即2^20约等于100万 //PS 如果同时要求最大最小,要多开一个dp2[][]来存最小 int mm[MAXN];//mm是间接存的数组 //b[]才是数据,并且b从1开始 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]; dp[i][0]=b[i]; } for (int j=1;j<=mm[n];j++) for (int i=1;i+(1<<j)-1<=n;i++) dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]); //PS 若最小 max 改为 min } int RMQ(int x,int y) { int k=mm[y-x+1]; return max(dp[x][k],dp[y-(1<<k)+1][k]); //PS 若最小 max 改为 min }
这是一个很好的测RMQ的题:http://poj.org/problem?id=3264
附上代码,initRMQ2和RMQ2是初始化最小,和查询最小的函数。
#include <stdio.h> #include <iostream> using namespace std; const int INF=0x3f3f3f3f; typedef long long ll; #define PI(A) printf("%d\n",A) #define SI(N) scanf("%d",&(N)) #define SII(N,M) scanf("%d%d",&(N),&(M)) #define cle(a,val) memset(a,(val),sizeof(a)) #define rep(i,b) for(int i=0;i<(b);i++) #define Rep(i,a,b) for(int i=(a);i<=(b);i++) #define reRep(i,a,b) for(int i=(a);i>=(b);i--) const double EPS= 1e-9 ; /* ///////////////////////// C o d i n g S p a c e ///////////////////////// */ //kuangbin templet(查询最大值) 一维 //若想查最小,看提示更改 const int MAXN= 50000 + 9 ; int dp[MAXN][20];//第二维是范围,即2^20约等于100万 int dp2[MAXN][20]; int mm[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]; dp[i][0]=b[i]; } for (int j=1;j<=mm[n];j++) for (int i=1;i+(1<<j)-1<=n;i++) dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]); //PS 若最小 max 改为 min } int RMQ(int x,int y) { int k=mm[y-x+1]; return max(dp[x][k],dp[y-(1<<k)+1][k]); //PS 若最小 max 改为 min } void initRMQ2(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]; dp2[i][0]=b[i]; } for (int j=1;j<=mm[n];j++) for (int i=1;i+(1<<j)-1<=n;i++) dp2[i][j]=min(dp2[i][j-1],dp2[i+(1<<(j-1))][j-1]); //PS 若最小 max 改为 min } int RMQ2(int x,int y) { int k=mm[y-x+1]; return min(dp2[x][k],dp2[y-(1<<k)+1][k]); //PS 若最小 max 改为 min } int N,Q; int input[MAXN]; int main() { while(~SII(N,Q)) { Rep(i,1,N) SI(input[i]); initRMQ(N,input); initRMQ2(N,input); rep(i,Q) { int a,b; SII(a,b); printf("%d\n",RMQ(a,b)-RMQ2(a,b)); } } return 0; }
时间: 2024-11-06 03:36:40