第一想法是逐位确定,但是位与位之间的割裂难以提出复杂度优秀的做法。转换视角:从大往小考虑所有数 x,找到一个字典序最小的下标集合 S,然后将 i\in S 的 b_i 赋成 x 并满足存在解。判断性问题即区间选点问题,判断最少选择点数(记为 c)是否不大于 x 在 a 中出现次数(记为 c_x)。考察 S 的形式,最开始肯定是不断取当前未选取位置中第一个,直到 c>c_x,回退这一步,然后再会被迫选取一些零散的点。c 每次操作后至多增加一,则选取完一个未选点序列的前缀后有 c=c_x,随后加入零散点需满足 c 不发生变化。
如何求出该前缀?显然可以二分,但是实际上在 S 内的点和二分 check 的 S 大小可能完全不在同一级别,复杂度退化到平方及以上。如何保证复杂度正确?先找到最小的 k 使得选取前 2^k 个位置不合法,如此 2^k 和 S 中极长前缀大小 d 是同一级别,接下来在 [2^{k-1},2^k) 内二分即可。找 k 复杂度是 T(k)=T(k-1)+\mathcal{O}(k2^k)=\mathcal{O}(k2^k) 的,后面是 \log{d}\times(d\log{d}) 的,不过可以事先将 2^k 个区间排好序,如此每次 check 顺次拉出,复杂度优化到 d\log{d}+\log{d}\times d。这一部分均摊总复杂度 \mathcal{O}(n\log{n})。