歐拉計(jì)劃 21

Amicable numbers

題目描述

d(n)n 的所有真約數(shù)(小于 n 且整除 n 的正整數(shù))之和。如果 d(a) = b,d(b) = a,且 a \neq b ,那么 a 和構(gòu)成一個(gè) b 親和數(shù)對(duì),ab 被稱為親和數(shù)。

求所有小于 10000 的親和數(shù)的和。

思路

歐拉篩求解素因子和
因子和公式

代碼

// 素?cái)?shù)篩算法求解因子和問題
#include <cstdio>
#include <cmath>
#include <algorithm>

using namespace std;
const int N = 10000;
int prime[N + 5];
int f[N + 5];
int cnt[N + 5]; // cnt[i] 記錄 i 最小素因子的冪次

void init() {
    for (int i = 2; i <= N; i++) {
        if (!prime[i]) {
            prime[++prime[0]] = i;
            f[i] = i + 1;
            cnt[i] = 1;
        }
        for (int j = 1; j <= prime[0] && prime[j] * i < N; j++) {
            prime[prime[j] * i] = 1;
            if (i % prime[j]) {  // i 與 prime[j] 互素
                f[i * prime[j]] = f[i] * f[prime[j]];
                cnt[i * prime[j]] = 1;
            }
            else {
                f[i * prime[j]] = f[i] / (pow(prime[j], cnt[i] + 1) - 1) * (pow(prime[j], cnt[i] + 2) - 1);  // 等比數(shù)列求和公式
                cnt[i * prime[j]] = cnt[i] + 1;
                break;
            }
        }
    }
}

int main() {
    init();
    for (int i = 2; i < N; i++) f[i] -= i;
    
    int ans = 0;
    for (int i = 2; i < N; i++) {
        if (f[i] != i && f[f[i]] == i) {
            ans += i;
            printf("%d %d\n", i, f[i]);
        }
    }
    
    printf("%d\n", ans);
    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容