1 条题解
-
0
自动搬运
来自洛谷,原作者为

hsfzLZH1
我永远喜欢珂朵莉搬运于
2025-08-24 22:07:56,当前版本为作者最后更新于2019-01-18 12:31:15,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
感觉标准题解里的式子推错了。。。我来写一篇详细一点的题解吧。
注意:本文所有除法均为向下取整。
公式、引理及证明
引理:$gcd(ij,ik,jk)=\frac {gcd(i,j)gcd(i,k)gcd(j,k)}{gcd(i,j,k)}$
证明:考虑每个数质因数的幂次,设 关于质因子 的幂次分别为 ,不妨设 。
易证 关于 的幂次为 。
则原式关于 的幂次的式子等于
$min(a+b,a+c,b+c)=min(a,b)+min(a,c)+min(b,c)-min(a,b,c)$
即 ,显然成立。
若两个数关于各质因子的幂次都相等,则这两个数相等。
得证。
所以
$Ans=\sum_{i=1}^n \sum_{j=1}^m \sum_{k=1}^p gcd^2(i,j)+gcd^2(i,k)+gcd^2(j,k)$
发现每个 中都只有两个参数,第三个参数不会影响 的值,只会影响 的值出现的次数,分别枚举,得
发现要求的 的平方和都是形如 的,莫比乌斯反演如下:
枚举 的值
$\sum_{i=1}^n \sum_{j=1}^m gcd^2(i,j)=\sum_{d=1}^{min(n,m)} d^2\sum_{i=1}^n\sum_{j=1}^m [gcd(i,j)=d]$
对于方括号内的内容,如果式子的值为真,则方括号的返回值为 ,否则为 。
,只有在 均为 的倍数时才有可能,所以只枚举 均为 的倍数的情况
$=\sum_{d=1}^{min(n,m)} d^2 \sum_{i=1}^{\frac n d} \sum_{j=1}^{\frac m d} [gcd(i,j)=1]$
现在题目转化为求 的值了。
我们设 , ,易得
而因为 是 的倍数,当且仅当 均为 的倍数,所以
由倍数反演的式子
$=\sum_{d=1}^{min(n,m)} \mu(d)\times \frac n d\times \frac m d$
$\therefore \sum_{i=1}^n \sum_{j=1}^m gcd^2(i,j)=\sum_{d=1}^{min(n,m)} d^2 \sum_{i=1}^{\frac n d} \sum_{j=1}^{\frac m d} [gcd(i,j)=1]$
$=\sum_{d=1}^{min(n,m)} d^2 \sum_{g=1}^{min(\frac n d,\frac m d)} \mu(g)\times \frac n {gd}\times \frac m {gd}$
枚举 ,同时枚举 ,则
$=\sum_{T=1}^{min(n,m)} \frac n T \times \frac m T \times \sum_{d|T} d^2\mu(\frac T d)$
观察到 和 都最多分别只有 种取值(默认 同阶),可以用整除分块使枚举 的值的时间复杂度降为 ,现在的问题是,如何在合理的预处理时间内,在 的时间复杂度下求出 的值或前缀和。
观察到 和 都是 ** 积性函数 ** 。所求值的形式为两个函数的卷积,所以也是积性函数。考虑到 的预处理时间是可以接受的,借助它是积性函数的性质,我们可以利用 ** 线性筛 ** 计算出该函数的值。
记 。
根据定义计算得, $h(1)=1,h(p)=1^2\times \mu(p)+p^2\times \mu(1)=p^2-1$ ( 是质数)。
由积性函数的性质得, 。
现在,我们只需考虑线性筛的最后一个问题,若 ,则 如何表示?
引理:
证明:观察 函数的形式。因为 是 的最小素数因子,所以 一定含有 的平方因子。考虑 值对答案的贡献。 值为 时,即 有平方因子时,该 对答案无贡献。
若一个 的约数 对 的答案有贡献,则 对 的答案也有贡献,否则即有平方因子,即只有这些 对答案有贡献。因为乘上 后贡献的值乘了平方,所以答案会乘上 。
得证。
同理,该结论也能扩展到任意 的质因子 上。
同样的,也可以类比 的线性筛法得出 的线性筛方法。
代码展示
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=20000010; typedef long long ll; const ll mod=1000000007; ll T,n,m,p,cur,pri[maxn],f[maxn],sum[maxn]; bool tf[maxn]; ll calc(ll n,ll m) { ll ret=0; //for(ll T=1;T<=min(n,m);T++)ret=(ret+(n/T)*(m/T)%mod*f[T]%mod)%mod; for(ll i=1,j;i<=min(n,m);i=j+1) { j=min(n/(n/i),m/(m/i)); ret=(ret+(n/i)*(m/i)%mod*((sum[j]-sum[i-1]+mod)%mod)%mod)%mod; } return ret; } int main() { f[1]=1; for(ll i=2;i<=20000000;i++) { if(!tf[i]){pri[++cur]=i;f[i]=(i*i%mod-1+mod)%mod;} for(ll j=1;j<=cur&&i<=20000000/pri[j];j++) { tf[i*pri[j]]=true; if(i%pri[j]==0){f[i*pri[j]]=f[i]*pri[j]%mod*pri[j]%mod;break;} else f[i*pri[j]]=f[i]*f[pri[j]]%mod; } } for(ll i=1;i<=20000000;i++)sum[i]=(sum[i-1]+f[i])%mod; scanf("%lld",&T); while(T--) { scanf("%lld%lld%lld",&n,&m,&p); printf("%lld\n",(p*calc(n,m)%mod+m*calc(n,p)%mod+n*calc(m,p)%mod)%mod); } return 0; }
- 1
信息
- ID
- 4122
- 时间
- 5000ms
- 内存
- 500MiB
- 难度
- 7
- 标签
- (无)
- 递交数
- 0
- 已通过
- 0
- 上传者