๋ถ๋ถํฉ ๊ด๋ จ ์๊ณ ๋ฆฌ์ฆ ์ ๋ฆฌ
Query
๋, ์ด๋ฅผํ
๋ฉด ํน์ Range์ ํฉ์ ๊ตฌํ๋ ๊ฒ์ ๋งํ๋ค. ์ด๋ฌํ Query
์ ๋ฐ๋ผ ๋ถ๋ถํฉ์ ์ ์ฅํ๋ ๋ฐฉ์์ ๋ค๋ฅด๊ฒ ํด์ผํ๋ค.
์ด ๊ฒฝ์ฐ์๋ ๊ฐ์ฅ ๋จ์ํ๋ฉด์๋ ์ฌํํ ๋ฐฉ๋ฒ์ด ์๋ค.
int pSum[MAX];void init(int arr[]) {pSum[0] = arr[0];for(int i = 1; i < MAX; ++i) {pSum[i] = pSum[i-1] + arr[i];}}int getRangeSum(int l, int r) {if (l == 0) return pSum[r];return pSum[r] - pSum[l - 1];}
์ด ๊ฒฝ์ฐ ์ฒ์ init
์ด ๋ ์ดํ์๋ ๋ฌด๋ ค O(1)
๋ก ๋ถ๋ถํฉ์ ๊ตฌํ ์ ์๋ค.
๊ทธ๋ฐ๋ฐ, ์ด๋ ๊ฒ๋ง ๋๋ฉด ๋๋ฌด ์ฌ์ฐ๋, ๋ณดํต ์๊ณ ๋ฆฌ์ฆ ์ํ์ด๋ ์ด๋ฐ ๊ณณ์์๋ arr
์ ๊ฐ์ ์ง์์ ์ผ๋ก ๋ณ๊ฒฝํ๋ ํํ์ ๋ฌธ์ ๊ฐ ์ถ์ ๋๊ณค ํ๋ค. ์ด๋ ๊ฒ ์๋ณธ ๋ฐฐ์ด์ ๊ฐ์ด ๋ณํ๊ฐ ์์ ๊ฒฝ์ฐ์๋ ๊ธฐ์กด์ ๊ตฌํด๋์ pSum
์ ๊ฐ์ด ๋ฌด์ฉ์ง๋ฌผ์ด๊ณ , ๊ฐ์ ๋ณํ๊ฐ ์์ ๋๋ง๋ค O(n)
์ ์
๋ฐ์ดํธ๊ฐ ์์ด์ผ ํ ๊ฒ์ด๋ค.
๋ถ๋ถํฉ์ ๊ตฌํ ๋ ์์ด์ ๊ฐ์ฅ ์๋ฆ๋ค์ด ๋ฐฉ๋ฒ์ด๋ผ๊ณ ๋๋ ์๊ฐํ๋ค. ์ด ํธ๋ฆฌ๋ Binary-Indexed Tree
๋ผ๊ณ ๋ ๋ถ๋ฆฌ๋ฉฐ, ์ถํ ์๊ฐํ Segment Tree
์ ๋ค๋ฅด๊ฒ, ์ถ๊ฐ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ N
๋งํผ๋ง ์ฌ์ฉํ๊ณ ๋ ๋ถ๋ถํฉ์ ์ ์ฅํ ์ ์๋ ๋ฐฉ๋ฒ์ด๋ค. ์ด๋ป๊ฒ N
๋งํผ์ผ๋ก ์ ์ฅํ๋๊ฐ? ์ด์ง์์ ์๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ค. ์๋ฅผ๋ค์ด ํน์ Index์ ๊ฐ์ ์
๋ฐ์ดํธ ํ๋ค๊ณ ํ๋ฉด, ์๋์ฒ๋ผ ํ๋ค.
11 (1011)
-> 12 (1100)
-> 16 (10000)
-> 32 (100000)
-> ...7 (0111)
-> 8 (1000)
-> 16 (10000)
-> 32 (100000)
-> ...์ด๋ ๊ฒ ํ ๊ฒฝ์ฐ, ์ ์ฒด ์
๋ฐ์ดํธ ๋ Index์ ๊ฐ์๋ log n
๊ฐ๊ฐ ๋๋ฏ๋ก, ์๊ฐ๋ณต์ก๋๊ฐ O(n)
์์ ๋ง์ด ์ค์ด๋ค๊ฒ ๋๋ค.
๊ทธ๋ฆฌ๊ณ , ํน์ Index ๊น์ง์ ํฉ์ ๊ตฌํ๊ณ ์ถ๋ค๋ฉด, ์๋ ์์๋ก ํฉํ๋ค.
11 (1011)
-> 10 (1010)
-> 8 (1000)
7 (0111)
-> 6 (0110)
-> 4 (0100)
์ด ๊ณผ์ ๋ ๋ง์ฐฌ๊ฐ์ง๋ก ์ด์ง์ ๋จ์๋ก ์
๋ฐ์ดํธ ๋๋ฏ๋ก ์๊ฐ๋ณต์ก๋๋ O(log n)
์ด๋ค.
์ฝ๋๋ก ์ ๋ ๊ณผ์ ์ ๊ตฌํํ๋ฉด ์๋์ฒ๋ผ ๋๋ค.
int f[MAX];void update(int idx, int v) {for(; idx < MAX; idx += idx & -idx) f[idx] += v;}int get(int idx) {int r = 0;for(; idx > 0; idx -= idx & -idx) r += f[idx];return r;}
์ฝ๋์์ ๋๋ฌ๋ ๊ฒ์ฒ๋ผ, ๋ง์ฝ n๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ด๊ธฐํํ๋ค๊ณ ํ๋ฉด O(n log n)
์ ์๊ฐ๋ณต์ก๋๊ฐ ์์๋๋ค.
Segment Tree
๋ ์ผ๋ฐ์ ์ธ Query๋ฅผ ํจ์จ์ ์ผ๋ก ๋์ํ ์ ์๊ฒ ํ๋ ๊ตฌ์กฐ์ด๋ค.