http://acm.hdu.edu.cn/showproblem.php?pid=1754
数据比较大,暴力会超时,所以明显是线段树,普通的线段树,结构体中多开一个值sum储存每个子区间的最大成绩,借此更新和查找就行,差不多就是裸的线段树模板
这种基础的要思考透,多按自己的思想修改修改尝试,不然后面的线段树学习会很吃力
code
1 #include<cstdio> 2 using namespace std; 3 struct point { 4 int l,r,sum; 5 }; 6 point tree[200001*4]; 7 int a[200002]; 8 int max(int x,int y) 9 { 10 if (x>y) return x; 11 else return y; 12 } 13 void build(int i,int left,int right)//建树 14 { 15 tree[i].l=left,tree[i].r=right; 16 if (left==right) 17 { 18 tree[i].sum=a[left]; 19 return; 20 } 21 int mid=(left+right)/2; 22 build(i*2,left,mid); 23 build(i*2+1,mid+1,right); 24 tree[i].sum=max(tree[i*2].sum,tree[i*2+1].sum); 25 } 26 void update(int i,int pos,int ans)//更新 27 { 28 if (pos<tree[i].l||tree[i].r<pos) 29 return ; 30 if (pos==tree[i].l&&tree[i].r==pos) 31 { 32 tree[i].sum=ans; 33 return ; 34 } 35 int mid=(tree[i].l+tree[i].r)/2; 36 if (pos<=mid) 37 update(i*2,pos,ans); 38 else 39 update(i*2+1,pos,ans); 40 tree[i].sum=max(tree[i*2].sum,tree[i*2+1].sum); 41 return ; 42 } 43 int find(int i,int left,int right)// 查找 44 { 45 if (left>tree[i].r||right<tree[i].l) 46 return 0; 47 if (left<=tree[i].l&&right>=tree[i].r) 48 return tree[i].sum; 49 int a=0,b=0; 50 a=find(i*2,left,right); 51 b=find(i*2+1,left,right); 52 return max(a,b); 53 } 54 int main() 55 { 56 int n,m,x,y,i; 57 char op; 58 while (~scanf("%d %d",&n,&m)) 59 { 60 for (i=1;i<=n;i++) 61 scanf("%d",&a[i]); 62 build(1,1,n); 63 while (m--) 64 { 65 getchar(); 66 scanf("%c %d %d",&op,&x,&y); 67 if (op=='Q') 68 { 69 printf("%d\n",find(1,x,y)); 70 } 71 if (op=='U') 72 { 73 a[x]=y; 74 update(1,x,y); 75 } 76 } 77 } 78 return 0; 79 }