@lychee123
        
        2017-02-25T04:48:04.000000Z
        字数 1574
        阅读 1941
    数据结构
题面链接 
题意
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 2000022int n,x,y,k,i,j,m,a[200022];char s[2];struct node{int l,r,max1;}tr[MAXN*4];//一定要*4void 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函数没有返回值,直接这样写 。不需要printfif(s[0]=='Q')printf("%d\n",quary(1,x,y));}}return 0;}