[C++] ํŽœ์œ… ํŠธ๋ฆฌ(Fenwick Tree)

2021. 11. 14. 16:02ยท๐Ÿ“ Computer Science/โœ Algorithm

ํŽœ์œ… ํŠธ๋ฆฌ(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]๋ฅผ ๋‚˜ํƒ€๋‚ธ ํ‘œ์ด๋‹ค.

 

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]๋ฅผ ๋‚˜ํƒ€๋‚ธ ํ‘œ์ด๋‹ค.

 

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";
	}
}
์ €์ž‘์žํ‘œ์‹œ (์ƒˆ์ฐฝ์—ด๋ฆผ)
'๐Ÿ“ Computer Science/โœ Algorithm' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • [C++] ํฌ์†Œ ํ…Œ์ด๋ธ”(Sparse Table)
  • [C++] ์œ„์ƒ ์ •๋ ฌ(Topological Sort)
  • [C++] ์Šค์œ„ํ•‘ ์•Œ๊ณ ๋ฆฌ์ฆ˜(Sweeping Algorithm)
  • [C++] ๊ฐ•ํ•œ ์—ฐ๊ฒฐ ์š”์†Œ(ํƒ€์ž”, ์ฝ”์‚ฌ๋ผ์ฃผ)
Blxxming
Blxxming
CS ์ง€์‹๊ณผ ๊ณต๋ถ€ํ•˜๋‹ค ๋ฐฐ์šด ๊ฒƒ, ๊ฒฝํ—˜ํ•œ ๊ฒƒ ๋“ฑ์„ ๊ธฐ๋กํ•˜๋Š” ๋ธ”๋กœ๊ทธ์ž…๋‹ˆ๋‹ค.
  • Blxxming
    ๐Ÿ’ก๋ฒˆ๋œฉ๐Ÿ’ก
    Blxxming
  • ์ „์ฒด
    ์˜ค๋Š˜
    ์–ด์ œ
  • ๊ณต์ง€์‚ฌํ•ญ

    • Tech Interview
    • ๐Ÿ“š Tech (246)
      • ๐Ÿ“ Computer Science (96)
        • โœ OS (12)
        • โœ Network & Web (10)
        • โœ Database (11)
        • โœ Data Structure (6)
        • โœ Algorithm (40)
        • โœ Design Pattern (9)
        • โœ Cloud Computing (3)
        • โœ (5)
      • ๐Ÿ“ Language (73)
        • โœ Language (6)
        • โœ C & C++ (11)
        • โœ C# (19)
        • โœ JAVA (37)
      • ๐Ÿ“ Game (43)
        • โœ Computer Graphics (2)
        • โœ Unity (14)
        • โœ Unreal (26)
        • โœ (1)
      • ๐Ÿ“ Book (34)
        • โœ Effective (3)
        • โœ Game Server (16)
        • โœ Clean Code (14)
        • โœ (1)
  • hELLOยท Designed By์ •์ƒ์šฐ.v4.10.0
Blxxming
[C++] ํŽœ์œ… ํŠธ๋ฆฌ(Fenwick Tree)
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”