原题链接:https://www.luogu.org/problemnew/show/P1463
题目大意:在[1,n]的范围内,求一个数,要求所有小于这个数的数因数个数也要小于这个数,n<=2e9
设m=a1^p1*a2^p2……ak^pk
m的约数个数为(p1+1)*(p2+1)……(pk+1)
luogu题解上的dalao们都没给证明,但是其实很好证啊。。。
设num是m的一个因数,可以有0,1...pi个ai算进num中,即有pi+1种选法,因为ai都是质因数,所以互不影响,所以实际因数个数就是个乘法原理。。。
因为2^31>2e9 所以p1+p2+...pk<31
能够证明,符合条件的数字,它的质因数分解一定是由a1开始连续的
即num=a1^p1*a2^p2...ak^pk (p1*p2*p3*...*pk>0)
因为如果不是这样,则必定有一个数,将其中的一个ai换为更小的pi=0的ai,num一定会变小,但是(p1+1)*(p2+1)……(pk+1)却不会变,原数不合要求。
而最多10个质因子的乘积就会超过2e9,所以枚举质因子时只需枚举10个就够了。(不过为了保险,我用了15个)
然后枚举选用的质因子和它们的指数,搜索即可。
#include<cstdio> int pre[20]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47}; long long n,maxn,ans,sum; void dfs(long long p,long long a,int x) { if(p>maxn) { maxn=p; ans=a; } if(p==maxn&&ans>a) ans=a; if(x>15) return; for(int i=1;i<=34;i++) { if(a*pre[x]>n) break; dfs(p*(i+1),a*pre[x],x+1); a*=pre[x]; } } int main() { scanf("%lld",&n); ans=n; dfs(1,1,1); printf("%lld",ans); return 0; }