μΆμ²: https://cp-algorithms.com/data_structures/fenwick.html
Let, be some reversible function and A be an array of integers of length N.
νμ νΈλ¦¬λ λ€μκ³Ό κ°μ μλ£κ΅¬μ‘°λ₯Ό λ§νλ€.
νμ
νΈλ¦¬λ Binary Indexed Tree
λΌκ³ λ λΆλ₯Έλ€. λ³΄ν΅ range sumμ ꡬν λ λ§μ΄ μ¬μ©νλ€.
λ°°μ΄ κ° μλ€κ³ νμ. νμ νΈλ¦¬λ λ°°μ΄ μ΄κ³ κ° μμλ λ°°μ΄ μ μ ν©μ λμλλ€.
β
λ°°μ΄ λ λ°°μ΄μ΄μ§λ§ λ§€μ° π nice νκ² νΈλ¦¬λ‘ ννν μ μλ€. νμ νΈλ¦¬μμ νμν κ²μ λΏμ΄κ³ λͺ¨λ 쿼리λ₯Ό μ²λ¦¬ν μ μλ€.
// [0:r]κΉμ§ sum
def sum(int r):
result = 0
while (r>=0)
res += t[r]
r = g(r) - 1
return res
// update A[i] = A[i] + delta
def increase(int i, int delta):
for all j with g(j) <= i <= j:
t[j] += delta
ν¨μ sum
μ λ€μκ³Ό κ°μ΄ λμνλ€:
result
μ κΉμ§μ ν©μ λνλ€. ν¨μ increase
λ λ€μκ³Ό κ°μ΄ λμνλ€. = update
λ€μμ λ§μ‘±νλ κΉμ§μ ν©μ ꡬνλ€.
λ₯Ό λ§μ‘±νλ λ₯Ό delta
μ© μ¦κ°μν¨λ€. μ¦, t[j] += delta
.
sum
κ³Ό increase
μ μκ°λ³΅μ‘λλ ν¨μ g
μ μν₯μ λ°λλ€. λͺ¨λ μ λνμ¬ λ₯Ό λ§μ‘±νλ€λ©΄ ν¨μ λ₯Ό μ ννλ λ°©λ²μ λ§λ€. λΌκ³ μκ°ν΄λ³΄μ. κ·Έλ¬λ©΄ κ° λ λΏμ΄λ€. κ·Έλ¬λ―λ‘ λ₯Ό μ ννλ€λ©΄ ꡬκ°ν©μ ꡬνλ μκ°μ μ¬μ ν λ릴 κ²μ΄λ€.
μ ν¨μλ‘ νλ©΄ μ΄λ¨κΉ? μ΄λ κΉμ§ ν©μ ꡬνλ€λ μλ―Έμ΄λ―λ‘ μ΅ν μλ€μνΌ κ΅¬κ°ν©μ μ μ²λ¦¬ν μ μλ€. νμ§λ§ κ°±μ μ λ리λ€.
νμ μκ³ λ¦¬μ¦μ μ’μ μ μ΄ μ¬κΈ° μλ€. ν¨μ λ₯Ό νΉλ³νκ² μ μν¨μΌλ‘μ¨ κ΅¬κ°μΏΌλ¦¬μ κ°±μ μ μ μ²λ¦¬ν μ μλ€.
λ λ€μκ³Ό κ°μ΄ μ μν μ μλ€.
iλ₯Ό 2μ§μλ‘ νννμ λ, κ°μ₯ λ§μ§λ§μ λμ€λ 0μ λ€μ μλ 1μ λͺ¨λ 0μΌλ‘ λ°κΎΌλ€.
μ΄λ¬ν ν¨μ λ λ€μκ³Ό κ°μ΄ μ μν μ μλ€.
β β β
μ΄μ μ΄λ»κ² νλ©΄ μΈ λ₯Ό μ΄λ»κ² μκ³ μνν κΉ?
μκ°ν΄λ³΄λ©΄ μ½λ€. μ°μ λ₯Ό 2μ§μλ‘ νννλ€. κ·Έλ¦¬κ³ λμ μ°¨λ‘λλ‘ 0μΈ λΉνΈλ₯Ό 1λ‘ λ°κΎΌλ€. μ΄λ κ² λλ©΄ 0μΈ λΉνΈκ° 1μ΄ λμκΈ° λλ¬Έμ λ λͺ λ°±νλ€. λν λ κ°μ₯ λ§μ§λ§μΌλ‘ λμ€λ 0 λ€μ λΉνΈλ₯Ό λͺ¨λ 0μ λ°κΎΈκΈ° λλ¬Έμ μ΄λ€.
π Case:
κ·Έλ¦¬κ³ μ΄λ¬ν λ λΉνΈμ°μ°μΌλ‘ κ°λ¨νκ² κ΅¬ν μ μλ€.
β β β
μ΄λ¬ν μ°μ°μ ν΅ν΄ λ νΈλ¦¬μ ννλ₯Ό λκ² λλ€.
struct FenwickTree {
vector<int> bit;
int n;
FenwickTree(int n) {
this->n = n;
bit.assign(n, 0);
}
FenwickTree(vector<int> a):FenwickTree(a.size()) {
for(size_t i=0; i<a.size(); ++i) {
add(i, a[i]);
}
}
int sum(int r) {
int ret = 0;
for(; r>=0; r = (r & (r+1)) - 1)
ret+=bit[r];
return ret;
}
int sum(int l, int r) {
return sum(r) - sum(l-1);
}
void add(int idx, int delta) {
for(; idx<n; idx = idx | (idx+1))
bit[idex] += delta;
}
};
νμ νΈλ¦¬λ₯Ό μ΄μ©ν΄μ μμ μ΅μκ°μ μ°Ύλ μ¬μ΄ λ°©λ²μ μλ€. νμ νΈλ¦¬λ μ λν΄μλ§ μ μ μλ€.
struct FenwickTreeMin {
vector<int> bit;
int n;
const int INF = (int)1e9;
FenwickTreeMin(int n) {
this->n = n;
bit.assing(n, INF);
}
FenwickTree(vector<int> a) : FenwickTreeMin(a.size()) {
for (size_t i = 0; i < a.size(); ++i) {
update(i, a[i]);
}
}
int getMin(int r) {
int ret = INF;
for(; r >= 0; r = (r & (r+1)) - 1) {
ret = min(ret, bit[r]);
}
return ret;
}
void update(int idx, int val) {
for(; idx<n; idx = idx | (idx + 1)) {
bit[idx] = min(bit[idx], val);
}
}
}
struct FenwickTree2D {
vector<vector<int>> bit;
int n, m;
FenwickTree2D(int n, m) {
this->n = n;
this->m = m;
bit.assign(n, vector<int>(m, 0));
}
int sum(int x, int y) {
int ret = 0;
for(int i=x; i>=0; i = (i & (i+1))-1) {
for(int j=y; j>=0; j = (j & (j+1))-1)
ret += bit[i][j];
}
return ret;
}
void add(int x, int y, int delta) {
for(int i=x; i<n; i = i | (i+1)) {
for(int j=y; j<m; j = j | (j+1))
bit[i][j] += delta;
}
}
}
λ λ₯Ό μ‘°κΈ λ€λ₯΄κ² μ μν΄λ³΄μ. λ μ ν©μ μ μ₯νλ€. μ μ΄λ κ² ν κΉ? κ·Έ μ΄μ λ λ₯Ό μ΄λ κ² μ μνλ©΄ λ₯Ό π νκ² μ μν μ μλ€.
def sum(int r):
res = 0
while(r>0):
res+=t[r]
r=g(r)
return res;
def increase(int i, int delta):
for all j with g(j) < i <= j:
t[j] += delta
μ΄μ λ₯Ό λ€μκ³Ό κ°μ΄ μ μν μ μλ€.
iλ₯Ό 2μ§μλ‘ νννμ λ κ°μ₯ λ§μ§λ§μ 1μ 0μΌλ‘ λ°κΎΌλ€.
κ°μ₯ λ§μ§λ§ λΉνΈλ λ‘ ννν μ μκΈ° λλ¬Έμ λ λ€μκ³Ό κ°μ΄ ννν μ μλ€.
β ββ
λν λ λ€μκ³Ό κ°μ΄ ννν μ μλ€.
β β β
struct FenwickTreeOneBasedIndexing {
vector<int> bit;
int n;
FenwickTreeOneBasedIndexing(int n) {
this->n = n + 1;
bit.assing(n + 1, 0);
}
FenwickTreeOneBasedIndexing(vector<int> a) : FenwickTreeOneBasedIndexing(a.size()) {
init(a.size());
for(size_t i = 0; i < a.size(); ++i) {
add(i, a[i]);
}
}
int sum(int idx) {
int ret = 0;
for(++idx; idx>0; idx -= idx & -idx)
ret += bit[idx];
return ret;
}
int sum(int l, int r) {
return sum(r) - sum(l-1);
}
void add(int idx, int delta) {
for(++idx; idx<n; idx += idx & -idx)
bit[idx] += delta;
}
};
π μ΄λ»κ²
i&(-i)
κ° λ§μ§λ§ λΉνΈκ° λλμ§μ λνμ¬λΉνΈμμ μμλ₯Ό νννλ λ°©λ²μ 2μ 보μ μ΄λ€. 2μ 보μλ μ΄λ»κ² ꡬν κΉμ.
보μλ λ μμ ν©μ΄ μ§λ²μ λ°μκ° λκ² νλ μ μ΄λ€. μ»΄ν¨ν°λ λΊμ μ κ°λ μ΄ μκΈ° λλ¬Έμ λ§μ μ ν΅ν΄ μμλ₯Ό ꡬνλ€.
μ§κΈκΉμ§ νλ κ²!