畢達哥拉斯學派發現:兩數 a, b,若 a 的真因數和 = b,b 的真因數和 = a,則稱之為親和數。
例:220 真因數和 = 284,284 真因數和 = 220。
其他對:(1184,1210)、(2620,2924)……
直接模擬 + 剪枝,偽親和數量級達 10¹³,千萬次/秒也要 3 年。優化需空間換時間,但數據規模大,伴隨數組空間代價高。
關鍵洞察:利用下標即數值的數組特性,將「回溯」轉為「遞推預處理」——類埃氏篩。
// 時間複雜度 O(N log N) + O(N) = O(N log N) (log N 為調和級數)
#include <stdio.h>
int sum[5000010]; // 防越界
int main() {
int i, j;
// 1 是所有數真因數,初始化為 1
for (i = 0; i <= 5000000; i++) sum[i] = 1;
// 預處理:i 從 2 到 2500000,為所有倍數累加 i
for (i = 2; i + i <= 5000000; i++) {
j = i + i; // 真因數不含自身,從 2*i 開始
while (j <= 5000000) {
sum[j] += i; // j 是 i 的倍數,i 是 j 的真因數
j += i;
}
}
// 掃描:從最小親和數 220 開始
for (i = 220; i <= 5000000; i++) {
if (sum[i] > i && sum[i] <= 5000000 && sum[sum[i]] == i) {
printf("%d %d ", i, sum[i]); // 去重、不越界、滿足定義
}
}
return 0;
}

sum[x] 即為 x 的真因數和(類埃氏篩)。初始全置 1 → i=2,3,4,5 為倍數加 i → 得 sum[6]=1+2+3=6、sum[10]=1+2+5=8……
掃描時 sum[220]=284 且 sum[284]=220,即得一對親和數。