题意:
单点更新,区间求最值;
思路:
维护每个值 and 分块,维护每块的最值;
如果 x 和 y 隶属于同一块,那么直接枚举就行;
如果它们不在同一块,那么中间的每一块的最大值可以由数列 p[ ] 得到,其他x,y各自所在块包含的元素直接枚举即可;
枚举块数复杂度:sqrt(n);
枚举块内元素复杂度:sqrt(n);
所以总的复杂度:m*(sqrt(n));
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ULL;
typedef long long LL;
const int N=2e5+10;
int n,blo,m;
int v[N],p[N],be[N];
void query(int Left,int Right){
int ans=0;
for(int i=Left;i<=min(be[Left]*blo,Right);i++)
ans=ans>v[i]?ans:v[i];
if(be[Left] != be[Right])
{
for(int i=(be[Right]-1)*blo+1;i<=Right;i++)
ans=ans>v[i]?ans:v[i];
}
for(int i=be[Left]+1;i<=be[Right]-1;i++)
ans=ans>p[i]?ans:p[i];
printf("%d\n",ans);
}
void update(int pos,int val)
{
v[pos]=val;
p[be[pos]]=p[be[pos]]<val?val:p[be[pos]];
}
int main(){
char op[2];
int x,y;
while(~scanf("%d%d",&n,&m))
{
blo = sqrt(n);
for(int i=1;i<=n;i++)
{
scanf("%d",&v[i]);
be[i]=(i-1)/blo+1;
}
memset(p,0,sizeof(p));
for(int i=1;i<=n;i++)
p[be[i]]=max(p[be[i]],v[i]);
while(m--)
{
scanf("%s%d%d",op,&x,&y);
if(op[0]=='Q')
query(x,y);
else
update(x,y);
}
}
return 0;
}