ホームに戻る
 Sparse Table

// 最初に init することで、
// O(1) で範囲内の最小値のインデックスを検索する。

// セグメント木との違いは途中で要素の書き換えができないこと。

// 使用する最大要素数 1<<N_MAX を設定すること。

// seg.init(v);  // vectorを設定。init時に内部でコピーする。
// seg.get_index(l,r);  // l <= x <= r での最小値のインデックスを返す。
// 複数ある場合は最も左のものを返す。

// 最大値を返す、最も右のものを返すに書き換え可能。

// 最小探索(最も左のものを返す)

#define N_MAX 17

struct stmnl{
  long long nn;
  long long dat[1<<N_MAX][N_MAX];
  vector<ll> v;

  void init(vector<long long> &v_){
    v = v_;
    for(int i = 0; i < v.sz; i++){
      dat[i][0] = i;
    }
    for(int i = 1; (1LL<<i) < v.size(); i++){
      int d = 1<<i;
      int d1 = d>>1;
      for(int j = 0; j < v.size()-d+1; j++){
        if(v[dat[j][i-1]]<=v[dat[j+d1][i-1]]){
          dat[j][i] = dat[j][i-1];
        }
        else{
          dat[j][i] = dat[j+d1][i-1];
        }
      }
    }
  }
  int get_index(int l, int r){
    int d = log2(r-l+1);
    if(v[dat[l][d]]<=v[dat[r-(1<<d)+1][d]]){
      return dat[l][d];
    }
    else{
      return dat[r-(1<<d)+1][d];
    }
  }
}stmnl1;

// 最小探索(最も右のものを返す)

#define N_MAX 17

struct stmnr{
  long long nn;
  long long dat[1<<N_MAX][N_MAX];
  vector<ll> v;

  void init(vector<long long> &v_){
    v = v_;
    for(int i = 0; i < v.sz; i++){
      dat[i][0] = i;
    }
    for(int i = 1; (1LL<<i) < v.size(); i++){
      int d = 1<<i;
      int d1 = d>>1;
      for(int j = 0; j < v.size()-d+1; j++){
        if(v[dat[j+d1][i-1]]<=v[dat[j][i-1]]){
          dat[j][i] = dat[j+d1][i-1];
        }
        else{
          dat[j][i] = dat[j][i-1];
        }
      }
    }
  }
  int get_index(int l, int r){
    int d = log2(r-l+1);
    if(v[dat[r-(1<<d)+1][d]]<=v[dat[l][d]]){
      return dat[r-(1<<d)+1][d];
    }
    else{
      return dat[l][d];
    }
  }
}stmnr1;
inserted by FC2 system