51nod 1040 最大公约数之和

 

1040 最大公约数之和

  1. 1 秒
  2.  
  3. 131,072 KB
  4.  
  5. 80 分
  6.  
  7. 5 级题

给出一个n,求1-n这n个数,同n的最大公约数的和。比如:n = 6

1,2,3,4,5,6 同6的最大公约数分别为1,2,3,2,1,6,加在一起 = 15

 收起

输入

1个数N(N <= 10^9)

输出

公约数之和

输入样例

6

输出样例

15

题目很简单,我们可以知道一个数的gcd一定是这个数的因子,现在我们来观察,比如15

1,2,4,7,8,11,13,14 这几个数和15的gcd都是1

3,6,9,12 这几个数和15的gcd都是3

5,10 这几个数和15的gcd都是5

15 这个数和15的gcd都是15

所以gcd之和是1 * 8 + 3 * 4 + 2 * 5 + 1 * 15 = 45

我们可以枚举因子i,那么gcd(x,n) = i ,假如gcd(i,n) = x有y个,那么i这个因子所做的贡献和就是y * i

又∵gcd(i,n) = x ∴gcd(n / i,x / i) = 1  因为x是n的约数,也是i的倍数,那么问题现在就转变成,枚举i,来求1到n / i中与n / i 互质的数有多少个,用欧拉函数算即可 (突然发现自己一直保存的phi的模板出锅了,我把res写成x了,找了一万年的错误)

#include <bits/stdc++.h>
#include <time.h>
#define first fi
#define second se


using namespace std;

typedef long long ll;
typedef double db;
int xx[4] = {1,-1,0,0};
int yy[4] = {0,0,1,-1};
const double eps = 1e-9;
typedef pair<int,int>  P;
const int maxn = 600  ;
const ll mod = 1e9 + 7;
inline int sign(db a) {
    return a < -eps ? -1 : a > eps;
}
inline int cmp(db a,db b) {
    return sign(a - b);
}
ll mul(ll a,ll b,ll c) { ll res = 1; while(b) {  if(b & 1) res *= a,res %= c;  a *= a,a %= c,b >>= 1;  }  return res;}
ll phi(ll x) {  ll res = x;  for(ll i = 2; i * i <= x; i++) { if(x % i == 0) res = res / i * (i - 1);   while(x % i == 0) x /= i;   }  if(x > 1) res = res / x  * (x - 1);    return res;}
ll c,n,k;
int main() {
    ios::sync_with_stdio(false);
    while(cin >> n) {
        ll ans = 0;
        for(ll i = 1; i * i <= n; i++) {
            if(n % i == 0) {
                ans +=  i  * phi(n / i) ;
                if(i != n / i)
                    ans += (n / i) * phi(i);
            }
        }
        cout << ans << endl;
    }
    //cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
    return 0;
}


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值