【JZOJ4496】互补约数
【JZOJ4496】互补约数
by AmanoKumiko
Description
已知
\[f(i)=Σ_{d|i}(d,\frac{i}{d})
\]
求
\[F(n)=Σ_{i=1}^nf(i)
\]
Input
输入包含一行,一个正整数 n。
Output
输出只有一行, F(n)。
Sample Input
10
Sample Output
32
Data Constraint
\(n<=10^{11}\)
Solution
很妙的转换
考虑直接求解F
\[F(n)=Σ_{d1}Σ_{d2}(d1,d2)[d1d2<=n]
\]
原因:每一组\(d1d2<=n\)都会对\(f(d1d2)\)造成贡献
\[F(n)=Σ_{k=1}^{n}kΣ_{d1=1}^{n}Σ_{d2=1}^{\lfloor\frac{n}{d1}\rfloor}[(d1,d2)=k]
\]
\[F(n)=Σ_{k=1}^{n}kΣ_{d1=1}^{\lfloor\frac{n}{k^2}\rfloor}Σ_{d2=1}^{\lfloor\frac{n}{k^2d1}\rfloor}[(d1,d2)=1]
\]
\(k^2\)的原因:令\(d1=i1·k\),\(d2=i2·k\),\(d1d2=i1i2k^2<=n\)
\(∴i1<=\lfloor\frac{n}{k^2}\rfloor\)
下面同理
\[F(n)=Σ_{k=1}^{n}kΣ_{d=1}μ(d)Σ_{d1=1}^{\lfloor\frac{n}{d^2k^2}\rfloor}\ \lfloor\frac{n} {d^2k^2d1}\rfloor
\]
令\(T=dk\)
\[F(n)=Σ_{T=1}^{\sqrt{n}}Σ_{k|T}k·μ(\frac{T}{k})Σ_{d1=1}^{\lfloor\frac{n}{T^2}\rfloor}\ \lfloor\frac{n}{T^2d1}\rfloor
\]
\[F(n)=Σ_{T=1}^{\sqrt{n}}φ(T)Σ_{d1=1}^{\lfloor\frac{n}{T^2}\rfloor}\ \lfloor\frac{n}{T^2d1}\rfloor
\]
故数论分块求解
Code
#include<bits/stdc++.h>
using namespace std;
#define F(i,a,b) for(int i=a;i<=b;i++)
#define Fd(i,a,b) for(int i=a;i>=b;i--)
#define LL long long
#define N 320010
LL n,phi[N],prime[N],tot,ans;
bool vis[N];
LL calc(LL x){
LL res=0;
for(LL l=1,r;l<=x;l=r+1)r=x/(x/l),res+=(r-l+1)*(x/l);
return res;
}
int main(){
freopen("gcd.in","r",stdin);
freopen("gcd.out","w",stdout);
scanf("%lld",&n);
phi[1]=vis[1]=1;
F(i,2,N-10){
if(!vis[i])prime[++tot]=i,phi[i]=i-1;
for(int j=1;j<=tot&&prime[j]*i<=N-10;j++){
vis[prime[j]*i]=1;
if(!(i%prime[j])){phi[i*prime[j]]=phi[i]*prime[j];break;}
else phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
}
F(i,1,sqrt(n))ans+=phi[i]*calc(n/((LL)i*i));
printf("%lld",ans);
return 0;
}