RMQ模板

RMQ模板

/**
 * RMQ模板
 * 所有下标从1开始,查询的是闭区间[x,y]
 * RMQ查最大 RMQ2查最小 x一定要小于y
 */
const int maxn = 50000 + 7;
int dp[maxn][20], dp2[maxn][20], mm[maxn];

void initRMQ(int n, int b[]) {
	mm[0] = -1;
	for(int i = 1; i <= n; i++) {
		mm[i] = (i & (i - 1)) ? mm[i - 1] : mm[i - 1] + 1;
		dp[i][0] = b[i];
		dp2[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]);
			dp2[i][j] = min(dp2[i][j - 1], dp2[i + (1 << (j - 1))][j - 1]);
		}
}

int RMQ(int x, int y) {
	int k = mm[y - x + 1];
	return max(dp[x][k], dp[y - (1 << k) + 1][k]);
}

int RMQ2(int x, int y) {
	int k = mm[y - x + 1];
	return min(dp2[x][k], dp2[y - (1 << k) + 1][k]);
}

POJ-3264就是个模板题,要求区间最大减最小,链接:https://cn.vjudge.net/problem/POJ-3264

&代码:

#include <cstdio>
#include <bitset>
#include <iostream>
#include <set>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <map>
#include <queue>
#include <vector>
using namespace std;
#define INF 0x3f3f3f3f
#define ll long long
#define fo(i,a,b) for(int i=(a);i<=(b);i++)
#define fd(i,a,b) for(int i=(a);i>=(b);i--)


/**
 * RMQ模板
 * 所有下标从1开始,查询的是闭区间[x,y]
 * RMQ查最大 RMQ2查最小 x一定要小于y
 */
const int maxn = 50000 + 7;
int dp[maxn][20], dp2[maxn][20], mm[maxn];

void initRMQ(int n, int b[]) {
	mm[0] = -1;
	for(int i = 1; i <= n; i++) {
		mm[i] = (i & (i - 1)) ? mm[i - 1] : mm[i - 1] + 1;
		dp[i][0] = b[i];
		dp2[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]);
			dp2[i][j] = min(dp2[i][j - 1], dp2[i + (1 << (j - 1))][j - 1]);
		}
}

int RMQ(int x, int y) {
	int k = mm[y - x + 1];
	return max(dp[x][k], dp[y - (1 << k) + 1][k]);
}

int RMQ2(int x, int y) {
	int k = mm[y - x + 1];
	return min(dp2[x][k], dp2[y - (1 << k) + 1][k]);
}


int n, q, a[maxn];
int main() {
	freopen("E:1.in", "r", stdin);
	while(~scanf("%d%d", &n, &q)) {
		fo(i, 1, n) scanf("%d", a + i);
		initRMQ(n, a);
		fo(i, 1, q) {
			int x, y;
			scanf("%d%d", &x, &y);
			printf("%d
", RMQ(x, y) - RMQ2(x, y));
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/s1124yy/p/6915314.html