ํ์ ํธ๋ฆฌ(Fenwick Tree)
ํ์ ํธ๋ฆฌ๋ ๋ฐ์ด๋๋ฆฌ ์ธ๋ฑ์ค ํธ๋ฆฌ(Binary Indexed Tree)๋ผ๊ณ ๋ ๋ถ๋ฅธ๋ค. ์์๋ฅผ ๊ฐ๋ ๋ฐ์ดํฐ๊ฐ ์ฃผ์ด์ก์ ๋, ๊ตฌ๊ฐ์ ๋ํ ๊ฐ์ด๋ ์ฐ์ฐ ๊ฒฐ๊ณผ๋ฅผ ๋น ๋ฅด๊ฒ ์ป์ ์ ์๋ ํธ๋ฆฌ ํํ์ ์๋ฃ๊ตฌ์กฐ์ด๋ค.
๊ธฐ๋ณธ ์๋ฆฌ
https://www.acmicpc.net/blog/view/21
ํ์ ํธ๋ฆฌ๋ฅผ ๊ตฌํํ๊ธฐ ์ํด์ ์ด๋ค ์๋ฅผ ์ด์ง์๋ก ๋ํ๋์ ๋ ๋ง์ง๋ง 1์ ์์น๋ฅผ ์์์ผ ํ๋ค.
๋ง์ง๋ง 1์ด ๋ํ๋ด๋ ๊ฐ์ L[i]๋ผ๊ณ ํํํ ๋, L[3] = 1, L[10] = 2, L[12] = 4์ด ๋๋ค. ์ด๋, ์ง์๋ 0์ ๊ฐฏ์(num)๋ก ์ ํด์ง๋ค. (L[i] = 2^num)
์๋ ๊ทธ๋ฆผ์ ๊ฐ i์ ๋ํด L[i]๋ฅผ ๋ํ๋ธ ํ์ด๋ค.
์ N๊ฐ๋ฅผ A[1] ~ A[N]์ด๋ผ๊ณ ํ์ ๋, Tree[i]๋ A[i]๋ถํฐ ์์ผ๋ก L[i]๊ฐ์ ํฉ์ด ์ ์ฅ๋์ด ์๋ค.์๋ฅผ ๋ค์ด, Tree[12]์๋ A[12]๋ถํฐ ์์ผ๋ก L[12] = 4๊ฐ์ ํฉ์ธ A[9] + A[10] + A[11] + A[12]๊ฐ ์ ์ฅ๋์ด ์๋ค.
์๋ ๊ทธ๋ฆผ์ ๊ฐ i์ ๋ํด Tree[i]๋ฅผ ๋ํ๋ธ ํ์ด๋ค.
https://www.acmicpc.net/problem/2042
#include <iostream>
#include <vector>
using namespace std;
long long sum(vector<long long>& tree, int index)
{
// ํฉ ๊ตฌํ๊ธฐ
// index๋ฅผ ์ด์ง์๋ก ๋ํ๋ธ ๋ค ๋นํธ ๋ด 1์ด ์์ด์ง ๋๊น์ง ๋ํ๋ค.
// index = 13์ผ ๋, A[1] + ... + A[13] = tree[1101] + tree[1100] + tree[1000]
long long ans = 0;
while (index > 0) {
ans += tree[index];
index -= (index & -index); // ์ตํ์ ๋นํธ(1) ์ง์ฐ๊ธฐ
}
return ans;
}
void update(vector<long long>& tree, int index, long long value)
{
// ๋ณ๊ฒฝ
// sum๊ณผ ๋ฐ๋๋ก ์ตํ์ ๋นํธ์ 1์ ๋ํ๋ค.
while (index < tree.size()) {
tree[index] += value;
index += (index & -index);
}
}
int main()
{
int n, m, k;
cin >> n >> m >> k;
vector<long long> arr(n + 1), tree(n + 1);
for (int i = 1; i <= n; i++) {
cin >> arr[i];
update(tree, i, arr[i]);
}
m += k;
while (m--) {
int num;
cin >> num;
if (num == 1) {
int index;
long long val;
cin >> index >> val;
long long diff = val - arr[index];
arr[index] = val;
update(tree, index, diff);
}
else if (num == 2) {
int left, right;
cin >> left >> right;
cout << sum(tree, right) - sum(tree, left - 1) << '\n';
}
}
}
๋ฌธ์
https://www.acmicpc.net/problem/2934
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
vector<ll> tree(200001);
int sum(int index)
{
int ans = 0;
while (index > 0) {
ans += tree[index];
index -= index & -index;
}
return ans;
}
void update(int index, int num)
{
while (index <= tree.size()) {
tree[index] += num;
index += index & -index;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int n;
cin >> n;
while (n--) {
int a, b;
cin >> a >> b;
int sumA = sum(a), sumB = sum(b);
cout << sumA + sumB << '\n';
// ๊ธฐ๋ณธ ์๋ฆฌ
// [a, b] ๊ตฌ๊ฐ์ 1์ ๋ํ๋ ค๋ฉด
// a๋ถํฐ 1์ ๋ํ ํ (update(a, 1)) b+1๋ถํฐ -1์ ๋นผ๋ฉด ๋๋ค. (update(b+1, -1))
// ๊ฝ์ด ํ ๊ณณ์๋ ๋ค์ ํผ์ง ์์ผ๋ฏ๋ก 0์ผ๋ก ๋ง๋ ๋ค.
update(a, -sumA); // a๋ง -sumA๊ฐ ์ ์ฉ๋๋ค.
update(a + 1, sumA);
update(b, -sumB); // b๋ง -sumB๊ฐ ์ ์ฉ๋๋ค.
update(b + 1, sumB);
// ๊ฝ์ด ํ์์๋ ๊ตฌ๊ฐ์ 1์ ๋ฃ๋๋ค.
update(a + 1, 1); // a~b์ 1์ ๋ํ๋ค.
update(b, -1);
}
}
https://www.acmicpc.net/problem/5419
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
class Point {
public:
int x, y;
int index; // x์ขํ ํฌ๊ธฐ ์์
};
int sum(vector<int>& tree, int index)
{
int ans = 0;
while (index > 0) {
ans += tree[index];
index -= (index & -index);
}
return ans;
}
void update(vector<int>& tree, int index, int value)
{
while (index < tree.size()) {
tree[index] += value;
index += (index & -index);
}
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
vector<Point> v;
vector<int> tree(n + 1);
for (int i = 0; i < n; i++) {
Point data;
cin >> data.x >> data.y;
v.push_back(data);
update(tree, i + 1, 1); // ํ์
ํธ๋ฆฌ ๊ฐฑ์
}
// ์ขํ ์์ถ
sort(v.begin(), v.end(), [](auto& a, auto& b) {
if (a.x == b.x)
return a.y > b.y;
return a.x < b.x;
});
for (int i = 0; i < n; i++)
v[i].index = i;
sort(v.begin(), v.end(), [](auto& a, auto& b) {
if (a.y == b.y)
return a.x < b.x;
return a.y > b.y;
});
// ํ์
ํธ๋ฆฌ
long long total = 0;
for (int i = 0; i < v.size(); i++) {
total += sum(tree, n) - sum(tree, v[i].index + 1);
update(tree, v[i].index + 1, -1);
}
cout << total << "\n";
}
}