区间同余问题

区间同余问题

例题 :CF2050F Maximum modulo equality

题意

给定一个长度为 n 的序列 an,有 Q 个询问,每次询问给定一个区间 [l,r] ,让你找一个最大的 m,使得区间内所有的 aimodm 相同,可以证明一定存在这样一个 m1)。

分析

看着很头痛,因为完全不知道从哪里入手,所以只做了这样一个转化 ai=ki×m+t,然后就不知道该怎么办了。
假设这样一个 m 满足题意的话,那么所有的 ai 其实都必须可以写成这样的形式,也就是 al=kl×m+t,al+1=kl+1×m+t,...,ar=kr×m+t,变量的个数仍然比较多,还是没有任何头绪啊。
这时候你会发现这实际上是一个线性方程组,从线性代数的角度思考,实际上任意两个非齐次方程相减就可以得到一个齐次方程,虽然和这个地方差别还是很大,不过可以尝试去沿袭这个思路。
比如对于 a1,a2 来说,把两个等式相减,有 abs(a1a2)==abs(k1k2)×m,这就意味着 m 一定是 abs(a1a2) 的因子。那么我们只需要保证 [l,r] 内的 n2 对都满足这个条件即可,也就是求这 n2 对的 GCD,但是这会超时,仔细思考,n2 对是不是太多了?实际上我们只需要对每一对相邻的进行这种操作,就可以保证所有对都可以被线性表示出来,也自然就满足了所有的限制(这个地方自己推一下就知道了)。

考虑 m 可以无限大的情况,肯定是区间每一个数都相等,这时候根据算法算出来的是 0,刚好也和题目要求契合了。

时间复杂度允许的情况下可以直接 O(n) 查询,但是如果只能 O(logn) 以下的话,只能用一些RMQ了。
但是这样就要注意,在合并两个区间的时候,不能直接把两份答案gcd起来,这样的话,并不能保证每一对都满足限制条件,比如各从两个区间内选一个,那么就不是满足的。因此我们在合并两个区间的时候还要注意 随便从两个区间里面分别取一个数gcd一下,然后丢到答案的GCD里面去。
这里ST表取的直接就是 al,ar,线段树取的是 amid,amid+1

注意

gcd不能写成 return x%y==0?y:gcd(y,x%y) 。不然会RE。

Code_ST

COde_Seg

延伸

这让我想到了之前有一场 div2 的 A,就是给定一个 x,y,然后求一个最小的 t,使得tmodx=tmody,这种情况可以证明最小的能够找到的 m 一定是lcm(x,y)。这个其实画一下数轴就可以直观地感受出来了。

posted @   Hanggoash  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!
动态线条
动态线条end
点击右上角即可分享
微信分享提示