[欧拉函数]51nod 1040 最大公约数之和 题解

(传送门)

题目大意

∑ i = 1 n   g c d ( i , n ) \sum_{i=1}^{n}\ gcd(i,n) i=1n gcd(i,n)

解题分析

注意,所有gcd(x,n)最后都是n的因数。所以可以对因数分类,设 f ( i ) f(i) f(i) g c d ( x , n ) = = i 且 i &lt; n gcd(x,n)==i且i&lt;n gcd(x,n)==ii<n的正整数x,则
a n s = ∑   i ∗ f [ i ] ∣ i 为 n 的 因 数 ans=\sum\ i*f[i]|i为n的因数 ans= if[i]in

如果 g c d ( x , n ) = i gcd(x,n)=i gcd(x,n)=i,则 g c d ( x / i , n / i ) = 1 gcd(x/i,n/i)=1 gcd(x/i,n/i)=1,gcd()=1就想到了欧拉函数,所以最后 f [ i ] = φ ( n / i ) f[i]=\varphi(n/i) f[i]=φ(n/i)

复杂度:
时间: O ( n ) O(\sqrt{n}) O(n )
空间: O ( 1 ) O(1) O(1)

#include<cmath>
#include<cstdio>
#define LL long long
using namespace std;
int n,S,p[10005];
LL ans;
int getp(int x){
	int sum=x; for (int i=2,S=sqrt(x);i<=S;i++) if (x%i==0) {sum=sum/i*(i-1); while (x%i==0) x/=i;}
	if (x>1) sum=sum/x*(x-1); return sum;
}
int main()
{
	freopen("gcda.in","r",stdin);
	freopen("gcda.out","w",stdout);
	scanf("%d",&n); S=sqrt(n); ans=0;
	for (int i=1;i<=S;i++)
		if (n%i==0){
			int t=n/i;ans+=(LL)i*getp(t);
			if (i!=t) ans+=(LL)t*getp(i);
		}
	printf("%lld",ans);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值