0
点赞
收藏
分享

微信扫一扫

聪明的燕姿

钵仔糕的波波仔 2022-04-02 阅读 48
算法

AcWing 1296. 聪明的燕姿

聪明的燕姿

在这里插入图片描述
思路:
在这里插入图片描述
1.假设这个时候有一个约数和S满足(1+2)(1+2+22)(1+2+22++2k)(1+2)(1+2+2^2)(1+2+2^2+…+2^k),359173365129=6350379753*5*9*17*33*65*129 = 635037975 就已经接近1e9的量级了,大概满足条件的不会超过9或者10个质数,可见符合条件的项不会很多那么这个时候我们就可以用dfs进行搜索。
2.考虑dfs遍历顺序:第一层遍历质数P,第二层遍历指数C,如果当前的pk0+pk1+...+pkcpk^0 + pk^1 + ... + pk^c和s取模为0则进去下一层循环
3.题目的s为2e9范围内的质数有slogs=210930\frac{s}{logs} = \frac{2*10^9}{30} ,有六七千万的质数,需要考虑如何剪枝:特殊情况如果S=1+Pk)S = (1 + P_{k}) 则直接输出即可导致会出现两种情况:
1.S=(1+Pk)(1+Pk+Pk2.....)S = (1+P_{k})(1+P_{k}+P_{k}^2.....)
2.S=(1+Pk+Pk2)(1+.....)S = (1+P_{k}+P_{k}^2)(1+.....)
可以看出Pk2<=SP_{k}^2 <= S
所以dfs枚举的PkP_{k}即为S\sqrt{S}的范围内
4.dfs过程中由于我们枚举的质数是单调递增的,所以除后当前的s - 1必须大于上一层质数

样例输入:

42

样例输出:

3
20 26 41

代码:

//import
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;

typedef long long LL;
const int N = 1e5;
int n;
int primes[N], cnt;
bool st[N];
int ans[N], len;

//筛质数
void init()
{
    for(int i = 2; i <= N; i ++ )
    {
        if(!st[i]) primes[cnt ++] = i;
        
        for(int j = 0; primes[j] <= N / i; j ++ )
        {
            st[i * primes[j]] = true;
            if(i % primes[j] == 0) break;
        }
    }
}
//判断是否是质数
bool is_prime(int x)
{
    if (x < N) return !st[x];
    for (int i = 0; primes[i] <= x / primes[i]; i ++ )
        if (x % primes[i] == 0)
            return false;
    return true;
}

void dfs(int s, int idx, int pro)
{
    if(s == 1)
    {
        ans[len ++] = pro;
        return;
    }
    //对s - 1进行特判  并且当前的s - 1 大于上一层的质数
    if(s - 1 > (idx < 0 ? 1 : primes[idx]) && is_prime(s - 1))
        ans[len ++] = pro * (s - 1);
    
    
    for(int i = idx + 1; primes[i] <= s / primes[i]; i ++ )
    {
        int p = primes[i];
        for(int j = 1 + p, t = p; j <= s; t *= p, j += t) // tip
            if(s % j == 0)
                dfs(s / j, i, pro * t);
    }
}

int main()
{
    init();
    while (cin >> n)
    {
        len = 0;
        dfs(n, -1, 1);

        cout << len << endl;
        if (len)
        {
            sort(ans, ans + len);
            for (int i = 0; i < len; i ++ ) cout << ans[i] << ' ';
            cout << endl;
        }
    }
    return 0;
}

 

举报

相关推荐

0 条评论