链接:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1752
思路:线段树;
代码如下:
/**
* 单点更新(单点值直接替换为另一个值)),查询区间最大值
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <algorithm>
#define RST(N)memset(N, 0, sizeof(N))
using namespace std;
#define LSON l, m, rt<<1
#define RSON m+1, r, (rt<<1)|1
const int MAXN = 111111;
int maxn[MAXN<<2];
int posn[MAXN<<2];
///把当前节点的信息更新到父节点
void pushUp(int rt)
{
if (maxn[rt<<1] > maxn[rt<<1|1]) {
maxn[rt] = maxn[rt<<1];
posn[rt] = posn[rt<<1];
}else {
maxn[rt] = maxn[rt<<1|1];
posn[rt] = posn[rt<<1|1];
}
}
///建树
void build(int l, int r, int rt)
{
if(l == r) {
scanf("%d", &maxn[rt]);
posn[rt] = l;
}else {
int m = (l + r) >> 1;
build(LSON);
build(RSON);
pushUp(rt);
}
}
///更新单点值(单点值直接替换为另一个值)
void update(int p, int val, int l, int r, int rt)
{
if (l == r) {
maxn[rt] = val;
}else {
int m = (l + r) >> 1;
if (p <= m) {
update(p, val, LSON);
}else {
update(p, val, RSON);
}
pushUp(rt);
}
}
///查询区间最大值
int query(int L, int R, int l, int r, int rt, int *pos)
{
if (L <= l && r <= R) {
*pos = posn[rt];
return maxn[rt];
}else {
int m = (l + r) >> 1;
int ret1 = INT_MIN, ret2 = INT_MIN;
int pa, pb;
int *pos1 = &pa, *pos2 = &pb;
if (L <= m) {
ret1 = query(L, R, LSON, pos1);
}
if (R > m) ret2 = query(L, R, RSON, pos2);
if (ret1 > ret2) {
*pos = pa;
}else {
*pos = pb;
ret1 = ret2;
}
return ret1;
}
}
int main()
{
int n, m, a, b;
while (~scanf("%d", &n)) {
build(1, n, 1);
scanf("%d", &m);
char op[2];
while(m--) {
scanf("%s", op);
if (op[0] == 'Q') {
int pos;
printf("%d %d\n", pos, query(1, n, 1, n, 1, &pos));
}else {
scanf("%d%d", &a, &b);
update(a, b, 1, n, 1);
}
}
printf("\n");
}
return 0;
}