题目链接:点击打开链接
题目大意:略。
解题思路:求最值类型的树状数组。
AC 代码
#include<bits/stdc++.h>
#include<cmath>
#define mem(a,b) memset(a,b,sizeof a);
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=200010;
int n,m;
int a[maxn], rs[maxn];
int lowbit(int x)
{
return x & -x;
}
void update(int x,int val)
{
a[x]=val;
while(x<=n)
{
rs[x]=max(rs[x],val);
x+=lowbit(x);
}
}
int query(int l,int r)
{
int ans=a[r]; // 不能用 rs[r] 否则直接就是 [1,r] 中的最大值了
// 这里很关键,看图,如果想求 [1,16],但是之前假如到达了 C[8] 就结束了
// 但本质上还不能结束,所以继续循环,下一个从 C[7] 开始,直到 l==r 为止
while(l!=r)
{
for(r--; r-lowbit(r)>=l; r-=lowbit(r))
ans=max(ans,rs[r]);
// 注意:这里最后一个 r 还没有比较
// 这里不能用 rs[r] 因为 rs[r] 的含义是 从 [1,r] 这个区间的最大值
// 而这里到达最左边界时,就应该要用 a[r] 来进行最后一次的比较
ans=max(ans,a[r]);
}
return ans;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
mem(rs,0);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
update(i,a[i]);
}
char ch[5];
int l,r;
while(m--)
{
scanf("%s%d%d",ch,&l,&r);
if(ch[0]=='Q') printf("%d\n",query(l,r));
else update(l,r);
}
}
return 0;
}