题目大意

对于任何正整数x,其约数的个数记作g(x)。如果某个正整数x满足对任意的0<i<x,都有g(x)>g(i)
,则称x为反质数。现在给定一个数N,求出不超过N的最大的反质数。(N<=2*1e9)

总体思路

性质1

不超过N的最大的反质数x为不超过N的约数个数最多的数字中最小的数字(最小的数字保证了不存在一个比x小的数y使得g(x)==g(y))。

直接爆搜寻找x会超时,我们要想办法缩小数据范围。

定理(性质2的基础)

任何一个合数都会分解为若干个质数的整数幂的乘积所表示。

所有因数的个数为所有质数幂的次数加一的乘积。(证明:因数也是由质数的乘积所组成的,所以把质数的幂拆解成一个个质数,因数的个数就是那若干个质数的组合。因为一种质数如果次数为0也是一种情况,所以要加1)。

性质2

若x是约数最多的数字中最小的数字,则一个必要条件是用于表示它的若干个质数的整数幂的次数随质数大小的增加而递减(否则,如果存在质数p1<p2,其次数a1<a2,那么把a1,a2交换,因数的个数没变,但所得的积变小了,这与x是约数最多的数字中 最小的 数字相矛盾)。

因此,我们用Dfs枚举满足性质2的质数的整数幂的次数的排列方式,在所有的排列方式中选取最优值即可。因为有了一个必要条件,搜索的范围减小了,这可以使时间效率提高。

那么到底枚举多少个质数呢?

性质3.1

N<=2*1e9时,枚举的质数不超过10个。(因为前十一个质数的乘积已经超过2*1e9了)

质数的选择式连续的,证明与性质2相似。

性质3.2

每个质数幂的次数不超过31(2^31已经超过整数的范围了)。

深度搜索

所有的深度搜索都是在隐式图上进行的。每个结点有它的【值】,每个结点有它所连着的【边】。

  • 本题中【边】是下一个质数的【幂次】的可能选项,其边权为 ak【下一个质数】^【幂次】,
  • 节点的【值】是多元组:①当前处理的【数值】(所有质数幂的次数加一的乘积),②当前的【约数的个数】,③当前节点的深度(对应全局【质数数组】的下标),④每个节点根据性质2对边有一个限制,作为【剪枝】。
  • 【边】和【节点】的关系为:乘积。

对于【隐式图】而言,节点的构成是通过DFS各个参数来传递和表示的。

非常重要的是对【叶子】的判定,因为【解】空间是由【叶子】构成的。可以根据【树深度】,也可以根据【孩子】的数目来判定。

每一个节点的性质应当是它自己的性质,而不是什么别的节点的性质。节点应当有一定的独立性。因此,DFS时,尽量不要出现prev什么什么的字眼。

注意事项

  • 21不是质数。。。
  • DFS初值的timeLimit应当为31,而不是正无穷。否则,枚举的幂的次数就成了2*1e31,就超时了。
  • 凡是带有product(积)字眼的必须是long long,否则会越界。
#include <cstdio>
#include <cstring>
#include <cstdarg>
#include <cstdlib>
using namespace std; int MaxFactorCnt;
int AnsProduct;
long long N;
const int Primes[15] = { 1,2,3,5,7,11,13,17,19,23,29,31 }; void Dfs(int p, int factorCnt, int timeLimit, long long totProduct)
{
if (p == 12)
{
if (factorCnt > MaxFactorCnt)
{
MaxFactorCnt = factorCnt;
AnsProduct = totProduct;
}
else if (factorCnt == MaxFactorCnt && totProduct < AnsProduct)
{
AnsProduct = totProduct;
MaxFactorCnt = factorCnt;
}
return;
}
long long nextPower = 1;
for(int nextTime=0; nextTime<=timeLimit && totProduct*nextPower<=N; nextTime++)
{
Dfs(p + 1, factorCnt * (nextTime + 1), nextTime, totProduct*nextPower);
nextPower *= Primes[p+1];
}
} int main()
{
MaxFactorCnt = 1;
AnsProduct = 1;
scanf("%lld", &N);
Dfs(0, 1, 31, 1);
printf("%d\n", AnsProduct);
return 0;
}

  

