void RMQ_init() { for(int i=1; i<=n; i++) dp[i][0]=s[i]; for(int j=1; (1<<j)<=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]); } int RMQ(int L,int R) { int k=0; while((1<<(k+1))<=R-L+1) k++; return max(dp[L][k],dp[R-(1<<k)+1][k]); }
附带讲解:
http://blog.csdn.net/liang5630/article/details/7917702
#include <cstring> #include <cmath> #include <cstdio> #include <algorithm> #define N 50010 using namespace std; int maxArr[N][16], minArr[N][16]; int n, q, num[N]; void Sparse_Table(){ int l = (int)(log((double)n) / log(2.0)); for (int j = 1;j <= l;j++) for (int i = 1; i + (1 << (j - 1) ) - 1 <= n;++i){ maxArr[i][j] = max(maxArr[i][j - 1], maxArr[i + (1 << (j - 1))][j - 1]); minArr[i][j] = min(minArr[i][j - 1], minArr[i + (1 << (j - 1))][j - 1]); } } int rmq(int l, int r){ int k = (int)(log((double)(r - l + 1)) / log(2.0)); int Max = max(maxArr[l][k], maxArr[r - (1 << k) + 1][k]); int Min = min(minArr[l][k], minArr[r - (1 << k) + 1][k]); return Max - Min; } int main(){ while (~scanf("%d %d", &n, &q)){ memset(maxArr, 0, sizeof(maxArr)); memset(minArr, 0, sizeof(minArr)); for (int i = 1;i <= n;i++){ scanf("%d", &num[i]); maxArr[i][0] = minArr[i][0] = num[i]; } Sparse_Table(); int l, r; while (q--){ scanf("%d%d", &l, &r); printf("%d ", rmq(l, r)); } } return 0; }