题意:单点修改,区间查询最大值
用线段树是可以轻松解决的,这题我是用树状数组写的
对于每个lowbit的区间维护一个最大值,然后当单点加的时候,然后到后面也都一起加
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define rep(i, j, k) for(int i = j; i <= k; i++)
#define maxn 200009
using namespace std;
int n, m, a[maxn], Max[maxn];
int lowbit (int x)
{
return x & (-x);
}
void init ()
{
memset (Max, 0, sizeof (Max));
rep (i, 1, n)
{
Max[i] = a[i];
//for (int j = 1; j < lowbit (i); j <<= 1)
//Max[i] = max (Max[i], Max [i - j]);
for (int j = i - lowbit (i) + 1; j <= i; j++)
Max[i] = max (Max[i], Max[j]);
}
}
int ask (int l, int r)
{
int ret = 0;
while (1)
{
ret = ret > a[r] ? ret : a[r];
if (r == l)
break;
for (r--; r - l >= lowbit (r); r -= lowbit (r))
ret = ret > Max[r] ? ret : Max[r];
}
return ret;
}
int main ()
{
while (scanf ("%d%d", &n, &m) == 2)
{
rep (i, 1, n)
scanf ("%d", &a[i]);
init ();
while (m--)
{
getchar ();
char ch;
scanf ("%c", &ch);
int x, y;
scanf ("%d%d", &x, &y);
if (ch == 'Q')
printf ("%d\n", ask (x, y));
else
{
a[x] = y;
while (x <= n)
{
if (y > Max[x])
Max[x] = y;
else
break;
x += lowbit (x);
}
}
}
}
return 0;
}