【BZOJ 1053】反素数

题目描述

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

如果某个正整数 x 满足:对于任意的 0 < i < x ,都有 g ( x ) > g ( i ) ,则称 x 为反质数。例如,整数 1 , 2 , 4 , 6 等都是反质数。

现在给定一个数 N ( 1 N 2 × 10 9 ) ,请求出不超过 N 的最大的反质数。

算法分析

一些结论:

  • 1 N 2 × 10 9 时, N 最多有 10 个不同的质因子,且所有质因子的指数不超过 30 。(证明:找极大情况)
  • 不超过 N 的最大的反质数就是最靠前的约数个数最多的数。(显然,可分类讨论)
  • 该数是反质数当且仅当其质因子是连续若干个最小的质数,并且质数单调递减。(反证法:交换质因子指数)

暴力搜索即可。

代码实现

#include <cstdio>
#include <algorithm>
const int arr[]={2,3,5,7,11,13,17,19,23,29,31};
int n;long long int ans=0,ansnum=0,now=1,cnt=1;
inline int pow(int n,int k) {
    int ans=1;
    while(k) {
        if(k&1) ans*=n;
        n*=n;k>>=1;
    }
    return ans;
}
void search(int idx,int up) {
    if(idx>10) {
        if(cnt>ans) {
            ans=cnt;
            ansnum=now;
        }
        else if(cnt==ans) ansnum=std::min(ansnum,now);
        return;
    }
    search(idx+1,0);
    for(int i=1;i<=up;++i) {
        int power=pow(arr[idx],i);
        if((long long int)now*power>n) break;
        now*=power;cnt*=i+1;
        search(idx+1,i);
        now/=power;cnt/=i+1;
    }
}
int main() {
    scanf("%d",&n);
    search(0,30);
    printf("%lld\n",ansnum);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/WHZ2018/article/details/81252459
今日推荐