【浅谈】exgcd 中的整数溢出
首先我们知道, exgcd 中求得 x,y 的绝对值满足 : |x| <=b , |y| <= a 。同时 x, y 在数据大时远小于 a, b 规模。
例一:CF1244C The Football Season
首先看数据范围,a, b<=1e5, p<=1e17 , 来看错误的溢出写法:
x=(x*(p/r)%(b/r)+(b/r))%(b/r)
y=(c-a*x)/b
当 r=1 ,p=1e17 时, x*(p/r) 直接爆 longlong 了。
正确写法:
ll mo=b/r
x=(x%mo*((p/r) % mo)%mo + mo)%mo
y=(c-a*x)/b
这里用到的方法是提前对 p/r 取模。因为 a,b,mo,x <= 1e5 ,所以这里不会溢出。
例二:HDU_4180_RealPhobia
数据范围:a,b <= 2^31
ll mo=b/r;
x=(x%mo*(r%mo)%mo+mo)%mo;
y=(1ll-a*x)/b
前文我们提到 |x| 的规模远小于 a,b 规模,但是真的没有隐患吗?
input: 2147483647 2147483648
output: 2147483647 -2147483646
(取模后的结果)
input: 3147483647 3147483650
output: -1049161217 1049161216
(这是取模前的结果)
可以发现取模前和取模后的结果都不安全。本题中,1-a*x=1-ab>=1-a(a-1)>=-2^62 + 2^31 +1 ,刚好不会爆 longlong 。
摸索一下午得出的结论 : 写一个快速乘除法可以有效避免溢出。
A C AC AC C o d e Code Code
__EOF__

本文链接:https://www.cnblogs.com/cqbzly/p/17530272.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」