Skip to content

Commit

Permalink
Sparse Table
Browse files Browse the repository at this point in the history
  • Loading branch information
userr2232 committed Oct 14, 2021
1 parent 5836588 commit 45d16d3
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 23 deletions.
36 changes: 36 additions & 0 deletions CSES/1647v2.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef vector<int> vi;

class SparseTable {
private:
vector<vi> SpT;
int N, LOG;
public:
SparseTable(const vi& A) {
N = A.size();
LOG = 31 - __builtin_clz(N)+1;
SpT.resize(N, vi(LOG));
for(int i = 0; i < N; ++i) SpT[i][0] = A[i];
for(int j = 1; j < LOG; ++j) for(int i = 0; i + (1<<j) - 1 < N; ++i) {
SpT[i][j] = min(SpT[i][j-1], SpT[i+(1<<(j-1))][j-1]);
}
}

int RMQ(int L, int R) {
int k = 31 - __builtin_clz(R-L+1);
return min(SpT[L][k], SpT[R-(1<<k)+1][k]);
}
};

int main() {
int n, q; cin >> n >> q;
vi v(n); for(auto& e : v) cin >> e;
SparseTable table(v);
for(int i = 0; i < q; ++i) {
int L, R; cin >> L >> R;
cout << table.RMQ(L-1, R-1) << endl;
}
}
38 changes: 15 additions & 23 deletions Study/sparse_table.cc
Original file line number Diff line number Diff line change
@@ -1,36 +1,28 @@
#include <iostream>
#include <vector>
#define FOR(i,a,b) for(int i = a; i <= b; ++i)
using namespace std;
typedef vector<int> vi;

classSparseTable {
class SparseTable {
private:
vi A, L2, P2;,
vector<vi> SpT;
vi A;
vector<vector<int>> SpT;
int LOG, N;
public:
SparseTable(vi& initialA) {
A = initialA;
int n = A.size();
int L2_n = log2(n)+1;
L2.assign((1<<L2_n)+1,0);
P2.assign(L2_n+1,0);
FOR(i,0,L2_n) L2[(1<<i)] = i, P2[i] = (1<<i);
FOR(i,2,P2[L2_n]) if(L2[i] == 0) L2[i] = L2[i-1];
SpT = vector<vi>(L2_n, vi(n));
FOR(i,0,n-1) SpT[0][i] = i;
for(int i = 1; P2[i] <= n; ++i)
for(int j = 0; j+P2[i]-1 < n; ++j) {
int x = SpT[i-1][j];
int y = SpT[i-1][j+P2[i-1]];
SpT[i][j] = A[x] <= A[y] ? x : y;
}
N = A.size();
LOG = 31-__builtin_clz(N)+1;
SpT.resize(N, vector<int>(LOG, 0));
for(int i = 0; i < N; ++i) SpT[i][0] = A[i];
for(int j = 1; j < LOG; ++j) for(int i = 0; i + (1<<j) - 1 < N; ++i) {
SpT[i][j] = min(SpT[i][j-1], SpT[i+(1<<(j-1))][j-1]);
}
}

int RMQ(int i, int j) {
int k = L2[j-i+1];
int x = SpT[k][i];
int y = SpT[k][j-P2[k]+1];
return A[x] <= A[y] ? x : y;
int RMQ(int L, int R) {
int len = R-L+1;
int k = 31 - __builtin_clz(len);
return min(SpT[L][k], SpT[R-(1<<k)+1][k]);
}
};

0 comments on commit 45d16d3

Please sign in to comment.