欧拉计划 第二十一题

Let d(n) be defined as the sum of proper divisors of n (numbers less than n which divide evenly into n).If d(a) = b and d(b) = a, where ab, then a and b are an amicable pair and each of a and b are called amicable numbers.

For example, the proper divisors of 220 are 1, 2, 4, 5, 10, 11, 20, 22, 44, 55 and 110; therefore d(220) = 284. The proper divisors of 284 are 1, 2, 4, 71 and 142; so d(284) = 220.

Evaluate the sum of all the amicable numbers under 10000.

设d(n)定义为n的适当除数之(小于n的数均匀分成n)。如果d(a)= b并且d(b)= a,其中ab,则ab是友好对,并且ab中的每一个被称为友好数字。

例如,220的适当除数是1,2,4,5,10,11,20,22,44,55和110; 因此d(220)= 284. 284的适当除数是1,2,4,71和142; 所以d(284)= 220。

评估10000以下所有友好数字的总和。

思路

1.一个正整数n被分解成质数相乘,如12 = 2(2)*3; p1(a1) p2(a2)p3(a3);

2.因子个数=(a1+1)(a2+1)(a3+1),如12的因子个数=(2+1)(1+1)=6;

3.F(A * B)=F(A)*F(B);

4.因子和:Eg 12因子和=28=(1+3)(1+2 + 2*2)

Sum_factor(n) = (p1^0 + p1^1 + p1 ^2 + ... + p1^a1)*(P2^0 + p2^1 +...+p2^a2) *... *(pn^0 + pn ^1 +...+ pn^an)

= 求乘[1-pi^(ai + 1)]/1-pi;

F(B) = F(A)/{[1-p1^ (a1+1)]/1-p1}*{[1-p1^(a1+2)]/1-p1}=F(A) * [1 - p1^(a1+2)]/[1 - p1^(a1+1)];

#include <stdio.h>

#define max 10000

int prime[max + 5] = {0};
int Sum_factor[max + 5] = {0};
int isprime[max + 5] = {0};

int main(){
	Sum_factor[1] = 0;
	for(int i = 2; i <= max; i++){//素数筛框架;
		if(!isprime[i]){
			prime[++prime[0]] = i;
			Sum_factor[i] = i + 1;//如果是素数的话,因子和为i+1;Eg:3的因子和=1 + 3;
			isprime[i] = i;
		}
		for(int j = 1; j <= prime[0]; j++){
			if(prime[j] * i > max) break;
			if(i % prime[j] == 0){
				isprime[i * prime[j]] = isprime[i] * prime[j];//isprime[i]存放i的最小因子项的幂次值;
				Sum_factor[i * prime[j]] = Sum_factor[i] * (isprime[i] * prime[j] * prime[j] - 1)/ (isprime[i] * prime[j] - 1) ;//F(B)=F(A)*(p1^(a1+2) - 1)/(p1^(a1+1)-1);
				break;
			}else{
				isprime[i * prime[j]] = prime[j];
				Sum_factor[i * prime[j]] = Sum_factor[i] * Sum_factor[prime[j]];//i与prime[j]互质,那么用公式F(A*B)=F(A)*F(B);
			}
		}
	}
	for(int i = 0; i <= max; i++){
		Sum_factor[i] -= i;
	}
	int ans = 0;
	for(int i = 1; i <= max; i++){
		if(Sum_factor[Sum_factor[i]] == i && Sum_factor[i] <= max && Sum_factor[i] != i){
			ans += i;
		}
	}
	printf("%d\n", ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38362049/article/details/81026182