timus 1748 The Most Complex Number zoj 2562 More Divisors

本文深入分析了大数分解的过程,并利用反素数的特性优化分解算法,通过实例展示如何高效地找到大于10^16的数的质因数分解,涉及C语言编程实现。

 

/*
* timus1748.c
*
* Created on: 2011-10-6
* Author: bjfuwangzhu
*/
/*
这里面我们有一个prime【16】的数组,为什么只要这几个素数呢,因为这几个素数的乘积大于10^16,
而且就反素数的性质来说
比如2^t1*3^t2*5^t3*...p1^x***p2^y,假设p1是大于prime[]中所有的素数的,
因为这几个素数的乘积大于10^16,如果
我们添加p1在这个连乘积式子里面,那么必然有至少一个prime[i]不在这个连乘积式子里面,
但是对于因子的总数目而言
我们在乎的是幂的大小,而非素因子的大小,也就是说如果素因子越大,反而会使因子的数目偏小。
这里引进反素数知识:
反素数第一点:g(x)表示 x含有因子的数目,设 0<i<=x 则g(i)<=x;
反素数第二个特性:2^t1*3^t2^5^t3*7^t4..... 这里有 t1>=t2>=t3>=t4...
证明:如果ti<tj,其中i<j,由于pi小于pj,那么pi^tj*pj^ti<pi^ti*pj^tj,这样就出现了
因子数目相同,但x更小的情况,与反素数的定义矛盾。
*/

#include<stdio.h>
#define LLU unsigned long long
#define pnum 17
int prime[pnum] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53,
59 };
LLU n, nmin;
int nmax;
void dfs(int pstart, int limit, LLU now, int nnum) {
int i;
LLU p = prime[pstart];
double nnow;
if (now > n) {
return;
}
if (nnum > nmax) {
nmin = now;
nmax = nnum;
}
if (nnum == nmax && now < nmin) {
nmin = now;
}
for (i = 1; i <= limit; p *= prime[pstart], i++) {
nnow = (double) now;
if (nnow * p > n) {
break;
} else {
dfs(pstart + 1, i, now * p, nnum * (i + 1));
}
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
#endif
int t;
while (~scanf("%d", &t)) {
while (t--) {
scanf("%llu", &n);
nmin = 1, nmax = 1;
dfs(0, 60, 1, 1);
printf("%llu %d\n", nmin, nmax);
}
}
return 0;
}

转载于:https://www.cnblogs.com/xiaoxian1369/archive/2011/10/06/2199896.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值