ํ์ ํธ๋ฆฌ(Fenwick Tree)
ํ์ ํธ๋ฆฌ๋ ๋ฐ์ด๋๋ฆฌ ์ธ๋ฑ์ค ํธ๋ฆฌ(Binary Indexed Tree)๋ผ๊ณ ๋ ๋ถ๋ฅธ๋ค. ์์๋ฅผ ๊ฐ๋ ๋ฐ์ดํฐ๊ฐ ์ฃผ์ด์ก์ ๋, ๊ตฌ๊ฐ์ ๋ํ ๊ฐ์ด๋ ์ฐ์ฐ ๊ฒฐ๊ณผ๋ฅผ ๋น ๋ฅด๊ฒ ์ป์ ์ ์๋ ํธ๋ฆฌ ํํ์ ์๋ฃ๊ตฌ์กฐ์ด๋ค.
๊ธฐ๋ณธ ์๋ฆฌ
https://www.acmicpc.net/blog/view/21
ํ์ ํธ๋ฆฌ (๋ฐ์ด๋๋ฆฌ ์ธ๋ฑ์ค ํธ๋ฆฌ)
๋ธ๋ก๊ทธ: ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ (Segment Tree) ์์ ํ์ด๋ณธ ๋ฌธ์ ๋ฅผ Fenwick Tree๋ฅผ ์ด์ฉํด์ ํ์ด๋ณด๊ฒ ์ต๋๋ค. Fenwick Tree๋ Binary Indexed Tree๋ผ๊ณ ๋ ํ๋ฉฐ, ์ค์ฌ์ BIT๋ผ๊ณ ํฉ๋๋ค. Fenwick Tree๋ฅผ ๊ตฌํํ๋ ค๋ฉด, ์ด๋ค ์ X
www.acmicpc.net
ํ์ ํธ๋ฆฌ๋ฅผ ๊ตฌํํ๊ธฐ ์ํด์ ์ด๋ค ์๋ฅผ ์ด์ง์๋ก ๋ํ๋์ ๋ ๋ง์ง๋ง 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
2042๋ฒ: ๊ตฌ๊ฐ ํฉ ๊ตฌํ๊ธฐ
์ฒซ์งธ ์ค์ ์์ ๊ฐ์ N(1 ≤ N ≤ 1,000,000)๊ณผ M(1 ≤ M ≤ 10,000), K(1 ≤ K ≤ 10,000) ๊ฐ ์ฃผ์ด์ง๋ค. M์ ์์ ๋ณ๊ฒฝ์ด ์ผ์ด๋๋ ํ์์ด๊ณ , K๋ ๊ตฌ๊ฐ์ ํฉ์ ๊ตฌํ๋ ํ์์ด๋ค. ๊ทธ๋ฆฌ๊ณ ๋์งธ ์ค๋ถํฐ N+1๋ฒ์งธ ์ค
www.acmicpc.net
#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
2934๋ฒ: LRH ์๋ฌผ
์๊ทผ์ด๋ ์ ์ ์ ์กฐ์์ ํตํด ์ค๊ธฐ ๋ ๊ฐ๋ก ์ด๋ฃจ์ด์ง ์๋ฌผ์ ๋ง๋ค์๋ค. ์ด ์๋ฌผ์ ์ค๊ธฐ์ x์ขํ L, R๊ณผ ๋์ด H๋ก ๋ํ๋ผ ์ ์๋ค. ์๋ ๊ทธ๋ฆผ์ L=2, R=5, H=4์ธ ์๋ฌผ์ด๋ค. ์๊ทผ์ด๋ ๋งค์ผ ๋งค์ผ ํ๋จ์
www.acmicpc.net
#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
5419๋ฒ: ๋ถ์ํ
๊ฐ ํ ์คํธ ์ผ์ด์ค์ ๋ํด์, ๋ถ์ํ์ ํ๊ณ ํญํดํ ์ ์๋ ์ฌ์ ์์ ์๋ฅผ ์ถ๋ ฅํ๋ค.
www.acmicpc.net
#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";
}
}