P10171 [DTCPC 2024] 取模 题解

考虑不寻常的数据范围。

\(n\le 5\times 10^4\) 可以猜测,解法的时间复杂度是 \(\frac {n^2}w\),也就是使用 bitset。

然后我们发现 \(L,R\) 的范围非常大,但是事实上可以用到的非常少。

  • 如果 \(a\) 内有重复的数,答案一定为 \(0\)

  • 反之,对于 \(k\ge \max a_i\),这样的 \(k\) 一定合法。我们发现 \(a_i \le 4\times 10^5\)。所以需要的考虑的 \(R\) 也只有 \(4\times 10^5\)

问题已经转化成 \(1\le L \le R \le 4\times 10^5\) 的情况。后文记 \(\max a\)\(A\)

然后我们考虑怎么用 bitset 维护这个信息。

我们发现任意一组 \((a_i,a_j)\bmod k\) 相等,当且仅当 \(k|a_i-a_j\)。所以,我们维护 \(a_i-a_j\)\(a_i-a_j\) 的约数。

维护 \(a_i-a_j\) 的约数,复杂度变成了 \(n^2\sqrt A\),显然过不了。我们考虑反过来考虑,对于一个数 \(k\),如果存在正整数 \(p\),使得存在 \((i,j)\) 满足 \(a_i-a_j=pk\)。则 \(k\) 不满足要求。而维护某一个数的所有倍数,这是一个调和级数:\(\frac A 1+\frac A 2+\frac A 3 + \cdots + \frac A A \approx A\log A\)

然后,我们考虑做差怎么用 bitset 维护,这是一个经典 tricks。先将所有 \(a_i\) 标成 1,这个 01 数组记为 \(G\),然后固定 \(i\) 的所有 \(a_j-a_i\) 所构成的 \(01\) 数组即为 G 右移 \(a_i\) 位的 bitset,这一步的时间复杂度是 \(O(\frac n w)\)。对于每一个 \(a_i\) 都如此维护,即可得到我们所要的 \(a_i-a_j\) 构成的 01 数组 \(G'\)

对于一个数 \(k\),枚举其在 \(4\times 10^5\) 内的所有倍数 \(pk\),如果有 \(G'[pk]=1\) ,那么 \(k\) 也不合法,因此 \(G'[k]=1\)

然后不管用 count 还是枚举转化过的 \([L,R]\) 暴力计数都可以。对于所有 \(G'[k]=1\)\(k\) 即代表 \(k\) 不合法。

有一些细节。

posted @ 2024-02-29 15:00  wtcqwq  阅读(15)  评论(0)    收藏  举报