Smart Stefanie

Title description

Insert picture description here

analysis

When it comes to sum of divisors, it is not difficult to think of the two formulas of sum of divisors and sum of divisors.
Insert picture description here
For this problem, if the number is greater than S, then the number must have two factors, one 1 and one S. Then this number must not meet the requirements, so it only needs to be considered in 1~S

Suppose that each prime factor decomposed by X is 2 30 =1 073 741 824, so the power of each prime factor will not be too much.
Assuming that each prime factor decomposed by X only appears once, and that They are all the smallest ones. The answer to the sum of prime numbers just considering the first 15 prime numbers is 1 610 612 736. The prime numbers decomposed by each factor will not be too many. The
two are combined, and the prime factors and powers decomposed by X are even more. It won't be big anymore!
Therefore, you can search directly and find out all the prime factors and powers.

First specify the search order, the default enumerated prime factor isStrictly monotonically increasing
If we want to enumerate all possible prime numbers directly, we need to enumerate numbers around 1e8. Obviously this is not possible. We need to think of some pruning to optimize the search process.
For each remaining S, we judge S Is it equal to a (prime number) + 1
If it is satisfied, then the following enumeration
is not necessary. If it is not satisfied, there are two cases as follows. In
Insert picture description here
either case, there must be pi 2 <S, so we only need Enumerate to S 1/2 , so the complexity is greatly reduced

Code

#include <bits/stdc++.h>
using namespace std;
const int N = 45000;
int prime[N], cnt;
bool st[N];
int ans[N], len;
void get_prime(int n)
{
    
    
    for (int i = 2; i <= n; i++)
    {
    
    
        if (!st[i])
            prime[cnt++] = i;
        for (int j = 0; prime[j] * i <= n; j++)
        {
    
    
            st[prime[j] * i] = 1;
            if (i % prime[j] == 0)
                break;
        }
    }
}
bool check(int n)
{
    
    
    if (n < N)
        return !st[n];
    for (int i = 0; prime[i] <= n / prime[i]; i++)
        if (n % prime[i] == 0)
            return 0;
    return 1;
}
//last表示当前用到的素数的下标是多少
//res表示当前的答案是多少
//s表示当前剩余的S是多少
void dfs(int last, int res, int s)
{
    
    
    if (s == 1) //表示这个数已经被完美的凑出来了
    {
    
    
        ans[len++] = res;
        return;
    }
    if (s - 1 > (last < 0 ? 1 : prime[last]) && check(s - 1))
        ans[len++] = res * (s - 1);
    for (int i = last + 1; prime[i] <= s / prime[i]; i++)
    {
    
    
        int temp = prime[i];
        for (int j = 1 + temp, t = temp; j <= s; t *= temp, j += t) //j保存的是和,t保存的是最后一个次幂的值
            if (s % j == 0)
                dfs(i, res * t, s / j);
    }
}
int main()
{
    
    
    get_prime(N - 1);
    int s;
    while (cin >> s)
    {
    
    
        len = 0;
        dfs(-1, 1, s);
        cout << len << endl;
        if (len)
        {
    
    
            sort(ans, ans + len);
            for (int i = 0; i < len; i++)
                cout << ans[i] << " ";
            cout << endl;
        }
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/qq_46126537/article/details/113823034