传送门
题目描述:
代码题解
#include<map>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<set>
#include<vector>
#include<numeric>
#include<string>
using namespace std;
#define ll long long
#define MAX 200005
const int inf = 1 << 30;
int n, m;
int maxarray[MAX];
int score[MAX];
int lowbit(int x)
{
return x & (-x);
}
int Getmax(int left, int right)
{
int res = 0;
while (right >= left)
{
res = max(res, score[right]);//注意不能直接取maxarray[right],因为maxarray[right]可能包含了小于left范围的数值
right--;
for (; right - lowbit(right) >= left; right -= lowbit(right))//取到left所属的最近父节点
res = max(res, maxarray[right]);
}
return res;
}
void update(int x)
{
while (x <= n)
{
maxarray[x] = score[x];//先初始化为单点值
int lx = lowbit(x);//获取x所管辖的区域大小
for (int i = 1; i < lx; i <<= 1)//遍历x所管辖的区域最大值点
maxarray[x] = max(maxarray[x], maxarray[x - i]);
x += lx;//更新x所属的区域最大值
}
}
int main()
{
while (scanf("%d%d", &n, &m) != EOF)
{
memset(score, 0, sizeof(score));
memset(maxarray, -inf, sizeof(maxarray));
for (int i = 1; i <= n; i++)
{
scanf("%d", &score[i]);
update(i);
}
//getchar();
char C;
int a, b;
for (int i = 1; i <= m; i++)
{
scanf(" %c%d%d", &C, &a, &b);
if (C == 'Q')
printf("%d\n", Getmax(a, b));
else if (C == 'U')
{
score[a] = b;
update(a);
}
}
}
return 0;
}