1 #include<cstdio>
2 #include<cmath>
3 #include<iostream>
4 #define MAX 200010
5 using namespace std;
6 struct node{
7 int l,r;
8 int max;
9 }tree[3*MAX];//三倍就差不多了
10 int s[MAX];
11 void build(int l,int r,int i)//负责建树
12 {
13 tree[i].l=l;
14 tree[i].r=r;
15 if(l==r){
16 tree[i].max=s[l];
17 return;
18 }
19 int mid=(l+r)>>1;//用位运算符效率要高点,还有加法要比乘法效率高
20 build(l,mid,i<<1);
21 build(mid+1,r,(i<<1)+1);
22 tree[i].max=max(tree[i<<1].max,tree[(i<<1)+1].max);//回归的过程中把每一段的最大值带回
23 }
24 void update(int order,int data,int i)//修改节点order的数据为data
25 {
26 if(tree[i].l==order&&tree[i].r==order){//找到此节点的话,直接返修改
27 tree[i].max=data;
28 return;
29 }
30 int mid=(tree[i].l+tree[i].r)>>1;
31 if(order<=mid) update(order,data,i<<1);//否则查找其在左子树还是右子树上
32 else update(order,data,(i<<1)+1);
33 tree[i].max=max(tree[i<<1].max,tree[(i<<1)+1].max);//回归更新max域
34 }
35 int query(int l,int r,int i)//查询l~r间的最大值
36 {
37 if(tree[i].l==l&&tree[i].r==r) return tree[i].max;//找到节点,直接返回max值
38 int mid=(tree[i].l+tree[i].r)>>1;
39 if(r<=mid) return query(l,r,i<<1);//如果r<mid则待查段在左子树上
40 else if(l>mid) return query(l,r,(i<<1)+1);//如果l>mid则待查段在左子树上
41 else return max(query(l,mid,i<<1),query(mid+1,r,(i<<1)+1));//否则左右子树均有,则左右子树均要查找,并返回两者中的较大值
42 }
43 int main()
44 {
45 int N,M,i,a,b;
46 char c;
47 while(~scanf("%d%d",&N,&M)){
48 for(i=1;i<=N;++i)
49 scanf("%d",&s[i]);
50 build(1,N,1);
51 while(M--){
52 scanf("%*c%c%d%d",&c,&a,&b);
53 if(c=='Q') printf("%d\n",query(a,b,1));
54 else update(a,b,1);
55 }
56 }
57 return 0;
58 }
Accepted |
1754 |
500MS |
7200K |
1232 B |
C++ |