题目链接:[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;
}