您的位置:首页 > 其它

[51nod1040]最大公约数之和

2016-07-06 15:31 295 查看

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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: