当C为‘Q‘的时候,表示这是一条询问操作,它询问ID从A到B(包括A,B)的学生当中,成绩最高的是多少。
当C为‘U‘的时候,表示这是一条更新操作,要求把ID为A的学生的成绩更改为B。
题目大意就是这样,然后这道题呢,就是一道线段树的区间查询与端点更新的问题。
与区间和有所不同的是:这道题我们是维护线段树的最大值,所以在建树的时候,pushup时,我们要对父节点维护的是两个子节点中的最大值。
然后最后再注意一下更新的时候别忘记了要pushup来更新父节点。
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; #define maxn 222222 int a[maxn]; int ans=0; struct node{ int l,r; int val; }tree[maxn*4]; void pushup(int v){ int temp=v*2; tree[v].val=max(tree[temp].val,tree[temp+1].val); } void build(int l,int r,int v){ tree[v].l=l; tree[v].r=r; tree[v].val=0; if(l==r){ tree[v].val=a[l]; return; } int mid=(l+r)/2; int temp=v*2; build(l,mid,temp); build(mid+1,r,temp+1); pushup(v); } void query(int l,int r,int v){ if(tree[v].l==l&&tree[v].r==r){ ans=max(ans,tree[v].val); return; } int mid=(tree[v].l+tree[v].r)>>1; int temp=v<<1; if(r<=mid) query(l,r,temp); else if(mid<l) query(l,r,temp+1); else{ query(l,mid,temp); query(mid+1,r,temp+1); } } void update(int v,int pos,int score){ if(tree[v].l==pos&&tree[v].r==pos){ tree[v].val=score; return; } int temp=v<<1; int mid=(tree[v].l+tree[v].r)>>1; if(pos<=mid) update(temp,pos,score); else if(pos>mid) update(temp+1,pos,score); pushup(v); } int main(){ int n,m; while(~scanf("%d%d",&n,&m)){ memset(a,0,sizeof(a)); for(int i=1;i<=n;i++) scanf("%d",&a[i]); build(1,n,1); char ss[6]; while(m--){ int aa,bb; scanf("%s",ss); if(ss[0]=='Q'){ ans=0; scanf("%d%d",&aa,&bb); query(aa,bb,0); printf("%d\n",ans); } else if(ss[0]=='U'){ scanf("%d%d",&aa,&bb); update(0,aa,bb); } } } }
时间: 2024-11-06 16:13:04