1. 程式人生 > 其它 >【JZOJ4496】互補約數

【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;
}