素数的定义可以为:因子只有2个的数(一个是1,另一个是本身),也就是因子最少的数。
那么,反素数可以定义成因子数最多的数,假如因子个数相同那么是最小的那个数,反素数是相对于一个集合来说的(比如在n个数以内的数)。
简而言之,因素最多并且值最小的数,就是反素数。
朴素求法:利用整数唯一分解定理若x=pk11pk22…pknn,那么x就有(k1+1)(k2+1)…(kn+1)个因数。给某个集合扫一遍求下max即可。
反素数有两个特点:
- 反素数肯定是从2开始的连续素数的幂次形式的乘积。
- 数值小的素数的幂次大于等于数值大的素数:x=pk11pk22…pknn,那么有k1≥k2≥…kn。
解释:
- 反证,若存在不从2开始的连续素数之积p,那么必然存在一个从2开始的连续素数之积q,除了一个2以外,其他值均与p相等,而此时q<p。
- 若存在ki,kj,使得i<j,ki>kj成立。那么我们可以交换一下pi与pj,使得这个数更小。
想要求给定自然数n,求[1,n]内的反素数。这个问题似乎没有什么更加牛X的解决方法,实际上还是要通过枚举的方法,为了解决这个问题,我们再提出两个问题:
- 对于给定的n,要枚举到哪一个素数:枚举到≤n的素数就可以。
- 枚举多少次幂:实际上枚举到最小素数p的k次幂,使得pk>n,那么枚举到的最大幂次肯定要小于k。
一般这类问题都是DFS+一些分支限界枚举答案的。
练习1:http://codeforces.com/contest/27/problem/E
题意:找含有n个因子的最小的那个数,这个数不超过1E18。
分析:
- 设这个数字是m,那么可以设m=pk11pk22…pkrr,其中(k1+1)(k2+1)…(kr+1)=n。我们由上述结论1可以求出来pi的上界:取k1=2,那么最多也就是⌈log21000⌉=10个不同的素数,贪心取最小的前10个素数就可以。
分析到这里就可以打表了。 - 再考虑这个数在1E18内的问题,也就是k的取值范围。取最小的p=2,那么顶多是60层。
于是我们就可以DFS,在每层(即每个素数)暴力枚举这个数选取次数,然后维护上一层的数值以及因数个数就行了。
1 |
|
v1.5.2