数论关于素数与反素数求解的一些技巧

1:求某个数的素因子个数: 这便是用于求素因子个数的公式
那么问题来了,对于已经的数我们怎么求比他小的最大素数呢
我们可以使用素数筛(不懂的同学可以百度一下)
然后用数组维护一下即可。
2:反素数。
首先 什么是反素数呢。
反素数的定义:对于任何正整数x,其约数的个数记做g(x).例如g(1)=1,g(6)=4.如果某个正整数x满足:对于任意i(0小于i小于x),都有g(i)小于g(x),则称x为反素数·
满足反素数有以下条件:
1.因子必须是连续的质因子
2.质因子的次数必须满足后一个比前一个的大
利用这些性质,我们可以很快求出反素数。
解释:
第一条:如果不是从2开始的连续素数,那么如果幂次不变,把素数变成数值更小的素数,那么此时因子个数不变,但是n的数值变小了。交换到从2开始的连续素数的时候n值最小。
第二条:如果数值小的素数的幂次小于数值大的素数的幂,那么如果把这两个素数交换位置(幂次不变),那么所得的n因子数量不变,但是n的值变小,直到符合条件。
由性质可知,我们进行反素数相关运算的方法是从小到大枚举每个质因子(素数)进行DFS
代码如下:

void dfs(ll num,int k,int sum,int limit) {
    //num: 当前枚举到的数 k:枚举到的第k大的质因子 sum:该数的约数个数 limit:质因子个数上限(重要剪枝)
    if(sum>maxsum) {     //约数个数更多
        maxsum=sum;
        ans=num;
    }
    if(sum==maxsum&&ans>num) { //约数个数相同,把最优解更新为较小值
        ans=num;
    }
    if(k>16)                     //这里k>x; x至少满足prime[1]*prime[2]*prime[3]*...*prime[x]>x ,当x=16时,数据已超过10^18
        return;                  //当x=10时,数据已超过10^9
    ll temp=num;
    for(int i=1; i<=limit; i++) { //枚举每个质因子的个数
        if(n/prime[k]<temp)    //n为上限,用除法防止溢出
            return;
        temp*=prime[k];
        dfs(temp,k+1,sum*(i+1),i);  //把limit置为i的原因见性质第二条
    }
}
感谢观看!
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值