求区间内最大数和最小数的差,用两棵线段树,一个维护区间最大值,一个维护区间最小值。
#include <stdio.h> #include <vector> #include <math.h> #include <string.h> #include <string> #include <iostream> #include <queue> #include <list> #include <algorithm> #include <stack> #include <map> #include <time.h> using namespace std; #define QUADMEMSET inline void QuadMemSet(void* dst, int iSize, int value) { iSize = iSize / 4; int* newDst = (int*) dst; #ifdef WIN32 __asm { mov edi, dst mov ecx, iSize mov eax, value rep stosd } #else for (int i = 0; i < iSize;i++) { newDst[i] = value; } #endif } #define MAXN 132000 int ST[2][MAXN]; #define MAXVALUE 1000000 #define MINVALUE 0 template<class TYPE> void UpdateValue(TYPE st[],int i, TYPE value, int N, bool bMin) { i += N - 1; st[i] = value; while (i > 0) { i = (i - 1) / 2; if (bMin) { st[i] = min(st[i * 2 + 1], st[i * 2 + 2]); } else st[i] = max(st[i * 2 + 1], st[i * 2 + 2]); } } template<class TYPE> TYPE QueryST(TYPE st[], int a, int b, int l, int r, int k, bool bMin) { if (l > b || a > r) { return bMin ? MAXVALUE : MINVALUE; } if (l >= a && b >= r) { return st[k]; } else { TYPE value1 = QueryST(st, a, b, l, (r + l) / 2, k * 2 + 1, bMin); TYPE value2 = QueryST(st, a, b, (r + l) / 2 + 1, r, k * 2 + 2, bMin); if (bMin) { return min(value1, value2); } else { return max(value1, value2); } } } int main() { #ifdef _DEBUG freopen("e:\\in.txt", "r", stdin); #endif QuadMemSet(ST[0], sizeof(ST[0]), MAXVALUE); QuadMemSet(ST[1], sizeof(ST[1]), MINVALUE); int N, Q; scanf("%d %d", &N, &Q); int maxn = 1; while (maxn < N) { maxn *= 2; } for (int i = 0; i < N; i++) { int value; scanf("%d", &value); UpdateValue<int>(ST[0], i, value, maxn, true); UpdateValue<int>(ST[1], i, value, maxn, false); } for (int i = 0; i < Q;i++) { int a, b; scanf("%d %d", &a, &b); int maxr = QueryST<int>(ST[1], a - 1, b - 1, 0, maxn - 1, 0, false); int minr = QueryST<int>(ST[0], a - 1, b - 1, 0, maxn - 1, 0, true); printf("%d\n", maxr - minr); } return 0; }
POJ3264 Balanced Lineup RMQ 线段树,布布扣,bubuko.com
时间: 2024-11-03 20:46:47