提到反素数,大家可能比较陌生,这里博主我对反素数的了解也不是很深刻,希望能借此机会来总结一下并和大家交流
概念
对于任何正整数n,其约数个数为f(n),如果某个正整数n满足:对任意正整数i(0
性质
性质1、一个反素数的所有质因子必然是从2开始的连续若干个质数,因为反素数是保证约数个数为x的这个数n尽量小
性质2、如果n=2^t1*3^t2*5^t3*…,那么必有t1>t2>t3…
应用
1.给出一个数n,求一个最小的正整数x,使得x的约数个数为n
2.求出1~n中约数最多的这个数(构建搜索树,每层为素因子的i次幂,其中0<=i<=63,一般取63,因为2^64为long long上限,每层碰到所剩数字/该层代表素因子小于上层质因子时不再拓展本枝)
反素数表
int a[42] = {1,2,4,6,12,24,36,48,60,120,180,240,360,720,840,1260,1680,2520,5040,7560,10080,15120,20160,25200,27720,45360,50400,55440,83160,110880,166320,221760,277200,332640,498960,554400,665280,720720,1081080,1441440,2162160};
int b[42] = {1,2,3,4,6,8,9,10,12,16,18,20,24,30,32,36,40,48,60,64,72,80,84,90,96,100,108,120,128,144,160,168,180,192,200,216,224,240,256,288,320};
应用示例
求一个最小正整数,使得它的因子个数为n
typedef unsigned long long ULL;
const ULL INF = ~0ULL;
int p[16] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};
int n;
ULL ans;
void dfs(int dept,ULL tmp,int num){
if(num > n) return;
if(num == n && ans > tmp) ans = tmp;
for(int i=1;i<=63;i++){
if(ans / p[dept] < tmp) break;
dfs(dept+1,tmp *= p[dept],num*(i+1));
}
}
int main(){
while(cin>>n){
ans = INF;
dfs(0,1,1);
cout<<ans<<endl;
}
return 0;
}
求n以内的因子数最多的数
typedef unsigned long long ULL;
const ULL INF = ~0ULL;
int p[16] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};
ULL ans,n;
int best;
void dfs(int dept,ULL tmp,int num){
//到叶子结点,返回
if(dept >= 16) return;
//num记录的因子个数,如果遇到更小的,就更新
if(num > best){
best = num;
ans = tmp;
}
//当因子个数相同时,取值最小的
if(num == best && ans > tmp) ans = tmp;
for(int i=1;i<=63;i++){
if(n / p[dept] < tmp) break;
dfs(dept+1,tmp *= p[dept],num*(i+1));
}
}
int main(){
while(cin>>n){
ans = INF;
best = 0;
dfs(0,1,1);
cout<<ans<<endl;
}
return 0;
}
超大数据(10^80)找n以内的约数最多的数并输出因子个数(java实现)
package main;
import java.io.*;
import java.math.*;
import java.util.*;
class Node {
private static final int MAXP = 60;
public BigInteger K;
public long F;
public int N;
public int[] A;
public Node() {
K = BigInteger.ZERO;
A = new int[MAXP];
}
}
public class Main{
private static final int MAXIP = 250;
private static final int MAXP = 60;
private static BigInteger[] prime;
private static void init() {
boolean[] isPrime = new boolean[MAXIP];
for(int i=0;i<MAXIP;++i){
isPrime[i] = true;
}
isPrime[0] = isPrime[1] = false;
for(int i=4;i<MAXIP;i+=2) {
isPrime[i] = false;
}
for(int i=3;i<MAXIP;i+=2) {
for(int j=3;i*j<MAXIP;j+=2) {
isPrime[i*j] = false;
}
}
prime = new BigInteger[MAXP];
for(int i=0, j=0;i<MAXIP;++i) {
if(isPrime[i]) {
prime[j++] = BigInteger.valueOf(i);
}
}
}
public static void main(String args[]) {
init();
List<BigInteger> P = new ArrayList<BigInteger>();
BigInteger MP = BigInteger.ZERO;
List<Node> ans = new ArrayList<Node>();
Scanner cin = new Scanner(new BufferedInputStream(System.in));
//Integer cas = new Integer(3);
while(cin.hasNext()) //cas>0{
BigInteger temp = cin.nextBigInteger();
P.add(temp);
if(temp.compareTo(MP) == 1) {
MP = temp;
}
ans.add(new Node());
//cas--;
}
Map<Long, BigInteger> map = new HashMap<Long, BigInteger>();
Queue<Node> queue = new LinkedList<Node>();
Node origin = new Node();
origin.K = BigInteger.ONE;
origin.F = 1;
origin.N = 0;
queue.add(origin);
map.put(origin.F, origin.K);
while(!queue.isEmpty()) {
Node u = queue.peek();
queue.remove();
BigInteger compare = map.get(u.F);
if(compare != null) {
if(compare.compareTo(u.K) == -1) {
continue;
}
}
for(int i=0;i<P.size();++i) {
if(u.K.compareTo(P.get(i)) <= 0) {
if(u.F > ans.get(i).F) {
ans.get(i).F = u.F;
ans.get(i).K = u.K;
}
else if(u.F == ans.get(i).F) {
if(u.K.compareTo(ans.get(i).K) == -1) {
ans.get(i).K = u.K;
}
}
}
}
for(int i=0;i<u.N;++i) {
Node v = new Node();
v.K = u.K.multiply(prime[i]);
if(v.K.compareTo(MP) <= 0) {
v.F = u.F / (u.A[i] + 1) * (u.A[i] + 2);
v.N = u.N;
for(int j=0;j<u.N;++j) {
v.A[j] = u.A[j];
}
++ v.A[i];
boolean flag = true;
compare = map.get(v.F);
if(compare != null) {
if(compare.compareTo(v.K) <= 0) {
flag = false;
}
else {
map.remove(v.F);
}
}
if(flag) {
queue.add(v);
map.put(v.F, v.K);
}
}
}
Node v = new Node();
v.K = u.K.multiply(prime[u.N]);
if(v.K.compareTo(MP) <= 0) {
v.F = u.F * 2;
v.N = u.N + 1;
for(int i=0;i<u.N;++i) {
v.A[i] = u.A[i];
}
++ v.A[u.N];
boolean flag = true;
compare = map.get(v.F);
if(compare != null) {
if(compare.compareTo(v.K) <= 0) {
flag = false;
}
else {
map.remove(v.F);
}
}
if(flag) {
queue.add(v);
map.put(v.F, v.K);
}
}
}
for(int i=0;i<ans.size();++i) {
System.out.println(ans.get(i).K.toString() + " " + ans.get(i).F);
}
}
}