@lychee123
2017-02-25T12:48:04.000000Z
字数 1574
阅读 1684
数据结构
题面链接
题意
Input
本题目包含多组测试,请处理到文件结束。
在每个测试的第一行,有两个正整数 N 和 M ( 0 学生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。Output
对于每一次询问操作,在一行里面输出最高成绩。
样例
Sample Input
5 6
1 2 3 4 5
Q 1 5
U 3 6
Q 3 4
Q 4 5
U 2 9
Q 1 5
Sample Output
5
6
5
9
代码
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<stdlib.h>
#include<string>
using namespace std;
#define MAXN 2000022
int n,x,y,k,i,j,m,a[200022];
char s[2];
struct node
{
int l,r,max1;
}tr[MAXN*4];//一定要*4
void build(int id,int l,int r)
//建树
{
tr[id].l=l;
tr[id].r=r;
if(l==r)
{
tr[id].max1=a[l];
}
else
{
int mid=(l+r)/2;
build(id*2,l,mid);//左儿子
build(id*2+1,mid+1,r);//右儿子
tr[id].max1=max(tr[id*2].max1,tr[id*2+1].max1);//合并
}
}
int quary(int id,int l,int r)
//查询区间[l,r]的最大值
{
if(l<=tr[id].l&&tr[id].r<=r)
return tr[id].max1;
else
{
int mid=(tr[id].l+tr[id].r)/2;
if(r<=mid)//要找的区间在左边
return quary(id*2,l,r);
else if(l>mid)//要找的区间在右边
return quary(id*2+1,l,r);
else//在之间
{
int x=quary(id*2,l,r);//左边
int y=quary(id*2+1,l,r);//右边
return max(x,y);//合并求最大值
}
}
}
void update(int id,int pos,int val)
//单点更新,把a[pos]修改成val
{
if(tr[id].l==tr[id].r)
tr[id].max1=val;
else
{
int mid=(tr[id].l+tr[id].r)/2;
if(pos<=mid)//往左
update(id*2,pos,val);
else//往右
update(id*2+1,pos,val);
tr[id].max1=max(tr[id*2].max1,tr[id*2+1].max1);
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
build(1,1,n);
for(i=0;i<m;i++)
{
scanf("%s%d%d",s,&x,&y);
if(s[0]=='U')
update(1,x,y);//void函数没有返回值,直接这样写 。不需要printf
if(s[0]=='Q')
printf("%d\n",quary(1,x,y));
}
}
return 0;
}