poj2480

题目链接:http://poj.org/problem?id=2480

题目大意:求一个数n的gcd(i,n)求和(i从1到n)

思路:

设函数g(n) = gcd(i,n) (1<=i<=n),由积性函数的定义,g(n)=g(m1)*g(m2) (n=m1*m2 且 (m1, m2)= 1),所以g是积性函数。由具体数学上的结论,积性函数的和也是积性的。所以f(n) = ∑gcd(i, n)也是积性函数。由初等数论中的定理,如果f(n)是不恒为0的数论函数,n>1时 n=p1^a1*p2^a2*...*ps^as,那么f(n)是积性函数的充要条件是f(1)=1,及f(n) = f(p1^a1)*f(p2^a2)*...f(pr^ar)。所以只要求f(pi^ai)就好,如果d是n的一个约数,那么1<=i<=n中gcd(i,n) = d的个数是phi(n/d),即n/d的欧拉函数
求出来的公式参考这个博客:https://blog.csdn.net/qq_41515833/article/details/95961608

先唯一分解,再直接利用这个公式,ac!

ac代码:

#include<iostream>
#include<cstring>
#include<algorithm>
typedef long long ll;
using namespace std;
ll poww(ll a,ll b) {
    ll ans = 1, base = a;
    while (b != 0) {
        if (b & 1 != 0)
            ans *= base;
            base *= base;
            b >>= 1;
    }
    return ans;
}
struct node{
    ll p;
	ll m;	
}su[105];
int main(){
	ll n;
	while(cin>>n){
	    ll ans=1;
	    ll cnt=0;
	    //唯一分解
		for(ll i=2;i*i<=n;i++){
			if(n==1)
			break;
			if(n%i==0){
				su[cnt].p=i;
				su[cnt].m=0;
				while(n%i==0){
					n/=i;
					su[cnt].m++;
				}
				cnt++;
			}
		}
		if(n!=1){
			su[cnt].p=n;
			su[cnt].m=1;
			cnt++;
		}
		ll t;
		for(int i=0;i<cnt;i++){
			t=su[i].m*(poww(su[i].p,su[i].m)-poww(su[i].p,su[i].m-1))+poww(su[i].p,su[i].m);
		    ans*=t;
		}
		 
		 cout<<ans<<endl;
		 
		 
	}
	return 0;
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值