ํํ ๋ถํ , ๋ชจ์ค ์๊ณ ๋ฆฌ์ฆ
ํํ ๋ถํ (SQRT Decomposition)์ ๋ฐ์ดํฐ๊ฐ N๊ฐ์ด๋ฉด √N๊ฐ๋งํผ ๋๋ ์ ๊ด๋ฆฌํ๋ ๋ฐฉ๋ฒ์ด๋ค.
- ๊ฐ ๊ทธ๋ฃน์ ๋ํฏ๊ฐ์ ๊ฐ์ง๊ณ ์๋ค. ๋ง์ฝ ์ฃผ์ด์ง๋ ์ฟผ๋ฆฌ๊ฐ ๊ตฌ๊ฐ์ ๋ง์ ์ด๋ผ๋ฉด ๊ทธ๋ฃน์ ํฉ์ด ๋ํฏ๊ฐ์ด ๋๋ค.
๋ชจ์ค ์๊ณ ๋ฆฌ์ฆ์ ์ด๋ค ๊ตฌ๊ฐ [s, e]์ ์ํ๋ ์์๋ค์ ์ด์ฉํ์ฌ ์ด๋ค ๊ฐ์ ๊ณ์ฐํ๋ ์ฟผ๋ฆฌ๋ฅผ ์ฒ๋ฆฌํ๋ ์๊ณ ๋ฆฌ์ฆ์ด๋ค.
- ์ ๋ฐ์ดํธ๊ฐ ์์ด ์ฟผ๋ฆฌ์ ์์๋ฅผ ๋ณ๊ฒฝํด๋ ๋ฌด๋ฐฉํ๋ค. ๊ทธ๋์ ์ฟผ๋ฆฌ ์์๋ฅผ ์ฌ๋ฐฐ์นํ์ฌ ํจ์จ์ ์ผ๋ก ์ํํ๋ค.
- ๋ฐฐ์ด์ k(√N)๊ฐ๋ก ์ด๋ฃจ์ด์ง ๊ทธ๋ฃน์ผ๋ก ๋๋ ์ฃผ๊ณ , ์ฟผ๋ฆฌ๋ฅผ ์คํํ ๋ ๋ ์กฐ๊ฑด ์ค ํ๋๋ฅผ ๋ง์กฑํ๋ ๊ฒฝ์ฐ ๋จผ์ ์ฒ๋ฆฌํ๋ค.
- [s1/k] < [s2/k]
- [s1/k] = [s2/k] and e1 < e2
๋ฌธ์
https://www.acmicpc.net/problem/13547
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAX = 100000;
const int MAX_VAL = 1000000;
struct QueryNode {
int i, j, index;
int sqrtN;
QueryNode() : QueryNode(0, 0, -1, 0) {}
QueryNode(int i, int j, int index, int N) : i(i), j(j), index(index) { sqrtN = sqrt(N); }
// (s/√N, e) ์์ผ๋ก ์ค๋ฆ์ฐจ์ ์ ๋ ฌ
bool operator <(const QueryNode& O)const {
if (i / sqrtN != O.i / sqrtN)
return (i / sqrtN < O.i / sqrtN);
return (j < O.j);
}
};
int N, M, A[MAX]{};
int result[MAX]{};
QueryNode Q[MAX];
int main()
{
cin >> N;
for (int i = 0; i < N; ++i)
cin >> A[i];
cin >> M;
// ์ฟผ๋ฆฌ๋ฅผ ์
๋ ฅ๋ฐ์ ํ ์ ๋ ฌ
for (int index = 0, i, j; index < M; ++index) {
cin >> i >> j;
Q[index] = QueryNode(i - 1, j, index, N);
}
sort(Q, Q + M);
// ์ฒซ ๋ฒ์งธ์ ์์นํ ์ฟผ๋ฆฌ์ ๊ฒฐ๊ณผ๋ ์์ ๊ตฌํจ
int dcnt = 0, cnt[MAX_VAL + 1]{};
int i0 = Q[0].i, j0 = Q[0].j;
for (int i = i0; i < j0; ++i)
if (cnt[A[i]]++ == 0)
++dcnt;
result[Q[0].index] = dcnt;
// ๋ค์ ์ฟผ๋ฆฌ๋ถํฐ ๋ฐ๋ก ์ด์ ์ฟผ๋ฆฌ์ ๊ฒฐ๊ณผ๋ฅผ ์ฌ์ฉํด ๊ณ์ฐํด ๋๊ฐ
for (int i = 1; i < M; ++i) {
while (Q[i].i < i0) if (cnt[A[--i0]]++ == 0) ++dcnt;
while (j0 < Q[i].j) if (cnt[A[j0++]]++ == 0) ++dcnt;
while (Q[i].i > i0) if (--cnt[A[i0++]] == 0) --dcnt;
while (j0 > Q[i].j) if (--cnt[A[--j0]] == 0) --dcnt;
result[Q[i].index] = dcnt;
}
for (int i = 0; i < M; ++i)
cout << result[i] << "\n";
}