题目描述:
给出N个数,两种操作:
1、C x y:修改第x个数的值为y;
2、P x y:求第x到第y个的最大值,注:x未必比y小
输入格式:
第一行输入N和M(0<N<=200000,0<M<5000),N表示有N个数,M表示有M个操作
下来N个数
然后是M个操作。
输出格式:
遇到P操作的时候,输出结果。
样例输入:
5 6 1 2 3 4 5 P 1 5 C 3 6 P 3 4 P 4 5 C 2 9 P 1 5
样例输出:
5 6 5 9
时间限制: 1000ms
空间限制: 256MB
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N = 200005;
int a[N], tree[N * 4];
void build(int rt, int l, int r) //rt当前节点,l,r表示区间
{
if (l == r)
{
tree[rt] = a[l];
return;
}
int mid = (l + r) >> 1; // (l + r) / 2
build(rt << 1, l, mid); // rt * 2
build(rt << 1 | 1, mid + 1, r); // rt * 2 + 1
tree[rt] = max(tree[rt << 1], tree[rt << 1 | 1]);
}
void modify(int rt, int l, int r, int x, int y) //把a[x]改成y
{
if (l == r)
{
tree[rt] = y;
return;
}
int mid = (l + r) >> 1;
if (x <= mid) modify(rt << 1, l, mid, x, y);
else modify(rt << 1 | 1, mid + 1, r, x, y);
tree[rt] = max(tree[rt << 1], tree[rt << 1 | 1]);
}
int query(int rt, int l, int r, int x, int y)
{
if (x <= l && r <= y) return tree[rt]; //当前线段树节点代表的区间在询问区间内部
int mid = (l + r) >> 1;
int ans = -1e9;
if (x <= mid) ans = max(ans, query(rt << 1, l, mid, x, y));
if (y > mid) ans = max(ans, query(rt << 1 | 1, mid + 1, r, x, y));
return ans;
}
int main()
{
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
build(1, 1, n);
for (int i = 1; i <= m; i++)
{
char ope[10];
int x, y;
scanf("%s%d%d", ope, &x, &y);
if (ope[0] == 'C') modify(1, 1, n, x, y);
else
{
if (x > y) swap(x, y);
printf("%d\n", query(1, 1, n, x, y));
}
}
return 0;
}