题目大意

对于任何正整数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. mysql数据库的介绍及安装

    一.什么是数据库 1.什么是数据(Data) 描述事物的符号记录成为数据,描述事物的符号既可以是文字.图片.图像.声音.语言等,数据有多种表现形式,他们都可以经过数字化后存入计算机 在计算机中描述一个 ...

  2. 自学Python四 爬虫基础知识储备

    首先,推荐两个关于python爬虫不错的博客:Python爬虫入门教程专栏   和 Python爬虫学习系列教程 .写的都非常不错,我学习到了很多东西!在此,我就我看到的学到的进行总结一下! 爬虫就是 ...

  3. Nmap linux端口扫描神器

    #简介 Nmap亦称为Network Mapper(网络映射)是一个开源并且通用的用于Linux系统/网络管理员的工具.nmap用于探查网络.执行安全扫描.网络核查并且在远程机器上找出开放端口.它可以 ...

  4. Java冒泡,快速,插入,选择排序^_^+二分算法查找

    这段时间在学Java,期间学到了一些排序和查找方法.特此写来和大家交流,也方便自己的日后查看与复习. 1.下边是Java的主类: public class Get { public static vo ...

  5. 【Linux】Vi中的各种命令

    Ctrl+u:向文件首翻半屏: Ctrl+d:向文件尾翻半屏: Ctrl+f:向文件尾翻一屏: Ctrl+b:向文件首翻一屏: Esc:从编辑模式切换到命令模式: ZZ:命令模式下保存当前文件所做的修 ...

  6. SAP computer之program counter

    Program counter The program is stored in memory with the first instruction at binary address 0000, t ...

  7. Linux之tar.gz file

    A tarball (tar.gz file) is compressed tar archive. The tar program provides the ability to create ta ...

  8. std::string格式化输入输出

    在C语言中: C函数有sprintf函数, 比较方便, 但是需要知道所需要的内存空间是多少. 在C++的框架MFC中: 在MFC中CString 有Format函数来格式化字符串. 很方便. 难过的是 ...

  9. scala类型系统:24) 理解 higher-kinded-type

    首先我们从最基本的泛型来看: 现在我们对上面泛型中的类型参数再进一步,也是个泛型会如何呢? 可以看到,java中不支持类型参数也是泛型类型的情况,而scala支持.这是一个很重要的区别,scala在类 ...

  10. 函数式编程-将Monad(单子)融入Swift

    前言 近期又开始折腾起Haskell,掉进这个深坑恐怕很难再爬上来了.在不断深入了解Haskell的各种概念以及使用它们去解决实际问题的时候,我会试想着将这些概念移植到Swift中.函数式编程范式的很 ...