More Divisors----反素数

题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1562

题解:g(x)表示x的因子个数。

如果满足对于任意的0<i<x,有g(i)<g(x),则称x为反素数。

它有如下性质:

1、一个反素数的质因子一定是从2开始的连续的质数。

2、一个反素数可以唯一表示成2^a*3^b*5^c······的形式,并且a>=b>=c>=d······

证明:(仅供参考)

先证明性质2:
因为每个整数都有唯一的因式分解,所以表示唯一。

设某个整数Y的因式分解中有t1 个2,t2个3,t3个5······

则Y的因子数为sum=(t1+1)*(t2+1)*(t3+1)······

而Y=2^t1*3^t2*5^t3······

因为要使sum最大,则需要增大t1,t2,t3······的值,而对于2的指数t1,增大的速度最大,所以a最大,其次是b,c。

有了性质2,因为a>=b>=c>=d的。所以中间不会出现0的情况。所以连续。


求n以内的数,该数的因子数最多。

就是要求n以内的最大反素数x。

证明:

在x以内,g(x)最大,在大于x小于n之间不存在因子数大于g(x)的数。

假设存在p,使g(p)>g(x),则p就是n以内的最大反素数,与x使最大反素数矛盾,顾不存在p。

n的最大值是10^16.

则最多用到14个素数来表示n。(2 3 5 7 11 13 17 19 23 29 31 37 41 43)

源代码:

#include <stdio.h>

typedef long long ll;
int prime[14]={2,3,5,7,11,13,17,19,23,29,31,37,41,43};
ll max,best;
ll n;

void getAnti_prime(ll num,int k,ll sum,int limit)
{
    ll temp;
    if(sum>max)
    {
        max=sum;
        best=num;
    }
    if(sum==max&&best>num)  best=num;
    if(k>=14)  return;
    temp=num;
    for(int i=1;i<=limit;i++)
    {
        if(temp*prime[k]>n)
         break;
         temp=temp*prime[k];
         getAnti_prime(temp,k+1,sum*(i+1),i);
    }
}
int main()
{
    while(scanf("%lld",&n)!=EOF)
    {
        getAnti_prime(1,0,1,50);
        printf("%lld\n",best);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值