Description
求
∑i=1ngcd(i,n)
n<=10^9
Solution
这道题有多种做法。
我们设
f(n)=∑ni=1gcd(i,n)
那么f应该是积性函数。(证明自行脑补)
也就是说我们要求出来
f(pk)p是质数
直接推式子似乎很麻烦,我们换个思路。
如何从
f(pk)
转移到
f(pk+1)
?
首先,因为我们可以把f(p^k)*p,那么就构成了f(p^k+1)的答案中所有不为1的部分.
(显然
gcd(i,p)=gcd(i∗p,p2)∗p
)
那么剩下的为1的就是
φ(pk+1)
了。
于是我们得到了
f(pk+1)=f(pk)∗p+φ(pk+1)
于是就解决了。
然而,我发现似乎只有我一个人想用积性函数的方法。
其余的都是机智的直接
φ
法。
因为我们的答案都是n的因数。那么我们把它分解质因数,枚举每个因数x,我们就是要求1~n有多少个数k满足
gcd(x,k)=x
很显然有
φ(nx)
个。
于是暴力求
φ
也可以。
Code
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long long ll;
ll ans;
int a[32],b[32],n;
int main() {
scanf("%d",&n);int i=2;ans=1;
fo(i,2,sqrt(n)) {
if (!(n%i)) a[++a[0]]=i;
while (!(n%i)) b[a[0]]++,n/=i;
}
if (n>1) a[++a[0]]=n,b[a[0]]=1;
fo(i,1,a[0]) {
ll sum=1,x=1;
fo(j,1,b[i]) sum=sum*a[i]+x*(a[i]-1),x*=a[i];
ans*=sum;
}
printf("%lld",ans);
}