ZJOI2018 迷宫

我们简化的题意为:构造一个 \(m\) 进制下的自动机,使得其可以识别所有 \(K\) 的倍数。

我们可以轻易构造一个大小为 \(K\) 的自动机(按照模 \(K\) 进行分类)

我们考虑到部分节点是冗余的,将他们缩起来就可以得到答案。

换而言之,我们需要缩去这个自动机上所有从 \(x\) 处出发,到达 \(0\) 时能够识别的串 \(s\) 都相同的节点。

(事实上,可以论证不存在更优的构建方法,因为构造出来的自动机都可以类似的描述)

假定 \(i\) 出发到达 \(0\) 的最短串长为 \(f(i)\),定义 \(g(i)=m^{f(i)}\mod K\),那么两个节点等价当且仅当 \((f(i),g(i))\) 是相同的。

\(f(i)\) 等价于 \(i\times m^j=0/i\times m^j\bmod K+m^j>K\),可以 \(\log K\) 的计算,此时可以得到 50pts 的高分。

我们观察到:若令 \(d=\gcd(m,K)\),假定剩余了数字,那么剩余数字必然为 \(d\) 的倍数,且其是均匀的,将所有数字除以 \(d\) 都将剩余连续的区间。

不妨令 \(f(L,m,m^j,K)\) 表示当前保留的数为 \([1,L]\) 执行上述流程留下的数字数。

  • \(\gcd(m,K)=1\),答案为 \(L\),否则令 \(h(i)=im\mod K\),显然 \(d|h(i)\) 且其模 \(\frac{K}{d}\) 循环。
  • 被删除的个数等价于考虑 \(h\) 的取值位于 \((K-m^j,K)\) 内的数的个数。
  • \(L>\frac{K}{d}\),则 \(h(1)\sim h(L)\) 取遍了所有的 \(\frac{K}{d}\) 的值,剩下的都是 \((0,K-m^j]\)\(d\) 的倍数,删掉了 \(\frac{m^j}{d}\) 个数,我们递归到 \(f(\frac{L-m^j}{d},m,m^j\cdot \frac{m}{d},K/d)\)(注意 \(m\) 处也需要放缩)。
  • 否则显然 \(h(1)\sim h(L)\) 互不相同,在最终的递归中这些数字都将被删除,于是最后删除 \(L\) 个数。
  • 特别注意需要需要特判 \(K<m\) 的时候,此时返回 \(\min(L,K/d)\)
  • 复杂度 \(\mathcal O(T\cdot \log^2 n)\)
posted @ 2021-02-03 16:20  Soulist  阅读(132)  评论(0编辑  收藏  举报