Hilbert Curve
ย - Last update: 2024-03-19

Hilbert Curve

Hilbert Curve๋Š” ์ •์ˆ˜์ขŒํ‘œ๊ณ„์—์„œ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•œ ์ผ์ข…์˜ Space-Filling Curve ์ด๋‹ค. 1์ฐจ์› ์ขŒํ‘œ๊ณ„์—์„œ ์–ด๋–ค ์ขŒํ‘œ ๋ฆฌ์ŠคํŠธ๊ฐ€ ์žˆ์–ด์„œ ๊ทธ๋“ค์„ ์ตœ๋‹จ ๊ฒฝ๋กœ๋กœ ๋ฐฉ๋ฌธํ•ด์•ผ ํ•œ๋‹ค๊ณ  ํ•œ๋‹ค๋ฉด ์ด๋ฅผ ๊ตฌํ•˜๋Š” ๊ฒƒ์€ ๊ฐ„๋‹จํ•˜๋‹ค. ์œ„์น˜๋ฅผ ์ •๋ ฌํ•ด์„œ ์˜ค๋ฆ„์ฐจ์ˆœ์ด๋‚˜ ๋‚ด๋ฆผ์ฐจ์ˆœ์œผ๋กœ ๋ฐฉ๋ฌธํ•˜๋ฉด ๋œ๋‹ค. 2์ฐจ์› ์ขŒํ‘œ๊ณ„๊ฐ€ ๋˜๋ฉด ์ด์•ผ๊ธฐ๊ฐ€ ๋งŽ์ด ๋ณต์žกํ•ด์ง„๋‹ค. ์ด๋ฅผ Hilbert Curve ๋ฅผ ์‚ฌ์šฉํ•ด์„œ 1์ฐจ์› ์ขŒํ‘œ๊ณ„์ฒ˜๋Ÿผ 2์ฐจ์› ์ขŒํ‘œ๊ณ„๋ฅผ projection ํ•  ์ˆ˜ ์žˆ๊ณ , ํœด๋ฆฌ์Šคํ‹ฑํ•˜๊ฒŒ ์–ด๋Š์ •๋„ ๊ฐ€๊นŒ์šด ์ ๋“ค๋ผ๋ฆฌ ๋ฐฉ๋ฌธํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

์•„๋ž˜ ์ฝ”๋“œ๋Š” ์„œ๋‘์˜ codeforces blog์—์„œ ๊ณต์œ ๋œ ์ฝ”๋“œ๋กœ, ์ž„์˜์˜ xx, yy ์ขŒํ‘œ๊ฐ€ ์ฃผ์–ด์กŒ์„ ๋•Œ์˜ Hilbert Curve ์ƒ์˜ ์ˆœ์„œ๋ฅผ O(logโกN)O(\log N) ์‹œ๊ฐ„ ๋ณต์žก๋„๋กœ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.

constexpr int rotateDelta[4] = {3, 0, 0, 1};
inline int64_t hilbertOrder(int x, int y, int pow, int rotate) {
if (pow == 0) {
return 0;
}
int hpow = 1 << (pow-1);
int seg = (x < hpow) ? (
(y < hpow) ? 0 : 3
) : (
(y < hpow) ? 1 : 2
);
seg = (seg + rotate) & 3;
int nx = x & (x ^ hpow), ny = y & (y ^ hpow);
int nrot = (rotate + rotateDelta[seg]) & 3;
int64_t subSquareSize = int64_t(1) << (2*pow - 2);
int64_t ans = seg * subSquareSize;
int64_t add = hilbertOrder(nx, ny, pow-1, nrot);
ans += (seg == 1 || seg == 2) ? add : (subSquareSize - add - 1);
return ans;
}

ํ™œ์šฉ

Mo's ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์ •๋ ฌ ์ˆœ์„œ๋กœ ํ™œ์šฉํ•˜๊ธฐ

Mo's ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๊ฒฝ์šฐ ์ฟผ๋ฆฌ ๋ฌธ์ œ์—์„œ ์ฟผ๋ฆฌ์˜ ll, rr ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌํ•ด์„œ ๋™์ž‘ํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค. ์ด์— ๊ด€ํ•ด์„œ๋Š” ๊ธ€ ์„œ๋‘์— ์žˆ๋Š” ๋ธ”๋กœ๊ทธ์— ์ž˜ ์ •๋ฆฌ๋˜์–ด ์žˆ๋‹ค. NN๊ณผ QQ๊ฐ€ ๊ฑฐ์˜ ์œ ์‚ฌํ•œ ๋ฌธ์ œ์—์„œ๋Š” Mo's ์•Œ๊ณ ๋ฆฌ์ฆ˜์— zigzag ์•„์ด๋””์–ด๋ฅผ ์„ž์€ ๊ฒƒ๊ณผ Hilbert Curve๋ฅผ ํ™œ์šฉํ•œ ๋ฐฉ์‹์ด ๊ฑฐ์˜ ์œ ์‚ฌํ•œ ์„ฑ๋Šฅ์„ ๋ณด์ธ๋‹ค. ์ˆ˜์—ด๊ณผ ์ฟผ๋ฆฌ 0 ๋ฌธ์ œ์—์„œ ์ธก์ •ํ•œ ์†๋„๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

  • ์ผ๋ฐ˜ Mo's: 1070 ms
  • Mo's + zigzag: 680 ms
  • Mo's + Hilbert: 660 ms

Heuristics ๋ฌธ์ œ์— ํ™œ์šฉํ•˜๊ธฐ

์„ฑ๋Šฅ์„ ์š”ํ•˜๋Š” TSP ๋ฌธ์ œ์—์„œ ํ™œ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค. ์ž„์˜์˜ ์ขŒํ‘œ๋ฅผ ๋น„์šฉ์„ ์ตœ์†Œ๋กœ ํ•ด์„œ ๋ฐฉ๋ฌธํ•ด์•ผ ํ• ๋•Œ, ์œ„์—์„œ ์‚ดํŽด๋ณธ ๊ฒƒ์ฒ˜๋Ÿผ 2์ฐจ์› ์ขŒํ‘œ๊ณ„๋ฅผ 1์ฐจ์› ์ขŒํ‘œ๊ณ„์ธ ๊ฒƒ์ฒ˜๋Ÿผ ์ˆœ์„œ๋ฅผ ์ •ํ•ด์„œ ๋ฐฉ๋ฌธํ•  ์ˆ˜ ์žˆ๋‹ค. ๋Œ€์ถฉ int map[1000][1000] ์ •๋„๊นŒ์ง€๋Š” ๋ฏธ๋ฆฌ ์ˆœ์„œ๋ฅผ ์ €์žฅํ•ด๋‘๊ณ  O(1)O(1)์— ๊ตฌํ•˜๋Š” ๊ฒƒ์ด ์ข‹์€ ๋ฐฉ์‹์œผ๋กœ ๋ณด์ธ๋‹ค. ์ด์ „์— ๋‹ค๋ค˜๋˜ Angle Sort์™€์˜ ์„ฑ๋Šฅ ๋น„๊ต๋„ ์ดํ›„์— ์ง„ํ–‰ํ•ด๋ด์•ผ๊ฒ ๋‹ค.

// [TODO] 2์ฐจ์› ๊ณต๊ฐ„์— Hilbert Curve ๋ฐฉ๋ฌธ ์ˆœ์„œ๋ฅผ ์ฑ„์šฐ๋Š” ์ฝ”๋“œ