The RMQ (Range Minimum/Maximum Query) question refers to: for a sequence A of length n, answer several questions RMQ(A,i,j)(i,j<=n), and the subscripts in the returned sequence A are i,j The minimum (large) value in , that is to say, the RMQ problem refers to the problem of finding the maximum value of the interval.
Template summary:
const int MAXNODE = 1 << 19; const int MAXN = 2e6 + 10; struct NODE{ int value; int left, right; } node [MAXNODE]; int father[MAXN]; void BuildTree(int i, int left, int right){ node[i].left = left; node[i].right = right; node[i].value = 0; if(left == right) { father[left] = i; return; } BuildTree(i << 1, left, (int)(floor(left + right)/ 2.0)); BuildTree((i << 1) + 1, (int)(floor((left + right)/ 2.0)) + 1, right); } void UpdateTree(int ri){ if(ri == 1) return; int fi = ri / 2; int a = node[fi << 1].value; int b = node[(fi << 1) + 1].value; node[fi].value = max(a, b); UpdateTree(ri / 2); } int MAX; void Query(int i, int l, int r){ if(node[i].left == l && node[i].right == r){ MAX = max(MAX, node[i].value); return; } i = i << 1; if(l <= node[i].right){ if(r <= node[i].right) Query(i, l, r); else Query(i, l, node[i].right); } i++; if(r >= node[i].left){ if(l >= node[i].left) Query(i, l, r); else Query(i, node[i].left, r); } }
Practical template title:
HDU1754 I Hate It
//HDU 1754 I Hate It //RMQ segment tree #include<cstdio> #include<iostream> #include<cmath> #include<string> #include<algorithm> using namespace std; const int MAXNODE = 1 << 19; const int MAXN = 2e6 + 10; struct NODE{ int value; int left, right; } node [MAXNODE]; int father[MAXN]; void BuildTree(int i, int left, int right){ node[i].left = left; node[i].right = right; node[i].value = 0; if(left == right) { father[left] = i; return; } BuildTree(i << 1, left, (int)(floor(left + right)/ 2.0)); BuildTree((i << 1) + 1, (int)(floor((left + right)/ 2.0)) + 1, right); } void UpdateTree(int ri){ if(ri == 1) return; int fi = ri / 2; int a = node[fi << 1].value; int b = node[(fi << 1) + 1].value; node[fi].value = max(a, b); UpdateTree(ri / 2); } int MAX; void Query(int i, int l, int r){ if(node[i].left == l && node[i].right == r){ MAX = max(MAX, node[i].value); return; } i = i << 1; if(l <= node[i].right){ if(r <= node[i].right) Query(i, l, r); else Query(i, l, node[i].right); } i++; if(r >= node[i].left){ if(l >= node[i].left) Query(i, l, r); else Query(i, node[i].left, r); } } intmain() { int n, m, g; ios::sync_with_stdio(false); while(cin >> n >> m){ BuildTree(1, 1, n); for(int i = 1; i <= n; i++) { cin >> g; node[father[i]].value = g; UpdateTree(father[i]); } string op; int a, b; while(m--) { cin >> op >> a >> b; if (at [0] == 'Q') { MAX = 0; Query(1, a, b); cout << MAX << endl; } else{ node[father[a]].value = b; UpdateTree(father[a]); } } } return 0; }