题目链接在这里
题目描述:
给出n个数,m次操作。操作有如下两种:
1.Q x y,查询在[x, y]中最大的数
2.U x y,将x点更新为y
题目思路:
用线段树维护[1, n]区间,单点更新区间查询。
代码如下:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#define rep(i, x) for(int i = 0; i < x; ++i)
#define clr(x) memset(x, 0, sizeof(x))
using namespace std;
const int MaxN = 2e5 + 5;
struct Node{
int l, r, w;
}tree[MaxN << 2];
int ans;
void build(int l, int r, int rt){
if(l == r){
scanf("%d", &tree[rt].w);
return;
}
int mid = (l + r) >> 1;
build(l, mid, rt << 1);
build(mid + 1, r, rt << 1 | 1);
tree[rt].w = max(tree[rt << 1].w, tree[rt << 1 | 1].w);
}
void update(int l, int r, int rt, int pos, int w){
if(l == r){
tree[rt].w = w;
return;
}
int mid = (l + r) >> 1;
if(pos <= mid){
update(l, mid, rt << 1, pos, w);
}
else{
update(mid + 1, r, rt << 1 | 1, pos, w);
}
tree[rt].w = max(tree[rt << 1].w, tree[rt << 1 | 1].w);
}
void query(int l, int r, int rt, int L, int R){
if(L <= l && R >= r){
ans = max(tree[rt].w, ans);
return;
}
int mid = (l + r) >> 1;
if(R <= mid){
query(l, mid, rt << 1, L, R);
}
else if(L > mid){
query(mid + 1, r, rt << 1 | 1, L, R);
}
else{
query(l, mid, rt << 1, L, R);
query(mid + 1, r, rt << 1 | 1, L, R);
}
}
int main(){
int n, m;
while(~scanf("%d %d", &n, &m)){
build(1, n, 1);
rep(i, m){
char q;
int x, y;
getchar();
scanf("%c %d %d", &q, &x, &y);
//printf("hahaha:%c\n", q);
if(q == 'U')
update(1, n, 1, x, y);
else{
ans = 0;
query(1, n, 1, x, y);
printf("%d\n", ans);
}
}
}
return 0;
}