[HAOI 2007]反素数ant

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

题解

拿到题首先准确无误地题干看错,以为是质因数个数...

这道题其实还是很好做的。首先我们要知道一个定理:

对任一整数$a>1$,有$a={p_1}^{a_1}{p_2}^{a_2}…{p_n}^{a_n}$,其中$p_1<p_2<…<p_n$均为素数,而$a_1$,$a_2$…,$a_n$是正整数。

$a$的正约数个数为:$(1+a_1)(1+a_2)…(1+a_n)$

我们很容易得到一个结论:由于这道题实际上是$1~n$因数最多的数中最小的。

从反素数的定义中可以看出两个性质:

(1)一个反素数的所有质因子必然是从$2$开始的连续若干个质数,因为反素数是保证约数个数为的这个数尽量小

(2)同样的道理,如果,那么必有

我们发现:

$2×3×5×7×11×13×17×19×23×29$

$=6,469,693,230>2,000,000,000$

显然只要用这十个数进行讨论就好了。

我们发现之前那个式子中$p$是不好讨论的,那么我们就用搜索实现了。

如果还是不太理解->戳我<-

 1 #include<map>
 2 #include<set>
 3 #include<ctime>
 4 #include<cmath>
 5 #include<queue>
 6 #include<stack>
 7 #include<cstdio>
 8 #include<string>
 9 #include<vector>
10 #include<cstdlib>
11 #include<cstring>
12 #include<iostream>
13 #include<algorithm>
14 #define LL long long
15 #define RE register
16 #define IL inline
17 using namespace std;
18 const LL prime[10]={2,3,5,7,11,13,17,19,23,29};
19 
20 LL n,ans,maxn;
21 
22 void Dfs(LL pn,LL cnt,LL cen);
23 
24 int main()
25 {
26     scanf("%lld",&n);
27     Dfs(1,1,0);
28     printf("%lld\n",ans);
29     return 0;
30 }
31 
32 void Dfs(LL pn,LL cnt,LL cen)
33 {
34     if (pn>maxn) maxn=pn,ans=cnt;
35     if (pn==maxn&&cnt<ans) ans=cnt;
36     if (cen==10) return;
37     LL a=1;
38     for (RE LL i=0;;i++)
39     {
40         if (cnt*a>n) break;
41         Dfs(pn*(i+1),cnt*a,cen+1);
42         a*=prime[cen];
43     }
44 }
posted @ 2017-08-05 17:24  NaVi_Awson  阅读(377)  评论(0编辑  收藏  举报