📌  相关文章
📜  数组中所有自然数的适当除数的总和

📅  最后修改于: 2021-04-24 18:03:58             🧑  作者: Mango

给定一个自然数数组,请为数组中的每个元素计算其适当除数的总和。

Input  : int arr[] = {8, 13, 24, 36, 59, 75, 87}
Output : 7 1 36 55 1 49 21
Number 8 has 3 proper divisors 1, 2, 4
and their sum comes out to be 7.

在下面的文章中讨论了这个问题的幼稚解决方案。
自然数的所有适当除数的总和

我们可以通过使用Eratosthenes筛子来更有效地做到这一点。

这个想法是基于数字的素因数分解。通过使用筛子,我们可以存储一个数的所有素数及其幂。

To find all divisors, we need to consider
all powers of a prime factor and multiply
it with all all powers of other prime factors.
(For example, if the number is 36, its prime
factors are 2 and 3 and all divisors are 1,
2, 3, 4, 6, 9, 12 and 18.

Consider a number N can be written 
as P1^Q1 * P2^Q2 * P3^Q3 (here only 3 
prime factors are considered but there can 
be more than that) then sum of its divisors 
will be written as:
 = P1^0 * P2^0 * P3^0 + P1^0 * P2^0 * P3^1 + 
   P1^0 * P2^0 * P3^2 + ................ + 
   P1^0 * P2^0 * P3^Q3 + P1^0 * P2^1 * P3^0 + 
   P1^0 * P2^1 * P3^1 + P1^0 * P2^1 * P3^2 + 
   ................ + P1^0 * P2^1 * P3^Q3 +
   .
   .
   .
   P1^Q1 * P2^Q2 * P3^0 + P1^Q1 * P2^Q2 * P3^1 + 
   P1^Q1 * P2^Q2 * P3^2 + .......... + 
   P1^Q1 * P2^Q2 * P3^Q3

Above can be written as,
(((P1^(Q1+1)) - 1) / 
  (P1 - 1)) * (((P2^(Q2+1)) - 1) / 
  (P2 - 1)) * (((P3^(Q3 + 1)) - 1) / 
  (P3 - 1))

以下是基于以上公式的实现。

C++
// C++ program to find sum of proper divisors for
// every element in an array.
#include 
using namespace std;
#define MAX 1000001
#define pii pair
#define F first
#define S second
  
// To store prime factors and their
// powers
vector factors[MAX];
  
// Fills factors such that factors[i] is
// a vector of pairs containing prime factors
// (of i) and their powers.
// Also sets values in isPrime[]
void sieveOfEratothenese()
{
    // To check if a number is prime
    bool isPrime[MAX];
    memset(isPrime, true, sizeof(isPrime));
    isPrime[0] = isPrime[1] = false;
  
    for (int i = 2; i < MAX; i++)
    {
        // If i is prime, then update its
        // powers in all multiples of it.
        if (isPrime[i])
        {
            for (int j = i; j < MAX; j += i)
            {
                int k, l;
                isPrime[j] = false;
                for (k = j, l = 0; k % i == 0; l++, k /= i)
                    ;
                factors[j].push_back(make_pair(i, l));
            }
        }
    }
}
  
// Returns sum of proper divisors of num
// using factors[]
int sumOfProperDivisors(int num)
{
    // Applying above discussed formula for every
    // array element
    int mul = 1;
    for (int i = 0; i < factors[num].size(); i++)
        mul *= ((pow(factors[num][i].F,
                     factors[num][i].S + 1) - 1) /
                (factors[num][i].F - 1));
    return mul - num;
}
  
// Driver code
int main()
{
    sieveOfEratothenese();
    int arr[] = { 8, 13, 24, 36, 59, 75, 91 };
    for (int i = 0; i < sizeof(arr) / sizeof(int); i++)
        cout << sumOfProperDivisors(arr[i]) << " ";
    cout << endl;
    return 0;
}


Java
// Java program to find sum of proper divisors for
// every element in an array.
import java.util.*;
  
class GFG
{
      
static final int MAX = 100001;
  
static class pair
{ 
    int F, S;
  
    public pair(int f, int s) {
        F = f;
        S = s;
    } 
      
} 
// To store prime factors and their
// powers
static Vector []factors = new Vector[MAX];
  
// Fills factors such that factors[i] is
// a vector of pairs containing prime factors
// (of i) and their powers.
// Also sets values in isPrime[]
static void sieveOfEratothenese()
{
    // To check if a number is prime
    boolean []isPrime = new boolean[MAX];
    Arrays.fill(isPrime, true);
    isPrime[0] = isPrime[1] = false;
  
    for (int i = 2; i < MAX; i++)
    {
        // If i is prime, then update its
        // powers in all multiples of it.
        if (isPrime[i])
        {
            for (int j = i; j < MAX; j += i)
            {
                int k, l;
                isPrime[j] = false;
                for (k = j, l = 0; k % i == 0; l++, k /= i)
                    ;
                factors[j].add(new pair(i, l));
            }
        }
    }
}
  
// Returns sum of proper divisors of num
// using factors[]
static int sumOfProperDivisors(int num)
{
    // Applying above discussed formula for every
    // array element
    int mul = 1;
    for (int i = 0; i < factors[num].size(); i++)
        mul *= ((Math.pow(factors[num].get(i).F,
                    factors[num].get(i).S + 1) - 1) /
                (factors[num].get(i).F - 1));
    return mul - num;
}
  
// Driver code
public static void main(String[] args)
{
    for (int i = 0; i < MAX; i++)
        factors[i] = new Vector();
    sieveOfEratothenese();
    int arr[] = { 8, 13, 24, 36, 59, 75, 91 };
    for (int i = 0; i < arr.length; i++)
        System.out.print(sumOfProperDivisors(arr[i])+ " ");
    System.out.println();
}
}
  
// This code is contributed by 29AjayKumar


C#
// C# program to find sum of proper divisors for
// every element in an array.
using System;
using System.Collections.Generic;
  
class GFG
{
      
static readonly int MAX = 100001;
  
class pair
{ 
    public int F, S;
  
    public pair(int f, int s) 
    {
        F = f;
        S = s;
    } 
      
} 
  
// To store prime factors and their
// powers
static List []factors = new List[MAX];
  
// Fills factors such that factors[i] is
// a vector of pairs containing prime factors
// (of i) and their powers.
// Also sets values in isPrime[]
static void sieveOfEratothenese()
{
    // To check if a number is prime
    bool []isPrime = new bool[MAX];
    for (int i = 0; i < MAX; i++)
        isPrime[i] = true;
    isPrime[0] = isPrime[1] = false;
  
    for (int i = 2; i < MAX; i++)
    {
        // If i is prime, then update its
        // powers in all multiples of it.
        if (isPrime[i])
        {
            for (int j = i; j < MAX; j += i)
            {
                int k, l;
                isPrime[j] = false;
                for (k = j, l = 0; k % i == 0; l++, k /= i)
                    ;
                factors[j].Add(new pair(i, l));
            }
        }
    }
}
  
// Returns sum of proper divisors of num
// using factors[]
static int sumOfProperDivisors(int num)
{
    // Applying above discussed formula for every
    // array element
    int mul = 1;
    for (int i = 0; i < factors[num].Count; i++)
        mul *= (int)((Math.Pow(factors[num][i].F,
                    factors[num][i].S + 1) - 1) /
                (factors[num][i].F - 1));
    return mul - num;
}
  
// Driver code
public static void Main(String[] args)
{
    for (int i = 0; i < MAX; i++)
        factors[i] = new List();
    sieveOfEratothenese();
    int []arr = { 8, 13, 24, 36, 59, 75, 91 };
    for (int i = 0; i < arr.Length; i++)
        Console.Write(sumOfProperDivisors(arr[i])+ " ");
    Console.WriteLine();
}
}
  
// This code is contributed by 29AjayKumar


输出:

7 1 36 55 1 49 21