题意: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;
}
本文介绍了一种使用线段树解决包含单点更新和区间最大值查询问题的方法。通过构建线段树并实现更新与查询操作,有效解决了此类问题。
572

被折叠的 条评论
为什么被折叠?



