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