:heavy_check_mark: SparseTable
(data_structure/sparse_table.hpp)

Depends on

Required by

Verified with

Code

#pragma once
#include<vector>
#include<functional>
#include<cmath>
#include<algorithm>
#include"../alga/maybe.hpp"
/**
 * @brief SparseTable
 */

template<typename T,typename F>
class sparse_table{
    F f;
    std::vector<std::vector<T>>data;
    public:
    sparse_table(std::vector<T> v,F f=F()):f(f){
        int n=v.size(),log=log2(n)+1;
        data.resize(n,std::vector<T>(log));
        for(int i=0;i<n;i++)data[i][0]=v[i];
        for(int j=1;j<log;j++)for(int i=0;i+(1<<(j-1))<n;i++){
            data[i][j]=f(data[i][j-1],data[i+(1<<(j-1))][j-1]);
        }
    }
    maybe<T> get(int l,int r){
        if(l==r)return maybe<T>();
        if(r<l)std::swap(l,r);
        int k=std::log2(r-l);
        return maybe<T>(f(data[l][k],data[r-(1<<k)][k]));
    }
};
#line 2 "data_structure/sparse_table.hpp"
#include<vector>
#include<functional>
#include<cmath>
#include<algorithm>
#line 2 "alga/maybe.hpp"
#include<cassert>

/**
 * @brief Maybe
 * @see https://ja.wikipedia.org/wiki/%E3%83%A2%E3%83%8A%E3%83%89_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)#Maybe%E3%83%A2%E3%83%8A%E3%83%89
 */

template<typename T>
struct maybe{
    bool _is_none;
    T val;
    maybe():_is_none(true){}
    maybe(T val):_is_none(false),val(val){}
    T unwrap()const{
        assert(!_is_none);
        return val;
    }
    T unwrap_or(T e)const{
        return _is_none?e:val;
    }
    bool is_none()const{return _is_none;}
    bool is_some()const{return !_is_none;}
};

template<typename T,typename F>
auto expand(F op){
    return [&op](const maybe<T>& s,const maybe<T>& t){
        if(s.is_none())return t;
        if(t.is_none())return s;
        return maybe<T>(op(s.unwrap(),t.unwrap()));
    };
}
#line 7 "data_structure/sparse_table.hpp"
/**
 * @brief SparseTable
 */

template<typename T,typename F>
class sparse_table{
    F f;
    std::vector<std::vector<T>>data;
    public:
    sparse_table(std::vector<T> v,F f=F()):f(f){
        int n=v.size(),log=log2(n)+1;
        data.resize(n,std::vector<T>(log));
        for(int i=0;i<n;i++)data[i][0]=v[i];
        for(int j=1;j<log;j++)for(int i=0;i+(1<<(j-1))<n;i++){
            data[i][j]=f(data[i][j-1],data[i+(1<<(j-1))][j-1]);
        }
    }
    maybe<T> get(int l,int r){
        if(l==r)return maybe<T>();
        if(r<l)std::swap(l,r);
        int k=std::log2(r-l);
        return maybe<T>(f(data[l][k],data[r-(1<<k)][k]));
    }
};
Back to top page