#include <iostream>
#include <stdio.h>
using namespace std;
int tmp;
int max(int a,int b)
{
return a>b?a:b;
}
struct code
{
int l,r,max;
}xd[600001];//一般开最大值的三倍大小
int creat(int u,int l,int r) //创建树
{
int mid=(l+r)/2;
xd[u].l=l;xd[u].r=r;xd[u].max=0;
if(l!=r)
{
creat(u+u,l,mid);
creat(u+u+1,mid+1,r);
}
}
void work(int u,int l,int r) //寻找区间最大值
{
//if(tmp>xd[u].max) return; //优化,更省时
int mid=(xd[u].l+xd[u].r)/2;
if(xd[u].l==l&&xd[u].r==r) tmp=max(tmp,xd[u].max);
else if(l>mid) return work(u+u+1,l,r);
else if(r<=mid) return work(u+u,l,r);
else {work(u+u,l,mid);work(u+u+1,mid+1,r);}
}
void updata(int u,int old,int xin) //更新节点最大值
{
int mid=(xd[u].l+xd[u].r)/2;
if(xd[u].l==xd[u].r) {xd[u].max=xin;return;}
else
{
if(old<=mid) updata(u+u,old,xin);
else updata(u+u+1,old,xin);
xd[u].max=max(xd[u+u].max,xd[u+u+1].max); //利用递归实现将所有与updata叶子有关的节点进行更新
}
}
int main()
{
int n,m,num,a,b;
char c[5];
while(scanf("%d%d",&n,&m)!=EOF)
{
creat(1,1,n);
for(int i=1;i<=n;i++)
{
scanf("%d",&num);
updata(1,i,num);
}
while(m--)
{
scanf("%s%d%d",c,&a,&b);
if(c[0]=='Q')
{
tmp=-1;
work(1,a,b);
printf("%d\n",tmp);
}
else
{
updata(1,a,b);
}
}
}
}
下面是再度优化的方法,用于timelimited、
#include <iostream>
#include <stdio.h>
using namespace std;
int tmp,num[200001];//存储输入
int max(int a,int b)
{
return a>b?a:b;
}
struct code
{
int l,r,max;
}xd[600001];
void creat(int u,int l ,int r)
{
xd[u].l=l;xd[u].r=r;
int mid=(l+r)/2;
if(l==r) xd[u].max=num[l];
else
{
creat(u+u,l,mid);
creat(u+u+1,mid+1,r);
xd[u].max=max(xd[u+u].max,xd[u+u+1].max);//利用递归,在创建同时维护最大值,须先输入数据后创建
}
}
void updata(int u,int old,int xin)
{
int mid=(xd[u].l+xd[u].r)/2;
if(xd[u].l==xd[u].r) xd[u].max=xin;
else
{
if(old<=mid) updata(u+u,old,xin);
else updata(u+u+1,old,xin);
xd[u].max=max(xd[u+u].max,xd[u+u+1].max);
}
}
void work(int u,int l,int r)
{
int mid=(xd[u].l+xd[u].r)/2;
if(xd[u].l==l&&xd[u].r==r) tmp=max(tmp,xd[u].max);
else
{
if(l>mid) work(u+u+1,l,r);
else if(r<=mid) work(u+u,l,r);
else
{
work(u+u,l,mid);
work(u+u+1,mid+1,r);
}
}
}
int main()
{
int n,m,a,b;
char c[5];
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=1;i<=n;i++)
{
scanf("%d",&num[i]);
}
creat(1,1,n);
while(m--)
{
scanf("%s%d%d",c,&a,&b);
if(c[0]=='Q')
{
tmp=-1;
work(1,a,b);
printf("%d\n",tmp);
}
else
{
updata(1,a,b);
}
}
}
}