0x00 题目翻译

有一个长度为 nn 的序列 aaqq 个询问,每个询问给出一个区间 l,rl,r 要求查询最大的 mm 使得这个区间里所有数字模 mm 的结果相同(如果 mm 可以取得无穷大,输出 00)。

0x01 解题思路

这里要求余数全部相同,这样入手不好分析,那么尝试反向思考:如果余数已经相同,mm 已经确定,那么序列会有什么性质?

设原序列为 a1,a2,,ana_1,a_2,\cdots,a_n,那么可以表示为 k1m+x,k2m+x,,knm+xk_1m+x,k_2m+x,\cdots,k_nm+x,其中 xx 是那个相同的余数。

观察到每一项带有相同的 xx,尝试将它消掉,可以将相邻两项做差,求出一个差分序列 bb,即 $0,\vert a_1-a_2\vert ,\vert a_2-a_3\vert ,\cdots,\vert a_{n-1}-a_n\vert $,也就是 $0,\vert k_1-k_2\vert m,\vert k_2-k_3\vert m,\cdots,\vert k_{n-1}-k_n\vert $,这时,就可以用 bb 的区间最大公约数求出最大的 mm(序列 bb 开头的 00 只是在写代码时和 l,rl,r 对齐位置,没有意义)。

0x02 算法实现

似乎大部分人用的是 ST 表,但这里我用的是线段树(因为不会 ST 表),只有查询,没有修改,是比较好写的。

0x03 易错要点

  1. 输入的查询区间不是 bb 中的区间,应为 l+1,rl+1,r
  2. 注意当 l=rl=r 时要特判,否则你的实际查询会 l+1>rl+1>r 导致 RE。
  3. 建树时可以只用 2,n2,n 的一段数值传入,但同样应注意 n=1n=1 的情况。

0x04 程序代码