题目链接:[HDU 1754]I Hate It[树状数组查询+更新区间最大值]
题意分析:
查询区间最大值+更新区间最大值。
解题思路:
自己做主把代码改得自己好理解点了XD具体见代码注释
个人感受:
嘛,一步步来,先啃了树状数组先。
具体代码如下:
#include<iostream> #include<cstdio> using namespace std; const int MAXN = 2e5 + 111; int maxVal[MAXN], a[MAXN]; int lowbit(int x) { return x & -x; } void init(int n) { for (int i = 1; i <= n; ++i) { scanf("%d", &a[i]); maxVal[i] = a[i]; for (int j = 1; j < lowbit(i); j <<= 1) // 与所有涉及到的子区间段最大值比较 { maxVal[i] = max(maxVal[i], maxVal[i - j]); } } } int getMax(int l, int r) { int ret = a[r]; while (l != r) { for (r -= 1; r - lowbit(r) >= l; r -= lowbit(r)) // 1.判断是区间是否在查询范围内 { ret = max(ret, maxVal[r]); } ret = max(ret, a[r]); // 2.如果不在查询范围内,则只能将第r个数加入判断 } return ret; } void update(int x, int val, int n) // 单单改变父亲结点是不够的,因为无法确定这段区间中的最大值来自哪里, { // 所以还需要与子区间进行比较确定最大值 a[x] = val; for (int i = x; i <= n; i += lowbit(i)) { maxVal[i] = a[i]; for (int j = 1; j < lowbit(i); j <<= 1) { maxVal[i] = max(maxVal[i], maxVal[i - j]); } } } int main() { int n, m, a, b; while (~scanf("%d%d", &n, &m)) { init(n); char op[2]; for (int i = 0; i < m; ++i) { scanf("%s%d%d", op, &a, &b); if (op[0] == 'Q') printf("%d\n", getMax(a, b)); else update(a, b, n); } } return 0; }