BZOJ1053 反素数的更多相关文章

  1. 【BZOJ1053】 反素数ant

    BZOJ1053 反素数ant 我们先考虑唯一分解定理求出约数个数: \(x=a_1^{p_1}a_2^{p_2}a_3^{p_3}...a_k^{p_k}\) 然后\(num=\Pi_{i=1}^k ...

  2. 【bzoj1053】反素数

    [bzoj1053]反素数 题意 对于任何正整数x,其约数的个数记作g(x).例如g(1)=1.g(6)=4.如果某个正整数x满足:g(x)>g(i) 0<i<x,则称x为反质数.例 ...

  3. BZOJ1053 [HAOI2007]反素数ant 数论

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 传送门 - BZOJ1053 题目描述 对于任何正整数x,其约数的个数记作g(x).例如g(1)=1.g(6)=4.如果某个正 ...

  4. 【BZOJ1053】[HAOI2007]反素数(搜索)

    [BZOJ1053][HAOI2007]反素数(搜索) 题面 BZOJ 洛谷 题解 大力猜一下用不了几个质因子,那么随便爆搜一下就好了. #include<iostream> #inclu ...

  5. 【BZOJ1053】[HAOI2007]反素数

    [BZOJ1053][HAOI2007]反素数 题面 bzoj 洛谷 题解 可以从反素数的定义看出小于等于\(x\)的最大反素数一定是约数个数最多且最小的那个 可以枚举所有的质因数来求反素数,但还是跑 ...

  6. 【BZOJ1053】[HAOI2007]反素数ant 暴力

    [BZOJ1053][HAOI2007]反素数ant Description 对于任何正整数x,其约数的个数记作g(x).例如g(1)=1.g(6)=4.如果某个正整数x满足:g(x)>g(i) ...

  7. bzoj1053: [HAOI2007]反素数ant

    51nod有一道类似的题...我至今仍然不会写暴搜!!! #include<cstdio> #include<cstring> #include<iostream> ...

  8. 约数 求反素数bzoj1053 bzoj1257

    //约数 /* 求n的正约数集合:试除法 复杂度:O(sqrt(n)) 原理:扫描[1,sqrt(N)],尝试d能否整除n,若能,则N/d也能 */ ],m=; ;i*i<=n;i++){ ){ ...

  9. BZOJ1053:反素数(数学)

    题目链接 对于任意的正整数\(x\),记其约数的个数为\(g(x)\).现在定义反素数:对于\(0<i<x\),都有\(g(x)>g(i)\),那么就称x为反素数. 现在给定一个数N ...

随机推荐

  1. Elasticsearch之批量操作bulk

    1.bulk相当于数据库里的bash操作. 2.引入批量操作bulk,提高工作效率,你想啊,一批一批添加与一条一条添加,谁快? 3.bulk API可以帮助我们同时执行多个请求 4.bulk的格式: ...

  2. Assembly之instruction之Indirect Autoincrement Mode

    Assembler Code Content of ROMMOV @R10+,0(R11)   MOV @R10+,0(R11) Length: One or two words Operation: ...

  3. 如何安全使用dispatch_sync

    概述 iOS开发者在与线程打交道的方式中,使用最多的应该就是GCD框架了,没有之一.GCD将繁琐的线程抽象为了一个个队列,让开发者极易理解和使用.但其实队列的底层,依然是利用线程实现的,同样会有死锁的 ...

  4. C# 写入二进制文件

    写入整型25 文件在MiniHex中显示 写入字符串I am happy 0A 6D - 6D - 这一行数据是C#把字符串转换为16进制形式 不知道为啥用MiniHex打开多了个0A 写入空&quo ...

  5. Appium Android 获取包名和 Activity 的几种方法 (转)

    本文档主要记录“获取包名和 Activity 的方法”,用于自动化测试时启动APP.以下方法主要来源于网络和社区同学的贡献,特此感谢! 1. 方法一: pm list package查看包名 adb ...

  6. mysql主主同步

    Mysql 主主同步方案 第一台机器主 [root@master ~]# vim /etc/my.cnf [mysqld] server-id=1 log-bin=mysql-binlog log-s ...

  7. PAT_A1152#Google Recruitment

    Source: PAT A1152 Google Recruitment (20 分) Description: In July 2004, Google posted on a giant bill ...

  8. lucene7.1.0实现搜索文件内容

    Lucene的使用主要体现在两个步骤: 1 创建索引,通过IndexWriter对不同的文件进行索引的创建,并将其保存在索引相关文件存储的位置中. 2 通过索引查寻关键字相关文档. 首先,我们需要定义 ...

  9. 获取第n天日期

    function datezh(s){ return s = s>9 ? s:"0"+s } function dateTime(t){ var getNowTime = v ...

  10. 【剑指Offer】5、用两个栈实现队列

      题目描述:   用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型.   解题思路:   本题的基本意图是:用两个后入先出的栈来实现先入先出的队列.对于这个问题,我 ...