题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1053
题解:
可以证明,$1 sim N$ 中最大的反质数,就是 $1 sim N$ 中约数个数最多的数中,最小的那个。
证明:假设 $1 sim N$ 中最大的反质数 $x$ 不是 $1 sim N$ 中约数个数最多的,那么必然存在至少一个不等于 $x$ 的数字 $y$,它是 $1 sim N$ 中约数个数最多的数中最小的,显然有 $g(y) > g(x)$。
那么,分类讨论两种情况:
1、$x < y$,显然 $[1,y)$ 中不可能找到一个 $i$ 使得 $g(y) le g(i)$,因此 $g(y)$ 是一个反质数,且 $x < y$,$y$ 优于 $x$,不可能选 $x$ 作为答案。
2、$y > x$,此时 $g(y) > g(x)$,$x$ 不是一个反质数,不应当选择 $x$ 作为答案。
因此,不管怎么样,都不可能选择 $x$ 作为答案,因此只能选择 $1 sim N$ 中约数个数最多的数作为答案,又显然的,应当选这些数字中最小的那一个。
证毕。
然后,我们可以进一步考虑,在给出的 $N le 2e9$ 的前提下,$1 sim N$ 中的任何数,其不相同质因子的个数不会超过 $10$ 个,因为 $2 imes 3 imes 5 imes 7 imes 11 imes 13 imes 17 imes 19 imes 23 imes 29 = 6469693230 > 2e9$。
同时,$1 sim N$ 中的任何数,其任意一个质因子的幂次都不会超过 $30$,因为 $2^{31} > 2e9$。
最后,还可以证明 $x$ 如果是一个反质数,那么必然可以分解质因数成 $2^{c_1} imes 3^{c_2} imes 5^{c_3} imes 7^{c_4} imes 11^{c_5} imes 13^{c_6} imes 17^{c_7} imes 19^{c_8} imes 23^{c_9} imes 29^{c_{10}}$,且满足 $c_1 ge c_2 ge cdots ge c_{10} ge 0$。
这个是因为,假设 $x$ 有一个质因子 $p>29$,那么 $2 sim 29$ 这 $10$ 个质数必然至少有一个不能整除 $x$ 了,假设这个质数是 $q$,那么显然如果将 $p^k$ 换成 $q^k$,$x$ 就会变小,而且约数个数不变,也即存在一个 $x'<x$ 且 $g(x') = g(x)$,那么 $x$ 就不是反质数,证毕。
综上,我们可以暴力搜索 $2^{c_1} imes 3^{c_2} imes 5^{c_3} imes 7^{c_4} imes 11^{c_5} imes 13^{c_6} imes 17^{c_7} imes 19^{c_8} imes 23^{c_9} imes 29^{c_{10}}$ 中的 $c_1 sim c_{10}$。我们可以通过 $c_1 sim c_{10}$ 算出对应的约数个数,我们只需要维护约数个数最多的最小数即可。
AC代码(1A很舒服):
/************************************************************** Problem: 1053 User: Dilthey Language: C++ Result: Accepted Time:24 ms Memory:1288 kb ****************************************************************/ #include<bits/stdc++.h> #define fi first #define se second #define mk(a,b) make_pair(a,b) using namespace std; typedef long long ll; ll n; int p[10]={2,3,5,7,11,13,17,19,23,29}, c[10]; pair<ll,int> ans; void dfs(int pos,int limit,ll num,int cnt) { if(pos>=10) { if(cnt>ans.se) ans=mk(num,cnt); if(cnt==ans.se && num<ans.fi) ans=mk(num,cnt); return; } for(ll i=0,now=1;i<=limit;i++,now*=p[pos]) { if(num*now>n) break; dfs(pos+1,i,num*now,cnt*(i+1)); } } int main() { cin>>n; ans=mk((ll)(2e9+50),0); dfs(0,30,1LL,1); cout<<ans.fi<<endl; }