13年黑龙江省 省赛选拔赛 G题 (线段树)

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




你可能感兴趣的:(线段树,11年省赛)