參考資料
Binary Lifting, No Memory Wasted - Urbanowicz
一種基於斜二進位制的序列&樹上資料結構 - return20071007
什麼是斜二進位制
對於斜二進位制,第 \(i\) 位的位權為 \(2^i - 1\)。
用斜二進位制表示一個數,需要滿足斜二進位制中至多存在 \(1\) 個位為 \(2\),其餘的位都為 \(0\) 或 \(1\)。
同時定義一個斜二進位制數 \(x\) 的最低有效位為最低的值非 \(0\) 的位,記作 \(low_x\)。
斜二進位制表示的求解
對於斜二進位制的求解,可以考慮歸納構造,參考 一種基於斜二進位制的序列&樹上資料結構 - return20071007。
但是這裡面正確性的證明直接“不難驗證了”,這裡給個證明:
根據歸納的情況分討,若 \(n\) 合法,然後繼續構造:
- 第一種情況。有 \(n\) 的 \(low_n + 1\) 位 \(\le 1\),那麼 \(+ w_{low_n}\) 後 \(low_{n + 1} = low_n + 1\),且此時第 \(low_{n + 1}\) 這位 \(\le 2\),同時 \(> low_{n + 1}\) 位不受影響肯定都 \(\le 1\),合法。
- 第二種情況。那麼此時肯定 \(n\) 不存在 \(2\),\(+1\) 後最多會多一個 \(2\) 且就是第 \(1\) 位。
所以 \(n + 1\) 還是合法的。
這裡給出另一種構造方式:
首先對於 \(0\) 的斜二進位制表示就為 \(0\),\(1\) 的斜二進位制表示就為 \(1\)。
若已經知道了 \([1, 2^w - 1]\) 的對應表示方式,那麼 \([2^w, 2^{w + 1} - 2]\) 就是在 \([1, 2^w - 1]\) 的基礎上 \(+ (2^w - 1)\) 得到的,所以就只是整體在 \(w\) 這一位多 \(1\)。
於是對於 \([1, 2^w - 1]\) 複製一份接在後面並對於後面的這一份在 \(w\) 位 \(+1\) 即可,就得到了 \([1, 2^{w + 1} - 2]\)。
同時 \(2^{w + 1} - 1\) 的斜二進位制表示顯然就為 \(1\underbrace{0\cdots0}_{w}\),於是就得到了 \([1, 2^{w + 1} - 1]\) 的表示了。
證明:
考慮什麼情況會產生 \(2\)。
能發現只有擴充套件時 \(2^{w + 1} - 2\) 時會帶有 \(1\) 個 \(2\),也就是複製後的右端點會得到 \(2\)。
那麼對於下一次擴充套件,因為 \(2^{w + 1} - 2\) 不是 \([1, 2^{w + 1} - 1]\) 的右端點,就不會再得到 \(2\) 了。
這裡給出 \(1\sim 15\) 的斜二進位制表示:
斜二進位制表示的有效最低位的求解
因為實際上資料結構只需要用到 \(low_x\),所以上文作用不是特別大(。
可以考慮類似斜二進位制表示的求法:
已知 \([1, 2^w - 1]\) 的表示,那麼複製一份放在後面,再加入一個 \(w + 1\),就得到了 \([1, w^{w + 1} - 1]\) 的表示。
放一下 \(1\sim 15\) 的表:
根據上面的方法和這個表,能發現有:
\(low_n = \begin{cases}low_{n - 1} + 1 & low_{n - 1} = low_{n - 1 - (2^{low_{n - 1}} - 1)}\\ 1 & \text{otherwise}\end{cases}\)
這個可以理解成如果 \(low_{n - 1 - (2^{low_{n - 1}} - 1)}\) 就說明這前面已經複製了一份了,接下來的 \(n\) 就對應到單獨填進去的 \(2^{low_{n - 1} + 1} - 1\);否則不滿足,那麼就不是複製後新增的,就只有 \(1\) 了。
基於斜二進位制的資料結構的想法
令 \(x\) 的管轄區間為 \((x - (2^{low_x} - 1), x]\),把這個表打出來,會發現非常優美(\(1\sim 15\)):
【咕咕】