反素数介绍

以下内容参考自这里

定义

反素数的定义:对于任何正整数n,其约数个数记为 f(n) f ( n ) ,例如 f(6)=4 f ( 6 ) = 4 ,如果某个正整数n满足:对任意的正整数 i(0<i<n) i ( 0 < i < n ) ,都有 f(i)<f(n) f ( i ) < f ( n ) ,那么称n为反素数。

性质

1.一个反素数的所有质因子必然是从2开始的连续若干个质数,因为反素数是保证约数个数为 x x 的这个数n 尽量小。
2.同样的道理,如果 n=2t13t25t37t4... n = 2 t 1 ∗ 3 t 2 ∗ 5 t 3 ∗ 7 t 4 ∗ . . . ,那么必有 t1t2t3t4... t 1 ≥ t 2 ≥ t 3 ≥ t 4 ≥ . . .

常见问题

1.给定一个数n,求一个最小的正整数x,使得x的约数个数为n。
2.求出 1n 1 ∼ n 中约数个数最多的这个数。

算法解析

基于它的性质我们可以建一颗搜索树,找到正解。比如 n=pa11pa22...pakk n = p 1 a 1 ∗ p 2 a 2 ∗ . . . ∗ p k a k ,以每一个 pi p i 为树的一层建立搜索树,深度为k。
12=223 12 = 2 2 ∗ 3 为例进行说明,建树如下:
这里写图片描述
可以看出从根节点到每一个叶子结点这条路径上的所有数字乘起来都是12的约数,所以12有6个约数。

贴一份模板代码。
n的约数

#include <stdio.h>
#include <string.h>
#include <iostream>
#define LL long long
using namespace std ;

LL n,minnum,cnt ;
const int prime[20] = {1,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47} ;

//num:当前枚举到的数,k:枚举到的第k大的质因子;cntt:该数的约数个数;maxxcnt:质因子个数上限;
void dfs(LL num,LL k,LL cntt,int maxxcnt)
{
    if(k >= 16) return  ;

    //如果约数个数更多或者相同,将最优解更新为当前数;
    if(cntt > cnt || (cntt == cnt && num < minnum))
    {
        cnt = cntt ;
        minnum = num ;
    }
    LL temp = num ;
    for(LL i = 1 ; i <= maxxcnt ; i++) //开始枚举每个质因子的个数;
    {
        if(temp > n / prime[k])
            break ;
        temp *= prime[k] ; //累乘到当前数;
        dfs(temp,k+1,cntt*(i+1),i) ;
    }
}
int main()
{
    int T ;
    scanf("%d",&T) ;
    while(T--)
    {
        scanf("%lld",&n) ;
        minnum = cnt = 1 ;
        dfs(1,1,1,50) ;
        printf("%lld\n",cnt) ;
    }
    return 0 ;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值