要求:学生ID编号分别从1编到N。
第二行包含N个整数,代表这N个学生的初始成绩,其中第i个数代表ID为i的学生的成绩。
接下来有M行。每一行有一个字符 C (只取'Q'或'U') ,和两个正整数A,B。
当C为'Q'的时候,表示这是一条询问操作,它询问ID从A到B(包括A,B)的学生当中,成绩最高的是多少。
当C为'U'的时候,表示这是一条更新操作,要求把ID为A的学生的成绩更改为B。
方法:线段树。
1.update用while写不用递归。
2.query用递归求解。
3.重点是把树补成满二叉树。
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#define inf -1
using namespace std;
int k,n,m,qr,ql,a[1000005],b[1000005],maxv[1000005];
int query(int o,int L,int R)
{
int i,j,k;
int M=L+(R-L)/2,ans=inf;
if(ql<=L&&R<=qr)
return maxv[o];
if(ql<=M) ans=max(ans,query(o*2,L,M));
if(M<qr) ans=max(ans,query(o*2+1,M+1,R));
return ans;
}
void update(int o)
{
int i,j,k;
while(o>=1)
{
o/=2;
maxv[o]=max(maxv[o*2],maxv[o*2+1]);
}
}
int main()
{
int i,j,ans;
char c;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(maxv,inf,sizeof(maxv));
k=ceil(log(n)/log(2));
ans=1;
for(i=0;i<k;i++)
ans*=2;
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
maxv[i+ans-1]=a[i];
update(i+ans-1);
}
/*for(i=1;i<=ans2*2-1;i++)
printf("a%d=%d\n",i,maxv[i]);*/
/*for(i=1;i<=ans*2-1;i++)
printf("a%d=%d\n",i,maxv[i]);*/
for(i=0;i<m;i++)
{
getchar();
scanf("%c%d%d",&c,&ql,&qr);
if(c=='Q')
printf("%d\n",query(1,1,ans));
else
{
maxv[ql+ans-1]=qr;
update(ql+ans-1);
/*for(j=1;j<=ans*2-1;j++)
printf("a%d=%d\n",j,maxv[j]);*/
}
}
}
}