ํฌ์ ํ ์ด๋ธ(Sparse Table)
- ๋ฐฐ์ด์ด ์ ์ ์ด์ด์ผ ํ๋ค. ์ฆ, ๋ฐฐ์ด ๋ด์ฉ์ด ์์ ๋๋ฉด ์ ๋๋ค.
- ๋ฐฐ์ด์ ์์ด๋์ด๋ ๋ถํ ์ ๋ณต๊ณผ ๋น์ทํ์ง๋ง ๋ ๋น ๋ฅด๋ค.
๊ธฐ๋ณธ ์๋ฆฌ
๋ชจ๋ ์ ์ ์ ๊ฐ์ ์ด 1๊ฐ์ธ ์ ํฅ ๊ทธ๋ํ๊ฐ ์กด์ฌํ ๋ ์ด๋ค ์ ์ ์์ ์์ํด k๋ฒ ์ด๋์ ํ๋ฉด ๋์ฐฉํ๋ ์ ์ ์ ์ผํ๋ค. ์ด๋ k๋ฒ์ ์ผ์ผ์ด ๋งค๋ฒ ๋ฐ๋ผ๊ฐ๋ฉฐ ๋์ฐฉ์ ์ ๊ณ์ฐํ ์๋ ์๊ฒ ์ง๋ง k๊ฐ์ด ์ปค์ง์๋ก ์๊ฐ๋ ์ค๋ ๊ฑธ๋ฆด ๊ฒ์ด๋ค.
๋ง์ฝ ์ด๋ค ์ ์ ์ n๋ฒ ์ด๋ํ์ ๋ ๋์ฐฉ์ , ๋ ๊ทธ ๋์ฐฉ์ ์ ์ ์ ๋ง๋ค ๋ค ๊ธฐ์ตํ๋ ๋ฐฐ์ด์ด ์๋ค๋ฉด ๋์ฐฉ์ ์ ๋งค์ฐ ํจ์จ์ ์ผ๋ก ๊ตฌํ ์ ์์ ๊ฒ์ด๋ค.
๊ทธ๋ ๋ค๋ฉด ์ด ๋ฐฐ์ด์ ์ด๋ป๊ฒ ๊ฐ์ ธ์ผ ํ ๊น?
1์นธ, 2์นธ, 4์นธ, 8์นธ, 16์นธ,... ๋ฑ 2์ง์๋ฅผ ์ด์ฉํด 2์ง์์ ํด๋นํ๋ ์ด๋ ๊ฐ์ ๋ชจ๋ ๋ฐฐ์ด๋ก ๋ง๋ ๋ค. ๊ทธ๋ฆฌ๊ณ ์ด๋ ํ์ k๋ฅผ 2์ง์๋ก ๋ํ๋์ ๋ ์ผ์ ธ ์๋ ๋นํธ์ ํด๋นํ๋ ๋ฐฐ์ด๋ง ์ฌ์ฉํด ๊ฑด๋๋ฐ๋ฉด ๋๋ค. ์ฌ๊ธฐ์ ๋ฐ๋ ์์๋ ์๊ด์ด ์๋ค. ์๋ฅผ ๋ค์ด, k๊ฐ 13(1101(2))์ด๋ผ๋ฉด ์ผ์ ธ ์๋ ๋นํธ์ ํด๋นํ๋ 1์นธ, 4์นธ, 8์นธ ์ด 3๋ฒ๋ง ๋ฐ๋ฉด ๋๋ค.
๋ฌธ์
https://www.acmicpc.net/problem/17435
#include <iostream>
#include <vector>
using namespace std;
int main()
{
cin.tie(NULL);
cout.tie(NULL);
ios_base::sync_with_stdio(false);
int m;
cin >> m;
int f[200001][20]; // f[i][j]: ์ ์ i์์ 2^j๋ฒ ์ด๋ํ ํ์ ์ ์
for (int i = 1; i <= m; ++i)
cin >> f[i][0];
// 2์ง์ ์ด๋ ๊ฐ์ ๋ฐฐ์ด์ ์ฑ์ด๋ค.
for (int j = 1; j < 20; j++)
for (int i = 1; i <= m; i++)
f[i][j] = f[f[i][j - 1]][j - 1];
int q;
cin >> q;
while (q--) {
int n, x;
cin >> n >> x;
for (int i = 0; 0 < n; i++) {
// ์ผ์ ธ์๋ ๋นํธ๋ง ์ด๋ํ๋ค.
if (n & 1)
x = f[x][i];
n >>= 1;
}
cout << x << '\n';
}
}
https://www.acmicpc.net/problem/14942
#include <iostream>
#include <vector>
using namespace std;
int n;
vector<int> energys;
vector<pair<int, int>> tunnels[100001];
int parent[100001][20]; // ์ ์ i์์ 2^j๋ฒ ์ด๋ํ ํ์ ์ ์
int dist[100001][20]; // ์ ์ i์์ parent[i][j]๋ก ์ด๋ํ๋๋ฐ ํ์ํ ์๋์ง
void dfs(int start, int index)
{
parent[start][0] = index;
for (pair<int, int> next : tunnels[start])
if (next.first != index) {
dist[next.first][0] = next.second;
dfs(next.first, start);
}
}
int main()
{
cin.tie(NULL);
cout.tie(NULL);
ios_base::sync_with_stdio(false);
cin >> n;
energys.resize(n);
for (int i = 0; i < n; ++i)
cin >> energys[i];
for (int i = 0; i < n - 1; i++) {
int a, b, c;
cin >> a >> b >> c;
tunnels[a].push_back({ b, c });
tunnels[b].push_back({ a, c });
}
// ๊ฐ๋ฏธ๊ตด์ ํธ๋ฆฌ ๊ตฌ์กฐ๋ก ๋ง๋ค์ด ์ด๊ธฐํํ๋ค.
dfs(1, 0);
// 2์ง์ ์ด๋ ๊ฐ์ ๋ฐฐ์ด์ ์ฑ์ด๋ค.
for (int i = 1; i < 20; i++)
for (int j = 1; j <= n; j++) {
dist[j][i] = dist[j][i - 1] + dist[parent[j][i - 1]][i - 1];
parent[j][i] = parent[parent[j][i - 1]][i - 1];
}
for (int i = 0; i < n; i++) {
int pos = i + 1, energy = energys[i];
for (int j = 20 - 1; j >= 0; j--) {
if (parent[pos][j] != 0 && energy >= dist[pos][j]) {
energy -= dist[pos][j];
pos = parent[pos][j];
}
}
cout << pos << '\n';
}
}