[HAOI2007]反素数

嘟嘟嘟

 

做这道题得自己推出这么几个结论……

 

1.最大的反素数一定是约数个数最多的的数中最小的那个。

  这个其实很好想:根据定义,$g(x)$要大于任意的$g(i)$,而不是大于等于。

2.1~n中任意一个数的不同的质因子不会超过10个,且所有质因子的指数之和不会大于30.

  最小的10个质数的乘积刚好大于$2^{31}$了,而$2^{31} > 2 * 10^9$。

3.把$x$分解质因数:$x = 2^{a_1} * 3^{a_2} * 5^{a_3} * 7^{a_4} * …… * 29^{a_{10}}$,一定满足$a_1 \leqslant a_2 \leqslant a_3 \leqslant …… \leqslant a_{10}$.

  证明用反证法。假设$x$中有一项$p_k(p > 29)$,那么根据第二条结论,前10个质数中一定有一个$p'$不能整除$x$,那么我们应该用$p'$代替$p$,因为这即保证了约数相等,新的数又更小。

  而之所以递减,是因为如果$x$有相邻的两项$p_i ^ {a_i}, p_j ^ {a_j}(p_i < p_j, a_i > a_j)$,那么完全可以构造出另一个数$x'$,其中两项为$p_i ^ {a_j}, p_j ^{a_i}$,根据算数基本定理,$x$和$x'$约数个数相等,但是$x'$更小,所以应该选$x'$。

知道这几条结论后,一波爆搜就行了。

 (爆搜我写的特别丑,是在不行了再看我的吧)

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<cctype>
 8 #include<stack>
 9 #include<queue>
10 #include<vector>
11 using namespace std;
12 #define enter puts("")
13 #define space putchar(' ')
14 #define Mem(a, x) memset(a, x, sizeof(a))
15 #define rg register
16 typedef long long ll;
17 typedef double db;
18 const int INF = 0x3f3f3f3f;
19 const db eps = 1e-8;
20 //const int maxn = ;
21 inline ll read()
22 {
23   ll ans = 0;
24   char ch = getchar(), las = ' ';
25   while(!isdigit(ch)) las = ch, ch = getchar();
26   while(isdigit(ch)) ans = ans * 10 + ch - '0', ch = getchar();
27   if(las == '-') ans = -ans;
28   return ans;
29 }
30 inline void write(ll x)
31 {
32   if(x < 0) putchar('-'), x = -x;
33   if(x >= 10) write(x / 10);
34   putchar(x % 10 + '0');
35 }
36 
37 ll n;
38 const int a[] = {0, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29}; //num = 10
39 ll ans1 = 0, ans = (ll)INF * (ll)INF;
40 
41 void dfs(ll now, int id, int sum, int Max, int tot, ll x)
42 {
43   if(!tot || now > n || id > 11) return;
44   if(x > ans1 ||(x == ans1 && now < ans)) ans1 = x, ans = now;
45   ll tp = 1;
46   for(int i = 1; i <= min(tot, Max); ++i)
47     {
48       tp *= a[id];
49       if(tp > n) break;
50       dfs(now * tp, id + 1, sum + i, i, tot - i, x * (i + 1));
51     }
52 }
53 
54 int main()
55 {
56   n = read();
57   dfs(1, 1, 0, INF, 30, 1);
58   write(ans);  
59   return 0;
60 }
View Code

 

posted @ 2018-10-08 20:31  mrclr  阅读(132)  评论(0编辑  收藏  举报