基于值域的快速GCD
这其实是一道洛谷模板题,题目是5435
对预处理的讲解可以看看这个博客(代码看自己的,见下)
void getprime()
{
for(int i=0;i<=2;i++) fac[1][i]=1;
for(int i=2;i<=N-10;i++)
{
if(!v[i])
{
v[i]=i;
prime[++tot]=i;
fac[i][0]=fac[i][1]=1;
fac[i][2]=i;
}
for(int j=1;j<=tot;j++)
{
if(prime[j]>v[i]||(ll)i*prime[j]>N-10) break;
int tmp=i*prime[j];
v[tmp]=prime[j];
fac[tmp][0]=fac[i][0]*prime[j];
fac[tmp][1]=fac[i][1];
fac[tmp][2]=fac[i][2];
if(fac[tmp][0]>fac[tmp][1]) {
fac[tmp][0]^=fac[tmp][1]^=fac[tmp][0]^=fac[tmp][1];
}
if(fac[tmp][1]>fac[tmp][2]) {
fac[tmp][1]^=fac[tmp][2]^=fac[tmp][1]^=fac[tmp][2];//这个操作就是升序排序
}
}
}
}
void init()
{
for(int i=0;i<=M-10;i++)
pre[i][0]=pre[0][i]=i;
for(int i=1;i<=M-10;i++)//M是值域开根号
for(int j=1;j<=i;j++)
pre[i][j]=pre[j][i]=pre[j][i%j];
}
那么这篇博客对查询的讲解不太细致,其实就是用到一个定理
这个定理的证明暂时不详,有机会可以了解
但是查询时一定要注意,某一次的x可能是质数,此时想的分解为1,1,x,那么这个时候就别用预处理的数组了,可能会超出范围,这个时候特判即可,代码见下
int gcd(int a,int b)
{
int d1,d2,d3;
d1=pre[fac[a][0]][b%fac[a][0]];
b/=d1;
d2=pre[fac[a][1]][b%fac[a][1]];
b/=d2;
if(v[fac[a][2]]==fac[a][2])
{
if(b%fac[a][2]==0) d3=fac[a][2];
else d3=1;
}
else d3=pre[fac[a][2]][b%fac[a][2]];
return (ll)((ll)d1*d2)%p*d3%p;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构