关于1-n任意的gcd的和

gcd和

题目

GCD sum
公约数的和
大意是让你求1-n任意两个数的gcd的和之类的。

解法

显然你需要枚举对吧,不然你怎么可能求出gcd呢?
其次我们需要一些数学推理
令F(n)表示\(\sum_{i=1}^{n}gcd(1,n)\)
则我们只需要求出\(2\times \sum_{i=1}^{n}F(i) + \sum_{i=1}^{n}i\)对吧。
那么成立的充要条件是\(gcd(a/d,b/d)=1\),则我们就知道\(gcd(a/d,b/d)*d=gcd(a,b)\)
那么所以我们需要求出有多少个1-n/d的互质的数,显然这就是欧拉函数
所以我们就有了如下两道题目代码

//code 1
#include<bits/stdc++.h>
#define int long long //还是自觉换long long 更好吧
using namespace std;
const int maxn=100000+5;
int phi[maxn];
int f[maxn];
int s[maxn];
void get(int n) {
    for(int i=2; i<=n; i++) phi[i]=0;
    phi[1]=1;
    for(int i=2; i<=n; i++) {
        if(!phi[i]) {
            for(int j=i; j<=n; j+=i) {
                if(!phi[j]) phi[j]=j;
                phi[j]=phi[j]/i*(i-1);
            }
        }
    }
}
main() {
    int n;
    cin>>n;
    get(n);
    for(int i=1; i<=n; i++)
        for(int j=i*2; j<=n; j+=i)
            f[j]+=i*phi[j/i];
    for(int i=1; i<=n; i++) s[i]=s[i-1]+f[i];
    cout<<s[n]*2+(1+n)*n/2;
    return 0;
}
//code 2
#include<bits/stdc++.h>
#define int long long //还是自觉换long long 更好吧
using namespace std;
const int maxn=2000000+5;
int phi[maxn];
int f[maxn];
int s[maxn];
void get(int n) {
    for(int i=2; i<=n; i++) phi[i]=0;
    phi[1]=1;
    for(int i=2; i<=n; i++) {
        if(!phi[i]) {
            for(int j=i; j<=n; j+=i) {
                if(!phi[j]) phi[j]=j;
                phi[j]=phi[j]/i*(i-1);
            }
        }
    }
}
main() {
    int n;
    cin>>n;
    get(n);
    for(int i=1; i<=n; i++)
        for(int j=i*2; j<=n; j+=i)
            f[j]+=i*phi[j/i];
    for(int i=1; i<=n; i++) s[i]=s[i-1]+f[i];
    cout<<s[n];
    return 0;
}

转载于:https://www.cnblogs.com/ifmyt/p/9886203.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值