隐藏页面特效

Luogu P5435 基于值域预处理的快速 GCD

突然想起来曾经偶然在陈指导的博客看到过这个O(1)gcd的方法,其实理解了之后还是比较简单的,以下设数的值域为S

首先我们定义对于一个数x的一种分解方式为三元组(a,b,c),满足abca×b×c=x,并且若c为合数则cx

证明的话也很简单,考虑若c>x,则a×b<x,考虑找到c的一种合法分解c=d×e满足dex那么必然可以把三元组调整为(d,a×b,e)

有了这个性质我们就很好办了,考虑询问gcd(x,y)的话我们可以分别考虑x的分解(a,b,c)y的贡献

ay的贡献就是将答案乘上gcd(a,y),然后将y除以gcd(a,y)来消去这个因子的贡献,再对b,c做同样的事即可

由于一般情况下a,b,cx,因此我们可以记录下S范围内的gcd,这样就可以O(1)处理了,当然质数的情况可以简单讨论掉

现在就要考虑怎么O(S)求所有数的分解了,其实很简单,只要在欧拉筛的时候通过x的最小质因子p

xp的分解为(a0,b0,c0),那么x的合法分解为{a0×p,b0,c0}的不降排序,考虑证明:

  1. x为质数是分解显然成立
  2. px4时,将a0xp3代入有a0×px
  3. p>x4时,分情况考虑:
    • a0=1,显然a0×px
    • a01,由于x不是质数,那么xp的最小质因子q就是x的第二小质因子,一定p。而a0,b0,c0都为xp的非1因子,故有pqa0b0c0,p×a0×b0×c0>(x4)4=x,矛盾。故不存在这种情况

因此代码就很简单了

#include<cstdio> #include<algorithm> #define RI register int #define CI const int& using namespace std; const int N=1000005,S=1000,mod=998244353; int n,a[N],b[N],prm[N],cnt,G[S+5][S+5],frac[N][3]; bool vis[N]; inline void init(CI n) { RI i,j; for (i=0;i<3;++i) frac[1][i]=1; for (i=2;i<=n;++i) { if (!vis[i]) for (prm[++cnt]=frac[i][2]=i,j=0;j<2;++j) frac[i][j]=1; for (j=1;j<=cnt&&i*prm[j]<=n;++j) { vis[i*prm[j]]=1; for (RI k=0;k<3;++k) frac[i*prm[j]][k]=frac[i][k]; frac[i*prm[j]][0]*=prm[j]; sort(frac[i*prm[j]],frac[i*prm[j]]+3); if (i%prm[j]==0) break; } } for (i=1;i<=S;++i) G[i][0]=G[0][i]=i; for (i=1;i<=S;++i) for (j=1;j<=i;++j) G[i][j]=G[j][i]=G[i%j][j]; } inline int gcd(int x,int y,int ret=1) { for (RI i=0;i<3;++i) { int cur; if (frac[x][i]>S) { if (y%frac[x][i]) cur=1; else cur=frac[x][i]; } else cur=G[frac[x][i]][y%frac[x][i]]; y/=cur; ret*=cur; } return ret; } int main() { //freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout); RI i,j; for (init(1000000),scanf("%d",&n),i=1;i<=n;++i) scanf("%d",&a[i]); for (i=1;i<=n;++i) scanf("%d",&b[i]); for (i=1;i<=n;++i) { int ans=0,cur=i; for (j=1;j<=n;++j,cur=1LL*cur*i%mod) (ans+=1LL*cur*gcd(a[i],b[j])%mod)%=mod; printf("%d\n",ans); } return 0; }

__EOF__

本文作者hl666
本文链接https://www.cnblogs.com/cjjsb/p/16852535.html
关于博主:复活的ACM新生,目前爱好仅剩Gal/HBR/雀魂/单机/OSU
版权声明:转载请注明出处
声援博主:欢迎加QQ:2649020702来DD我
posted @   空気力学の詩  阅读(56)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
历史上的今天:
2020-11-02 AtCoder Grand Contest 019
2020-11-02 Luogu P1654 OSU!
点击右上角即可分享
微信分享提示