约数——反素数

时间秒杀一切 提交于 2020-02-10 15:13:22

反素数

对于任何正整数x,其约数的个数记作g(x),例如g(1)=1、g(6)=4。

如果某个正整数x满足:对于任意的小于x的正整数 i,都有g(x)>g(i) ,则称x为反素数。

例如,整数1,2,4,6等都是反素数。

现在给定一个数N,请求出不超过N的最大的反素数。

输入格式
一个正整数N。

输出格式
一个整数,表示不超过N的最大反素数。

数据范围
1N21091≤N≤2∗10^9
输入样例:
1000
输出样例:
840

题解:

我们推的反素数其实一个1-n中含有最多约数,并且这个数最小的数字。
假设这个数为x,我们画一个数轴来看,因为要任意的小于x的正整数 i,所以x点右边的数不考虑。再看左边的数,约数个数都是小于等于f(x)但是都是小于x的。
这里有几个性质:
1,21092*10^9中约数个数最多的数一共有1600个约数。
2,230>21092^{30}>2*10^9
3,利用中国四大定理可以知道。我们分解质因子再看看题目范围最多用到9个质因子就会超过范围了。
4,我们分解质因子的时候我们的因子指数是递减的。
所以综上,我们可以使用爆搜来处理问题。

#include <bits/stdc++.h>
using namespace std;
int primes[9] = {2, 3, 5, 7, 11, 13, 17, 19, 23};
int maxd,maxval;
long long n;
void dfs(int u,int ci,long long p,int d)
{
    if((d>maxd)||(d==maxd&&maxval>p)){
        maxd=d;
        maxval=p;
    }
    if(u==9) return;
    for(int i=1;i<=ci;i++){
        if(1LL*primes[u]*p>n) break;
        p=p*primes[u];
        dfs(u+1,i,p,d*(i+1));
    }
}
int main()
{
    cin>>n;
    dfs(0,30,1,1);
    cout<<maxval<<endl;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!