TOP > データ構造 永続配列(Persistent-Array) 2018/08/19 • ei1333 説明 $N$ 分木による永続配列。 計算量 $O(\log_{\mathrm{LOG}} N)$ 実装例 PersistentArray< T, LOG >(): LOG 分木の型 T の永続配列を宣言する get($k$): 現在の配列の $k$ 番目の要素を返す mutable_get($k$): 現在の配列の $k$ 番目の要素へのポインタを返す build($v$): $v$ をもとに永続配列を構築する template< typename T, int LOG > struct PersistentArray { struct Node { T data; Node *child[1 << LOG] = {}; Node() {} Node(const T &data) : data(data) {} }; Node *root; PersistentArray() : root(nullptr) {} T get(Node *t, int k) { if(k == 0) return t->data; return get(t->child[k & ((1 << LOG) - 1)], k >> LOG); } T get(const int &k) { return get(root, k); } pair< Node *, T * > mutable_get(Node *t, int k) { t = t ? new Node(*t) : new Node(); if(k == 0) return {t, &t->data}; auto p = mutable_get(t->child[k & ((1 << LOG) - 1)], k >> LOG); t->child[k & ((1 << LOG) - 1)] = p.first; return {t, p.second}; } T *mutable_get(const int &k) { auto ret = mutable_get(root, k); root = ret.first; return ret.second; } Node *build(Node *t, const T &data, int k) { if(!t) t = new Node(); if(k == 0) { t->data = data; return t; } auto p = build(t->child[k & ((1 << LOG) - 1)], data, k >> LOG); t->child[k & ((1 << LOG) - 1)] = p; return t; } void build(const vector< T > &v) { root = nullptr; for(int i = 0; i < v.size(); i++) { root = build(root, v[i], i); } } };