题意:n个数,m个操作。操作可以是更新某个数的值或查询某个区间的最大值。
思路:线段树(单点更新)。节点维护一个区间最值的信息。
#include <iostream> #include <stdio.h> #include <cmath> #include <algorithm> #include <iomanip> #include <cstdlib> #include <string> #include <memory.h> #include <vector> #include <queue> #include <stack> #include <map> #include <set> #include <ctype.h> using namespace std; int num[200010]; struct node{ int l; int r; int v; }; node tree[800010]; int build_tree(int n,int l,int r){ tree[n].l=l; tree[n].r=r; if(l!=r){ int mid=(l+r)/2; int v1=build_tree(n*2,l,mid); int v2=build_tree(n*2+1,mid+1,r); tree[n].v= max(v1,v2); }else{ tree[n].v=num[l]; } return tree[n].v; } void update(int pos,int n,int v){ int mid=(tree[n].l+tree[n].r)/2; if(tree[n].l==tree[n].r){ tree[n].v=v; return; } if(mid>=pos){ update(pos,n*2,v); }else{ update(pos,n*2+1,v); } tree[n].v=max(tree[2*n].v,tree[2*n+1].v); } int query(int n,int l,int r){ if(tree[n].l==l&&tree[n].r==r){ return tree[n].v; } int mid=(tree[n].l+tree[n].r)/2; if(mid>=r){ return query(n*2,l,r); }else{ if(mid<l){ return query(n*2+1,l,r); }else{ return max(query(n*2,l,mid),query(n*2+1,mid+1,r)); } } } int main(){ int n,m; while(cin>>n>>m){ for(int i=1;i<=n;i++){ scanf("%d",&num[i]); } build_tree(1,1,n); for(int i=1;i<=m;i++){ char c; int a,b; scanf("%c%c %d %d",&c,&c,&a,&b); if(c=='U'){ update(a,1,b); }else{ int ans=query(1,a,b); printf("%d\n",ans); } } } return 0; }