链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754
单点更新,求区间最大值
1 // https://blog.csdn.net/panyanyany/article/details/6776300 2 #define _CRT_SBCURE_NO_DEPRECATE 3 #include <cmath> 4 #include <string> 5 #include <cstdio> 6 #include <cstdlib> 7 #include <iostream> 8 using namespace std; 9 10 const int N = 200010; 11 12 int num[N]; 13 struct node 14 { 15 int l,r; 16 int mmax; // 此题只有询问最高成绩的操作,因此不需要存储区间和 17 int mid() 18 { 19 return (l+r)/2; 20 } 21 }tree[N*4]; 22 23 // 构建线段树 24 int BuildTree(int root,int l,int r) 25 { 26 // 当前节点所表示的区间 27 tree[root].l = l; 28 tree[root].r = r; 29 // 若左右区间相同,则此节点为叶子节点,mmax赢储存对应某个学生的值 30 if(l == r) 31 { 32 return tree[root].mmax = num[l]; 33 } 34 // 递归建立左右子树,并从子书中获得最大值 35 int a,b; 36 a = BuildTree(root*2,l,(l+r)/2); 37 b = BuildTree(root*2+1,(l+r)/2+1,r); 38 39 return tree[root].mmax = max(a,b); 40 } 41 42 // void add(int root,int i,int t) 43 // { 44 // // tree[root].sum += t; 45 // if(tree[root].l == i && tree[root].r == i) 46 // return ; 47 // if(i <= tree[root].mid()) 48 // add(root*2,i,t); 49 // else 50 // add(root*2+1,i,t); 51 // } 52 53 54 55 56 // 从节点root开始,查找l和r之间的最大值 57 int find(int root,int l,int r) 58 { 59 // 若此区间与root所管理的区间无交集 60 if(tree[root].l > r || tree[root].r < l) 61 return 0; 62 // 若此区间包含root所管理的区间 63 if(l <= tree[root].l && tree[root].r <= r) 64 return tree[root].mmax; 65 // 递归搜索左右子树,取最大值 66 int a,b; 67 a = find(root*2,l,r); 68 b = find(root*2+1,l,r); 69 return max(a,b); 70 } 71 // 更新pos点的值 72 int update(int root,int pos,int val) 73 { 74 // 若pos不存在于root所管理的区间内 75 if(pos < tree[root].l || tree[root].r < pos) 76 return tree[root].mmax; 77 78 // 若root正好是一个符合条件的叶子 79 if(tree[root].l == pos && tree[root].r == pos) 80 return tree[root].mmax = val; 81 82 // 否则··· 83 int a,b; 84 a = update(root*2,pos,val); 85 b = update(root*2+1,pos,val); 86 87 // 更新最大值 88 tree[root].mmax = max(a,b); 89 90 return tree[root].mmax; 91 } 92 93 94 // int query(int root,int s,int e) 95 // { 96 // if(tree[root].l == s && tree[root].r == e) 97 // return tree[root].mmax; 98 // if(e <= tree[root].mid()) 99 // return query(root*2,s,e); 100 // else 101 // if(s > tree[root].mid()) 102 // return query(root*2+1,s,e); 103 // else 104 // return max(query(root*2,s,tree[root].mid()),query(root*2+1,tree[root].mid()+1,e)); 105 // } 106 107 int main() 108 { 109 int n,m,i,a,b; 110 char s; 111 while(scanf("%d %d",&n,&m)!=EOF) 112 { 113 for(i = 1;i <= n;i++) 114 scanf("%d",&num[i]); 115 BuildTree(1,1,n); 116 for(i = 1;i <= m;i++) 117 { 118 getchar(); 119 scanf("%c",&s); 120 if(s == 'Q') 121 { 122 scanf("%d %d",&a,&b); 123 printf("%d ",find(1,a,b)); 124 } 125 if(s == 'U') 126 { 127 scanf("%d %d",&a,&b); 128 update(1,a,b); 129 } 130 } 131 } 132 return 0; 133 }