要询问一个数列的某区间的最大值,其中会更新数据。
这样的题目使用树状数组是可以的,但是因为要牵涉到区间操作,故此还是线段树比较好点。
不过使用树状数组也是可以的,就是查询的时候麻烦点,注意计算,不要超出区间了。
看下面的query函数,这是主要的难点函数,其中的-1操作和这个判断r - lowbit(r) >= l,都很蛋疼,一不小心就会出错。
#include <cstdio>
#include <algorithm>
using namespace std;
class IHateIt_1754_2
{
static const int SIZE = 200002;
int *a, *c;//a为普通数组,c为树状数组
inline int lowbit(int x)
{
return x & (-x);
}
void update(int i, int val, int len)
{
a[i] = val;
while (i <= len)
{
c[i] = max(c[i], val);
i += lowbit(i);
}
}
int query(int l, int r)
{
int ans = a[r];//上边界
while (l != r)
{
for (r -= 1; r - lowbit(r) >= l; r -= lowbit(r))
{
ans = max(ans, c[r]);//注意计算区间,不要夸区间
}
ans = max(ans, a[r]); //下边界
}
return ans;
}
public:
IHateIt_1754_2() : a((int*)malloc(sizeof(int)*SIZE)),
c((int*)malloc(sizeof(int)*SIZE))
{
int N, M;
while (scanf("%d %d", &N, &M) != EOF)
{
fill(c, c+N+1, 0);
for (int i = 1; i <= N; i++)
{
scanf("%d", &a[i]);
update(i, a[i], N);
}
while (M--)
{
char op[2];
int a, b;
scanf("%s%d%d", op, &a, &b);
if (op[0] == 'U') update(a, b, N);
else printf("%d\n", query(a, b));
}
}
}
~IHateIt_1754_2()
{
free(a), free(c);
}
};
本文探讨了如何使用树状数组和线段树解决数列区间最大值问题,特别是涉及数据更新的情况。通过具体代码示例展示了树状数组的查询函数实现细节,包括关键的区间判断逻辑。

446

被折叠的 条评论
为什么被折叠?



