๊ตฌ๊ฐํฉ, ๊ตฌ๊ฐ์ ๋ฐ๋ฅธ ๊ฒฝ์ฐ์ ์๋ฅผ ๊ตฌํ๋ ๋ฌธ์ ์์ ๋ง์ด ์ฐ์ด๋ ์๊ณ ๋ฆฌ์ฆ์ธ ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ์ ๋ํด ์์๋ณด์.
* ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ์ ๋ฑ์ฅ ๋ฐฐ๊ฒฝ ๋ฐ ํ์์ฑ
S[0] = A[0];
for (int i=1; i<n; i++) {
S[i] = S[i-1] + A[i];
}
๊ตฌ๊ฐํฉ์ ๋จ์ for ๋ฌธ์ ์ด์ฉํด์ ๊ตฌํ๋ ์ฝ๋์ด๋ค.
0~n ๊น์ง์ ํฉ์ ๊ตฌํ ๋ O(n) ์ ์๊ฐ๋ณต์ก๋๊ฐ ๋ฐ์ํ๋ค.
0~n ๋ฟ ์๋๋ผ 2~5, 100~200 ๋ฑ m ๊ฐ์ ๊ตฌ๊ฐํฉ์ ๊ตฌํ๋ค๋ฉด O(nm) ์ ์๊ฐ๋ณต์ก๋๊ฐ ๋ฐ์ํ๋ค.
์ฌ๊ธฐ์ ๋ง์ฝ A[x] ์ ๊ฐ์ ๋ณ๊ฒฝํด์ผ ํ๋ฉด ์ด๋ป๊ฒ ๋ ๊น.
A[x] ๊ฐ์ด ํฌํจ๋ ๋ชจ๋ S ๋ฐฐ์ด ๊ฐ์ ๋ณ๊ฒฝํด์ ๋ค์ ๊ตฌ๊ฐํฉ์ ๊ตฌํด์ฃผ์ด์ผ ํ๋ค.
0๋ฒ ๊ฐ์ด๋ผ๊ณ ํ๋ฉด ๋ O(nm) ์ ์๊ฐ๋ณต์ก๋๊ฐ ๋ฐ์ํ๋ค.
ํฐ ์์ n, m ์ด ์ฃผ์ด์ง๋ฉด ์๊ฐ์ด๊ณผ๋ก ํ ์ ์๋ค. ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์ฐพ์์ผ ํ๋ค.
* ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ๋ ?
: ๊ตฌ๊ฐ์ ์ ์ฅํ๊ธฐ ์ํ ํธ๋ฆฌ.
- ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ์ ๋ฆฌํ๋ ธ๋: ๋ฐฐ์ด์ ๊ทธ ์ ์์ฒด
- ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ์ ๋ค๋ฅธ ๋ ธ๋: ์ผ์ชฝ ์์๊ณผ ์ค๋ฅธ์ชฝ ์์์ ํฉ
- ํ ๋ ธ๋์ ๋ฒํธ๊ฐ x์ผ ๋ ์ผ์ชฝ ์์์ ๋ฒํธ๋ 2*x, ์ค๋ฅธ์ชฝ ์์์ ๋ฒํธ๋ 2*x + 1 ์ด ๋๋ค.
n = 10 ์ธ ๋ฐฐ์ด์ ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ๋ก ํํํด๋ณด์.
๋ฆฌํ ๋ ธ๋์ ๊ฐ ๋ฐฐ์ด์ index ๊ฐ ๋ค์ด ์๊ณ , ์ ์ ๋ฃจํธ ๋ ธ๋๋ก ๊ฐ๋ฉฐ 0~1์ ํฉ, 0~1๊ณผ 2์ ํฉ, 3๊ณผ 4์ ํฉ, 0~2์ 3~4์ ํฉ, 0~4์ 5~9์ ํฉ์ด ๋ด๊ธด๋ค. ์๊ฐ๋ณต์ก๋ O(logN).
์ผ์ชฝ, ์ค๋ฅธ์ชฝ ํธ๋ฆฌ์ ๋๋ ๊ธฐ์ค์ ๋ฐฐ์ด ํฌ๊ธฐ์ ๋ฐ์ด๋ค.(์์ ์ ์ ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ์ ํน์ง์ผ๋ก ํ ๋ ธ๋์ ๋ฒํธ๊ฐ x์ผ ๋ ์ผ์ชฝ ์์์ ๋ฒํธ๋ 2*x, ์ค๋ฅธ์ชฝ ์์์ ๋ฒํธ๋ 2*x + 1 ์ด๊ธฐ ๋๋ฌธ.)
์ฆ, 0~9์ ๊ตฌ๊ฐํฉ์ ๊ตฌํด์ผ ํ๋ค๋ฉด ๋ฃจํธ๋ ธ๋๋ง ์ ๊ทผํ๋ฉด ๋๋ค.
5~8์ ๊ตฌ๊ฐ ํฉ์ ๊ตฌํด์ผ ํ๋ฉด ์๋์ ๊ฐ์ด 2๊ฐ์ ๋ ธ๋๋ง ์ ๊ทผํ๋ฉด ๋๋ค.
3~9์ ๊ตฌ๊ฐํฉ์ ๊ตฌํด์ผ ํ๋ ๊ฒฝ์ฐ๋ ์๋์ ๊ฐ์ด 2๊ฐ์ ๋ ธ๋๋ง ์ ๊ทผํ๋ฉด ๋๋ค.
๋ฐฐ์ด์ ์ด๋ค ๊ฐ์ ๋ณ๊ฒฝํด์ผ ํ ๋๋ ํด๋น ๊ฐ์ ํฌํจํ๋ ๊ฐ๊ณผ ๊ตฌ๊ฐ ๋ ธ๋๋ง ๋ณ๊ฒฝํด์ฃผ๋ฉด ๋๋ค.
์ธ๊ทธ๋จผํธ ํธ๋ฆฌ๊ฐ ์๋์๋ค๋ฉด ๋ชจ๋ ๊ตฌ๊ฐํฉ์ ์ ๊ทผํ์ฌ ๊ฐ์ ๋ณ๊ฒฝํด์ค์ผ ํ์ ๊ฒ์ด๋ค. ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ์ ํน์ฑ์ ์ด์ฉํ๋ฉด 4๊ฐ์ ๊ตฌ๊ฐํฉ์๋ง ์ ๋ฐ์ดํธํ๋ฉด ๋๋ค. ์๊ฐ๋ณต์ก๋ O(logN).
* ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ ๋ง๋๋ ๋ฒ(C++)
1) ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ ์์ฑ
// a: ๋ฐฐ์ด a
// tree: ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ
// node: ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ ๋
ธ๋ ๋ฒํธ
// node๊ฐ ๋ด๋นํ๋ ํฉ์ ๋ฒ์๊ฐ start ~ end
long long init(vector<long long> &a, vector<long long> &tree, int node, int start, int end){
if(start == end){
return tree[node] = a[start];
} else{
return tree[node] = init(a, tree, node*2, start, (start+end)/2) + init(a, tree, node*2+1, (start+end)/2+1, end);
}
}
start == end ์ธ ๊ฒฝ์ฐ๋ ๋ฆฌํ๋ ธ๋๋ฅผ ๋ปํ๋ฏ๋ก ๋ฆฌํ๋ ธ๋๋ ๋ฐฐ์ด ์์ฒด์ ๊ฐ์ด ํฌํจ๋์ด์ผ ํ๋ฏ๋ก tree[node] ์ a[start] ๊ฐ์ ๋ฃ์ด์ค๋ค.
๋ฆฌํ๋ ธ๋๊ฐ ์๋ ๊ฒฝ์ฐ์ tree[node] ์ ์ผ์ชฝ ์์ ๋ ธ๋์ ๊ฐ๊ณผ ์ค๋ฅธ์ชฝ ์์ ๋ ธ๋์ ๊ฐ์ ๋ํด์ ๋ฃ์ด์ค๋ค.
2) ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ ๊ตฌ๊ฐํฉ ๊ตฌํ๊ธฐ
// node ๊ฐ ๋ด๋นํ๋ ๊ตฌ๊ฐ: start ~ end
// ๊ตฌํด์ผํ๋ ํฉ์ ๋ฒ์: left ~ right
long long sum(vector<long long> &tree, int node, int start, int end, int left, int right) {
if(left > end || right < start) {
return 0;
}
if(left <= start && end <= right) {
return tree[node];
}
return sum(tree, node*2, start, (start+end)/2, left, right) + sum(tree, node*2+1, start+end)/2+1, end, left, right);
}
๊ตฌํด์ผํ๋ ๊ตฌ๊ฐํฉ [left, right] ์ ๋ฒ์๊ฐ [start, end] ์ ํ๋๋ผ๋ ์๋ค๋ฉด 0์ return ํ๋ค.
๊ตฌํด์ผํ๋ ๊ตฌ๊ฐํฉ [left, right] ์ ๋ฒ์๊ฐ [start, end] ์์ ์์ ํ ์๋ค๋ฉด ํด๋น node ๊ฐ์ ๋ฐ๋ก return ํ๋ค.
๊ทธ ๊ฒฝ์ฐ๊ฐ ์๋๋ผ๋ฉด ์ผ์ชฝ, ์ค๋ฅธ์ชฝ ๋ ธ๋ ํ์์ ํตํด ๊ฐ์ ๊ตฌํ๋ค.
3) ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ ๋ ธ๋ ๊ฐ ๋ณ๊ฒฝํ๊ธฐ
// tree: ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ
// node: ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ์ ํ์ฌ ๋
ธ๋ ๋ฒํธ
// node ๊ฐ ๋ด๋นํ๋ ํฉ์ ๋ฒ์ start ~ end
// index: ์์ ํด์ผํ ๋
ธ๋์ index
// diff: ๊ธฐ์กด ๊ฐ๊ณผ ๋ณ๊ฒฝํ ๊ฐ์ ์ฐจ์ด
void update(vector<long long> &tree, int node, int start, int end, int index, long long diff) {
if (index < start || index > end) return;
tree[node] = tree[node] + diff;
if (start != end) {
update(tree,node*2, start, (start+end)/2, index, diff);
update(tree,node*2+1, (start+end)/2+1, end, index, diff);
}
}
index ๊ฐ start ์ end ์ฌ์ด์ ๊ฐ์ด ์๋๋ผ๋ฉด ๋ฐ๋ก return ํ๋ค.
index ๊ฐ start ์ end ์ฌ์ด์ ๊ฐ์ด๋ผ๋ฉด diff ๋งํผ์ ๋ํด์ ๊ฐ์ ๊ฐฑ์ ํ๋ค.
leef ๋ ธ๋๊ฐ ์๋๋ฉด ์ผ์ชฝ, ์ค๋ฅธ์ชฝ ์์ ํธ๋ฆฌ์ ๋ ธ๋๋ฅผ update ํ๋ฌ ๊ฐ๋ค.
* ์ถ์ฒ : https://www.acmicpc.net/blog/view/9
* ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ๋ก ํ ์ ์๋ ๋ฌธ์
2042๋ฒ ๊ตฌ๊ฐํฉ(https://www.acmicpc.net/problem/2042)
#include <cstdio>
#include <cmath>
#include <vector>
using namespace std;
long long init(vector<long long> &a, vector<long long> &tree, int node, int start, int end) {
if (start == end) {
return tree[node] = a[start];
} else {
return tree[node] = init(a, tree, node*2, start, (start+end)/2) + init(a, tree, node*2+1, (start+end)/2+1, end);
}
}
void update(vector<long long> &tree, int node, int start, int end, int index, long long diff) {
if (index < start || index > end) return;
tree[node] = tree[node] + diff;
if (start != end) {
update(tree,node*2, start, (start+end)/2, index, diff);
update(tree,node*2+1, (start+end)/2+1, end, index, diff);
}
}
long long sum(vector<long long> &tree, int node, int start, int end, int left, int right) {
if (left > end || right < start) {
return 0;
}
if (left <= start && end <= right) {
return tree[node];
}
return sum(tree, node*2, start, (start+end)/2, left, right) + sum(tree, node*2+1, (start+end)/2+1, end, left, right);
}
int main() {
int n, m, k;
scanf("%d %d %d",&n,&m,&k);
vector<long long> a(n);
int h = (int)ceil(log2(n));
int tree_size = (1 << (h+1));
vector<long long> tree(tree_size);
m += k;
for (int i=0; i<n; i++) {
scanf("%lld",&a[i]);
}
init(a, tree, 1, 0, n-1);
while (m--) {
int t1,t2,t3;
scanf("%d",&t1);
if (t1 == 1) {
int t2;
long long t3;
scanf("%d %lld",&t2,&t3);
t2-=1;
long long diff = t3-a[t2];
a[t2] = t3;
update(tree, 1, 0, n-1, t2, diff);
} else if (t1 == 2) {
int t2,t3;
scanf("%d %d",&t2,&t3);
printf("%lld\n",sum(tree, 1, 0, n-1, t2-1, t3-1));
}
}
return 0;
}
'๐ Coding Test Study > Algorithm' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
DP(Dynamic Programming) ๊ฐ๋ , ํ์ด๋ฒ (1) | 2024.06.07 |
---|