题目意思为:
给你n个数,m次操作( 0<N<=200000,0<M<5000 )。
Q X Y:它询问ID从X到Y(包括X,Y)的学生当中,成绩最高的是多少.
U X Y :要求把ID为X的学生的成绩更改为Y。
<span style="font-size:18px;">#include <stdio.h>
#include <iostream>
#define MAX 200000
using namespace std;
struct ac
{
int l,r;
int max;
}t[4*MAX+5];
int ans;
inline int fmax(int a,int b)
{
return a>b?a:b;
}
void build(int l,int r,int k) //建树
{
t[k].l=l;
t[k].r=r;
t[k].max=-1;
if(l==r)
return ;
int mid=(l+r)/2;
build(l,mid,2*k);
build(mid+1,r,2*k+1);
}
void tree_insert(int x,int d,int k) //更改的值,目标点,所在点,
{
if(t[k].l==t[k].r && t[k].l==d) //只对叶子赋值
{
t[k].max=x;
return ;
}
int mid=(t[k].l+t[k].r)/2;
if(d<=mid)
tree_insert(x,d,2*k);
else if(mid<d)
tree_insert(x,d,2*k+1);
t[k].max=fmax(t[2*k].max,t[2*k+1].max);//对结点取最大值
}
void research(int l,int r,int k) //查找区间最大值
{
if(t[k].l==l && t[k].r==r)
{
ans=fmax(ans,t[k].max);
return ;
}
int mid=(t[k].l+t[k].r)/2;
if(r<=mid) //判断查询区间所在位置
research(l,r,2*k);
else if(mid+1<=l)
research(l,r,2*k+1);
else
{
research(l,mid,2*k);
research(mid+1,r,2*k+1);
}
}
int main()
{
int m,n;
while(scanf("%d %d",&n,&m)!=EOF)
{
build(1,n,1);
int i,goal;
for(i=1;i<=n;i++)
{
scanf("%d",&goal);
tree_insert(goal,i,1);//边输入边叶子值。
}
char s[4];
int x,y,temp;
while(m--)
{
scanf("%s %d %d",s,&x,&y);
if(s[0]=='U')
tree_insert(y,x,1);
else if(s[0]=='Q')
{
ans=0;
if(x>y) //注意判断大小
{
temp=x;
x=y;
y=temp;
}
research(x,y,1);
printf("%d\n",ans);
}
}
}
return 0;
}
</span>
此题主要算法在 建树 区间查找 点更新 。