CP-Snippets

Sparse-General

template<class T>
class sparseTable
{
    public:
    int n,k;
    vector<vector<T>> table;
    vector<T> logs;
    function<T(T,T)> operation;
    void init(int x,function<T(T,T)> _operation)
    {  
            operation=_operation;
            n=x;
            logs.resize(n+1);
            logs[1]=0;
            for(int i=2;i<=n;i++)
                    logs[i]=logs[i/2]+1;
            k=*max_element(logs.begin(),logs.end());
            table.resize(k+1,vector<T>(n));
    }

    void build(vector<T> &arr)
    {
        for(int i=0;i<n;i++)
                table[0][i]=arr[i];
 
        for(int j=1;j<=k;j++)
        {
            for(int i=0;i+(1<<j)<=n;i++)
                table[j][i]=operation(table[j-1][i],table[j-1][i+(1<<(j-1))]);
        }
    }
    // 1 based indexing
    T query(int l , int r)
    {
        assert(l<=r);
        assert(l>=0 && r<n);
        int j = logs[r - l + 1];
        T answer = operation(table[j][l], table[j][r-(1<<j)+1]);
        return answer;
    }
};


// does not have a constructor, make an instance and then use the init method to use this