BZOJ1053 [HAOI2007]反素数ant

时间:2022-07-12 18:37:55

题意

Description

对于任何正整数x,其约数的个数记作g(x)。例如g(1)=1、g(6)=4。如果某个正整数x满足:g(x)>g(i) 0<i<x,则称x为反质数。例如,整数1,2,4,6等都是反质数。现在给定一个数N,你能求出不超过N的最大的反质数么?

Input

一个数N(1<=N<=2,000,000,000)。

Output

不超过N的最大的反质数。

Sample Input

1000

Sample Output

840

分析

根据定义,反素数是1~N中约数最多的数中最小的一个。并且一定是连续的质因数,指数递减,可以用微扰法证明。因为\(10^9\)以内的数的质因数个数不会超过10个,指数和不会超过30,所以考虑搜索。在种种限制条件下,搜索量非常小。

代码

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
    rg T data=0,w=1;
    rg char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
        data=data*10+ch-'0',ch=getchar();
    return data*w;
}
template<class T>il T read(rg T&x){
    return x=read<T>();
}
typedef long long ll;
co ll INF=0x7fffffff;
ll n,p[11]={0,2,3,5,7,11,13,17,19,23,29},c[11]={INF};
ll ans=INF,cnt=1;
void dfs(ll now,ll num,ll cnt0){
    if(now==11){
        if(cnt0>cnt||(cnt0==cnt&&ans>num))
            cnt=cnt0,ans=num;
        return;
    }
    for(int i=0;i<=c[now-1];++i){
        if(num>n) return;
        c[now]=i;
        dfs(now+1,num,cnt0*(i+1));
        num*=p[now];
    }
}
int main(){
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    read(n);
    dfs(1,1,1);
    printf("%lld\n",ans);
    return 0;
}