链接: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; }