インデックスツリー
Index Tree
飽和バイナリツリーデータ構造を用いて区間特徴値(および、乗算、最大、最小、gcdなど)を処理する
時間の複雑さ
point update : LIS(Least Incresing Subsequence) LCA(Least Common A Subsequence)
飽和バイナリツリーデータ構造を用いて区間特徴値(および、乗算、最大、最小、gcdなど)を処理する
時間の複雑さ
point update :
O(logN)
range query : O(logN)
区間和、区間積サンプルコード#define ll long long
int n; //수열의 수 및 노드의 수
vector<ll> tree;
int offset;
void construct(){
for(offset = 1; offset < n; offset <<= 1);
tree.resize(offset + offset--, 0);
}
ll sum(int s, int e){
s += offset; e += offset;
ll ret = 0;
while(s <= e){
if(s % 2 == 1) ret += tree[s++];
if(e % 2 == 0) ret += tree[e--];
s >>= 2;
e >>= 2;
}
return ret;
}
void sumUpdate(int idx, ll val){
idx += offset;
tree[idx] = val;
while((idx >>= 1) > 0){
tree[idx] = tree[idx << 1] + tree[(idx << 1) + 1];
}
}
ll mul(int s, int e){
s += offset; e += offset;
ll ret = 0;
while(s <= e){
if(s % 2 == 1) ret *= tree[s++];
if(e % 2 == 0) ret *= tree[e--];
s >>= 1;
e >>= 1;
}
return ret;
}
void mulUpdate(int idx, ll val){
idx += offset;
tree[idx] = val;
while((idx >>= 1) > 0){
tree[idx] = tree[idx << 1] * tree[(idx << 1) + 1];
}
}
区間最大、最小サンプルコード#define INT_MAX 0x7fffffff
#define ll long long
int n; //수열의 수 및 노드의 수
vector<ll> maxTree;
vector<ll> minTree;
int offset;
void construct(){
for(offset = 1; offset < n; offset <<= 1);
maxTree.resize(offset + offset, 0);
minTree.resize(offset + offset--, INT_MAX);
}
void minUpdate(int idx, int val){
idx += offset;
minTree[idx] = val;
while((idx >>= 1) > 0){
minTree[idx] = min(minTree[idx << 1], minTree[(idx << 1) + 1];
}
}
int getMin(int s, int e){
s += offset;
e += offset;
int ret = INT_MAX;
while(s <= e){
ret = min(ret, min(minTree[s++], minTree[e--]));
s >>= 1;
e >>= 1;
}
return ret;
}
void maxUpdate(int idx, int val){
idx += offset;
maxTree[idx] = val;
while((idx >>= 1) > 0){
maxTree[idx] = max(maxTree[idx << 1], maxTree[(idx << 1) + 1];
}
}
int getMax(int s, int e){
s += offset;
e += offset;
int ret = 0;
while(s <= e){
ret = max(ret, max(maxTree[s++], maxTree[e--]));
s >>= 1;
e >>= 1;
}
return ret;
}
区間最大公約数例コード#define ll long long
int n;
vector<int> tree;
int offset;
int seq[10] = {4, 2, 3, 5, 6, 5, 8, 8, 10, 12};
int gcd(int a, int b){
return b == 0 ? a : gcd(b, a % b);
}
void construct(){
for(offset = 1; offset < n; offset <<= 1);
tree.resize(offset + offset--, 0);
for(int i = 1; i <= n; i++) tree[i + offset] = seq[i - 1];
for(int i = offset; i > 0; i--) tree[i] = gcd(tree[i << 1], tree[(i << 1) + 1];
}
int query(int s, int e){
s += offset; e += offset;
int ret = tree[s];
while(s <= e){
if(s % 2 == 1) ret = gcd(ret, tree[s++]);
if(e % 2 == 0) ret = gcd(ret, tree[e--]);
s >>= 1;
e >>= 1;
}
return ret;
}
適用Reference
この問題について(インデックスツリー), 我々は、より多くの情報をここで見つけました https://velog.io/@rxjw95/그래프Index-Treeテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol