[HAOI2007]反素数

本文探讨了一种高效算法,用于找出特定范围内拥有最多约数的最小整数,即所谓的“最大反素数”。文章详细阐述了算法背后的数学原理,包括关于质因数分解的重要结论,以及如何通过深度搜索策略确定目标数值。

嘟嘟嘟

 

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

 

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

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

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

  最小的10个质数的乘积刚好大于231了,而231 > 2 * 109

3.把x分解质因数:x = 2a1 * 3a2 * 5a3 * 7a4 * …… * 29a10,一定满足a1 >= a2 >= a3 >= …… >= a10.

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

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

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

 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

 

转载于:https://www.cnblogs.com/mrclr/p/9756947.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值