推式子萌新来推推看式子。
n∑i=1m∑j=1σ(ij)φ(ij)
先把 σ 和 φ 展开来。
n∑i=1m∑j=1φ(i)φ(j)gcd(i,j)φ(gcd(i,j))∑x|i∑y|j[gcd(x,y)=1]
替换 [gcd(x,y)]=1。
n∑i=1m∑j=1φ(i)φ(j)gcd(i,j)φ(gcd(i,j))∑x|i∑y|j∑d|x,d|yμ(d)
换个枚举顺序,把 d 的枚举提前。
n∑i=1m∑j=1φ(i)φ(j)gcd(i,j)φ(gcd(i,j))∑d|gcd(i,j)σ(id)σ(jd)μ(d)
再换个枚举顺序,把 d 的枚举再提前。
n∑d=1n/d∑i=1m/d∑j=1φ(id)φ(jd)gcd(i,j)dφ(gcd(i,j)d)σ(i)σ(j)μ(d)
枚举 z=gcd(i,j)。
n∑d=1μ(d)dn/d∑z=1n/dz∑i=1m/dz∑j=1φ(idz)φ(jdz)zφ(zd)σ(iz)σ(jz)[gcd(i,j)=1]
换个顺序。
n∑d=1μ(d)dn/d∑z=1zφ(zd)n/dz∑i=1σ(iz)φ(idz)m/dz∑j=1σ(jz)φ(jdz)[gcd(i,j)=1]
再替换 [gcd(i,j)=1]。
n∑d=1μ(d)dn/d∑z=1zφ(zd)n/dz∑i=1σ(iz)φ(idz)m/dz∑j=1σ(jz)φ(jdz)∑w|i,w|jμ(w)
把 w 放到前面枚举。
n∑d=1μ(d)dn/d∑z=1zφ(zd)n/dz∑w=1μ(w)n/dzw∑i=1σ(iwz)φ(iwdz)m/dzw∑j=1σ(jwz)φ(jwdz)
定义两个函数:
A(x,y)=n/xy∑i=1σ(iy)φ(ixy)
B(x,y)=m/xy∑i=1σ(iy)φ(ixy)
原式可以转化为:
n∑d=1μ(d)dn/d∑z=1zφ(zd)n/dz∑w=1μ(w)A(d,zw)B(d,zw)
首先可以发现:乘积小于等于 n 的三元组个数是 O(nlog2n) 级别的。所以我们可以在 O(nlog2n) 的时间复杂度内计算出所有 A(x,y) 和 B(x,y)。
如果已经算出了 A 和 B,剩下的按照上面的式子算,容易发现也是 O(nlog2n) 的。所以我们用 O(nlog2n) 完成了这道题。
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> m;
init();
ll ans=0;
for (int d=1;d<=n;d++)
{
for (int j=1;j<=n/d;j++)
{
a[j]=0;
for (int i=1;i<=n/(d*j);i++) a[j]=(a[j]+1ll*D[i*j]*phi[i*d*j]%mod)%mod;
b[j]=0;
for (int i=1;i<=m/(d*j);i++) b[j]=(b[j]+1ll*D[i*j]*phi[i*d*j]%mod)%mod;
}
for (int j=1;j<=n/d;j++)
{
for (int w=1;w<=n/(d*j);w++)
{
ans=ans+1ll*mu[d]*mu[w]*inv[phi[j*d]]*d%mod*j%mod*a[j*w]%mod*b[j*w]%mod;
ans=(ans+mod)%mod;
}
}
}
cout << ans;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?