题意:把一个数的约数个数定义为该数的复杂程度,给出一个n,求1-n中复杂程度最高的那个数。
例如:12的约数为:1 2 3 4 6 12,共6个数,所以12的复杂程度是6。如果有多个数复杂度相等,输出最小的。
n<=1e18
反素数
定义:
对于任何正整数x,其约数的个数记做g(x).例如g(1)=1,g(6)=4.如果某个正整数x满足:对于任意i(0<i<x),都有g(i)<g(x),则称x为反素数·
性质:
性质一:一个反素数的质因子必然是从2开始连续的质数.
例如:12的约数为:1 2 3 4 6 12,共6个数,所以12的复杂程度是6。如果有多个数复杂度相等,输出最小的。
n<=1e18
反素数
定义:
对于任何正整数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>=....
本题就是求<=n中,最大的反素数y.(上面的性质容易用反证法证明)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXP = 16;
const int prime[MAXP] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53};
ll n,res,ans;
void dfs(ll cur,ll num,ll key,ll pre)//µ±Ç°Êý/Òò×ÓÊý/ϱê/ÉϸöÃÝ
{
if(key>=MAXP)
return;
if(ans<num)
ans=num,res=cur;
else if(ans==num)
res=min(cur,res);
for(int i=1;i<=pre;i++)
{
if(cur<=n/prime[key])
{
cur*=prime[key];
dfs(cur,num*(i+1),key+1,i);
}
else
break;
}
}
int main()
{
int T;
cin>>T;
while(T--)
{
cin>>n;
res=ans=1;
dfs(1,1,0,60);
cout<<res<<' '<<ans<<endl;
}
return 0;
}