CF1601F Two Sorts
給定 \(n\),將 \(1\sim n\) 按照字典序排序,\(a_i\) 表示第 \(i\) 小的數,求:
\(1\le n\le 10^{12}\)
Solution
先暴力,我們按照字典序搜索(記 \(\text{cnt}\) 和 \(\text{val}\) 表示第 \(\text{cnt}\) 小的數是 \(\text{val}\))即可線性。
考慮根號分治(不搜索末 \(6\) 位),我們同樣搜索,處理到 \(\overline {\text{valxxxxxx}}\) 時(假設 \(\overline{\text{val999999}} \le n\),即沒有任何上界限制),會發現可以快速計算這些值的和。
我們記 \(cnt_{x}\) 表示 \(x\) 的排名,\(cnt'_x\) 表示 \(x\) 在 \(\overline {abcdef}\) (\(0\le a,b,c,d,e,f\le 9\),即可以有前導零)的排名。
那么, \(cnt_{\overline {\text{valxxxxxx}}}=cnt_{\overline{\text{val}}}+cnt'_{\overline{\text{xxxxxx}}}\),因此可以把貢獻拆成:
因此,我們可以預處理 \(\overline{\text{xxxxxx}}\) 相關的信息,即 \((cnt'_{\overline{\text{xxxxxx}}}-\overline{\text{xxxxxx}})\)。
由於上述式子是 \((A+B)\bmod P\) 形式,而 \(0\le A,B<P\),因此值為 \(A+B\) 或 \(A+B-P\),判斷這個可以通過一個二分解決。
因此,總時間復雜度 \(\mathcal O(\sqrt{n} \log n)\)。
提一句,這個實在太難表述了,所以可以對照代碼閱讀。我的代碼碼量極小,並且是目前的最優解。