hihoCoder#1077 RMQ问题再临-线段树

原题地址

 

终于做到线段树的题了,因为建树、更新、查询都是递归操作,所以其实挺好写的。

用数组存的树,记得MAX_NODE开成两倍叶节点数大小,否则RE啊。。不要问我是怎么知道的。

 

代码:

  1 #include <iostream>

  2 #include <climits>

  3 using namespace std;

  4 

  5 #define MAX_NODE 2000008

  6 

  7 int N, Q;

  8 

  9 struct SegmentTree {

 10   int left[MAX_NODE];

 11   int right[MAX_NODE];

 12   int begin[MAX_NODE];

 13   int end[MAX_NODE];

 14   int value[MAX_NODE];

 15   int root;

 16   int size;

 17 

 18   void init() {

 19     size = 1;

 20     left[0] = right[0] = root = 0;

 21     value[0] = INT_MAX;

 22   }

 23 

 24   int insert(int v) {

 25     value[size] = v;

 26     size++;

 27     return size - 1;

 28   }

 29 

 30   int _build(int l, int r) {

 31     if (l > r)

 32       return 0;

 33     if (l == r) {

 34       left[l] = right[l] = 0;

 35       begin[l] = end[l] = l;

 36       return l;

 37     }

 38 

 39     int lc = _build(l, (l + r) / 2);

 40     int rc = _build((l + r) / 2 + 1, r);

 41     int me = insert(-1);

 42     left[me] = lc;

 43     right[me] = rc;

 44     begin[me] = l;

 45     end[me] = r;

 46     value[me] = min(value[lc], value[rc]);

 47 

 48     return me;

 49   }

 50 

 51   void build() {

 52     root = _build(1, size - 1);

 53   }

 54 

 55   int _query(int n, int l, int r) {

 56     if (begin[n] == l && end[n] == r)

 57       return value[n];

 58     int medium = (begin[n] + end[n]) / 2;

 59     if (r <= medium)

 60       return _query(left[n], l, r);

 61     if (l > medium)

 62       return _query(right[n], l, r);

 63     return min(_query(left[n], l, medium), _query(right[n], medium + 1, r));

 64   }

 65 

 66   int query(int l, int r) {

 67     return _query(root, l, r);

 68   }

 69 

 70   void _update(int n, int p, int v) {

 71     if (begin[n] == p && end[n] == p) {

 72       value[p] = v;

 73       return;

 74     }

 75     int medium = (begin[n] + end[n]) / 2;

 76     if (p <= medium)

 77       _update(left[n], p, v);

 78     if (p > medium)

 79       _update(right[n], p, v);

 80     value[n] = min(value[left[n]], value[right[n]]);

 81   }

 82 

 83   void update(int p, int v) {

 84     _update(root, p, v);

 85   }

 86 } st;

 87 

 88 int main() {

 89   st.init();

 90 

 91   scanf("%d", &N);

 92   for (int i = 0; i < N; i++) {

 93     int v;

 94     scanf("%d", &v);

 95     st.insert(v);

 96   }

 97 

 98   st.build();

 99 

100   scanf("%d", &Q);

101   while (Q--) {

102     int t, a, b;

103     scanf("%d%d%d", &t, &a, &b);

104     if (t)

105       st.update(a, b);

106     else

107       printf("%d\n", st.query(a, b));

108   }

109 

110   return 0;

111 }

 

你可能感兴趣的:(code)