Kyopro Library
 
読み取り中…
検索中…
一致する文字列を見つけられません
sparse_table_disjoint.hpp
[詳解]
1#include "../../kyopro_library/template.hpp"
2
3/// @brief スパーステーブル(Disjoint)
4/// @tparam Semigroup 半群(結合則が成り立つこと)
5template<typename Semigroup>
7 using Type=typename Semigroup::Type;
9
10 /// @brief 配列 v からDisjoint Sparse Tableを構築する
11 /// @note O(N log(N))
12 SparseTableDisjoint(const vector<Type>& v) {
13 n=v.size();
14 dat.assign(__lg(n)+1,vector<Type>(n));
15 dat[0]=v;
16 for(int i=1; i<dat.size(); i++) {
17 int w=1<<i;
18 for(int j=0; j<n; j+=w<<1) {
19 int t=min(j+w,n);
20 dat[i][t-1]=v[t-1];
21 for(int k=t-2; k>=j; k--) dat[i][k]=Semigroup::op(v[k],dat[i][k+1]);
22 if(t>=n) break;
23 dat[i][t]=v[t];
24 for(int k=t+1; k<min(j+(w<<1),n); k++) dat[i][k]=Semigroup::op(dat[i][k-1],v[k]);
25 }
26 }
27 }
28
29 /// @brief 区間 [l, r) の半群積を返す
30 /// @note O(1)
31 Type fold(int l, int r) {
32 r--;
33 if(l==r) return dat[0][l];
34 int i=__lg(l^r);
35 return Semigroup::op(dat[i][l],dat[i][r]);
36 }
37
38 /// @brief i 番目の要素を返す
39 Type operator[](int i) const { return fold(i,i+1); }
40
41 /// @brief 配列のサイズを返す
42 int size() { return n; }
43
44private:
45 int n;
46 vector<vector<Type>> dat;
47};
スパーステーブル(Disjoint)
int size()
配列のサイズを返す
SparseTableDisjoint(const vector< Type > &v)
配列 v からDisjoint Sparse Tableを構築する
Type fold(int l, int r)
区間 [l, r) の半群積を返す
Type operator[](int i) const
i 番目の要素を返す
SparseTableDisjoint()=default