RMQ--st算法

使用nlogn的时间和空间进行预处理,A[i][j]储存的为从i开始的2^j个元素中的最值。

代码未经编译,仅供参考

class ST {
 public:
  ST(vector<int> vals) : vals_(vals) {
    maxes_.resize(vals.size());
    mines_.resize(vals.size());
  }

  void Init() {
    int size = vals_.size();
    for (int i = 0; i < size; ++i) {
      maxes_[i].push_back(vals_[i]);
      mines_[i].push_back(vals_[i]);
    }   

    for (int i = 1; i <= log(size); ++i) {
      for (int j = 0; j < size; ++j) {
        if (j + pow(2, i - 1) >= size) break;
        int max = 0;
        int min = 0;
        if (maxes_[j + pow(2, i - 1)].size() < i) {
          max = max(maxes_[j][i - 1], maxes_[j + pow(2, i - 1)].back());
        } else {
          max = max(maxes_[j][i - 1], maxes_[j + pow(2, i - 1)][i - 1]);
        }   
        if (mines_[j + pow(2, i - 1)].size() < i) {
          min = min(mines_[j][i - 1], mines_[j + pow(2, i - 1)].back());
        } else {
          min = min(mines_[j][i - 1], mines_[j + pow(2, i - 1)][i - 1]);
        }   
        maxes_[j].push_back(max);
        mines_[j].push_back(min);
      }   
    }   
  }

  int GetMin(int pos_a, int pos_b) {
    int range = pos_b - pos_a + 1;
    int pos = pos_b;
    int min = 0xfffffff;
    while (range > 0) {
      int tmp = range & (range - 1); 
      int len = range - tmp;
      min = min(min, mines_[pos - len + 1][log(len)]);
      range = tmp;
    }   
    return min;
  }

  int GetMax(int pos_a, int pos_b) {
    int range = pos_b - pos_a + 1;
    int pos = pos_b;
    int max = -0xfffffff;
    while (range > 0) {
      int tmp = range & (range - 1); 
      int len = range - tmp;
      max = max(max, mines_[pos - len + 1][log(len)]);
      range = tmp;
    }   
    return max;
  }

 private:
  vector<int> vals_;
  vector<vector<int> > maxes_;
  vector<vector<int> > mines_;
};

 

posted @ 2013-08-22 17:09  dmthinker  阅读(119)  评论(0)    收藏  举报