把一个数的约数个数定义为该数的复杂程度,给出一个n,求1-n中复杂程度最高的那个数。
例如:12的约数为:1 2 3 4 6 12,共6个数,所以12的复杂程度是6。如果有多个数复杂度相等,输出最小的。
Input
第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 100) 第2 - T + 1行:T个数,表示需要计算的n。(1 <= n <= 10^18)
Output
共T行,每行2个数用空格分开,第1个数是答案,第2个数是约数的数量。
Input示例
5 1 10 100 1000 10000
Output示例
1 1 6 4 60 12 840 32 7560 64
1 2 3 45 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
1 2 2 32 42 4 4 4 2 62 4 4 5 2 62 6 4 4 2 8
25 26 27
3 4 2
设f(x)为x的复杂度
情况一:f(1) = 1
情况二:f(p) = 2,其中p为质数
情况三:f(x) = ?,其中x为合数
规律?NO!!!
真相 --> 反素数模板题,雪崩。。。
反素数
对于任何正整数x,其约数的个数记做g(x).例如g(1)=1,g(6)=4.如果某个正整数x满足:对于任意i(0<i<x),都有g(i)<g(x),则称x为反素数
性质
性质一:一个反素数的质因子必然是从2开始连续的质数.
性质二:p=2^t1*3^t2*5^t3*7^t4.....必然t1>=t2>=t3>=....
另外
如果一个数分解质因数的形式是:M = x^a * y^b * z^c * ...
则M的约数个数 = (a+1)(b+1)(c+1)
// 一开始的做法,傻逼的我记漏了一个性质 t1>=t2>=t3....,少了个重要剪植,超时了一段时间,不过yy了一个傻逼优化也水过了
#include <stdio.h>
#include <vector>
#include <algorithm>
#define PRIME_NUM 17
typedef long long LL;
LL ans;
int divCntOfAns;
int prime[PRIME_NUM] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59};
void dfs(LL limit, LL curAns, int divCntOfcurAns, int indexOfPrime)
{
// Update ans and the count of ans's divisor
if(divCntOfcurAns > divCntOfAns)
{
ans = curAns;
divCntOfAns = divCntOfcurAns;
}
else if(divCntOfcurAns == divCntOfAns && curAns < ans)
{
ans = curAns;
}
if(curAns <= limit && indexOfPrime < PRIME_NUM)
{
LL tmpcurAns = curAns;
int tmpdivCntOfcurAns = divCntOfcurAns;
int cnt = 0;
while(1)
{
if(static_cast<double>(tmpcurAns) * prime[indexOfPrime] > limit) return;
tmpcurAns *= prime[indexOfPrime];
cnt++;
dfs(limit, tmpcurAns, tmpdivCntOfcurAns * (cnt+1), indexOfPrime + 1);
}
}
}
void MostComplexNumber()
{
int T;
LL n;
std::vector<LL> data, dataBackup;
std::vector<LL> ansPre;
std::vector<int> ansDivCntPre;
scanf("%d", &T);
while(T--)
{
scanf("%lld", &n);
data.push_back(n);
}
dataBackup.assign(data.begin(), data.end());
std::sort(data.begin(), data.end(), std::greater<LL>());
for(auto it = data.begin(); it != data.end(); ++it)
{
if(ansPre.empty() || *ansPre.rbegin() > *it)
{
ans = divCntOfAns = 1;
dfs(*it, 1, 1, 0);
ansPre.push_back(ans);
ansDivCntPre.push_back(divCntOfAns);
}
}
for(auto it = dataBackup.begin(); it != dataBackup.end(); ++it)
{
int i = 0;
while(ansPre[i] > *it) i++;
printf("%lld %d\n", ansPre[i], ansDivCntPre[i]);
}
}
int main()
{
MostComplexNumber();
return 0;
}
// 正常做法
#include <stdio.h>
#define PRIME_NUM 17
typedef long long LL;
LL ans;
int divCntOfAns;
int prime[PRIME_NUM] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59};
void dfs(LL limit, LL curAns, int divCntOfcurAns, int preCnt, int indexOfPrime)
{
// Update ans and the count of ans's divisor
if(divCntOfcurAns > divCntOfAns)
{
ans = curAns;
divCntOfAns = divCntOfcurAns;
}
else if(divCntOfcurAns == divCntOfAns && curAns < ans)
{
ans = curAns;
}
if(curAns <= limit && indexOfPrime < PRIME_NUM)
{
LL tmpcurAns = curAns;
int tmpdivCntOfcurAns = divCntOfcurAns;
int cnt = 0;
while(1)
{
double preTmpcurAns = tmpcurAns;
preTmpcurAns *= prime[indexOfPrime];
if(preTmpcurAns > limit || cnt > preCnt) return;
tmpcurAns = tmpcurAns * prime[indexOfPrime];
cnt++;
dfs(limit, tmpcurAns, tmpdivCntOfcurAns * (cnt+1), cnt, indexOfPrime + 1);
}
}
}
void MostComplexNumber()
{
int T;
LL n;
scanf("%d", &T);
while(T--)
{
scanf("%lld", &n);
ans = divCntOfAns = 1;
dfs(n, 1, 1, 0xfffffff, 0);
printf("%lld %d\n", ans, divCntOfAns);
}
}
int main()
{
MostComplexNumber();
return 0;
}