【51nod1060】【最复杂的数】【数论】【反素数】【搜索】【结论】

来源:互联网 发布:视频旋转软件中文版 编辑:程序博客网 时间:2024/06/05 15:02

题目大意

把一个数的约数个数定义为该数的复杂程度,给出一个n,求1-n中复杂程度最高的那个数。例如:12的约数为:1 2 3 4 6 12,共6个数,所以12的复杂程度是6。如果有多个数复杂度相等,输出最小的。

解题思路

额……这个是求小于n的最大反素数(一脸懵逼)。

对于任何正整数x,其约数的个数记做g(x)。如果某个正整数x满足:对于任意i(0<i<x),都有g(i)<g(x),则称x为反素数。

这里有一个结论(惊恐无比的眼神……结论题)性质一:一个反素数的质因子必然是从2开始连续的质数.性质二:p=2^t1*3^t2*5^t3*7^t4…..必然t1>=t2>=t3>=….

额……我们发现最多只有log个质因子,有了上面的性质搜索剪枝就会跑得飞起,额……(心虚)。

code

#include<cmath>#include<cstdio>#include<algorithm>#define LL long long#define min(a,b) ((a<b)?a:b)#define max(a,b) ((a>b)?a:b)#define fo(i,j,k) for(int i=j;i<=k;i++)#define fd(i,j,k) for(int i=j;i>=k;i--)using namespace std;int const maxn=500;int t,anss,ss[26]={25,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97};LL n,noww,inf=1e18;void dfs(int pos,int mx,LL now,int ans){    if(ans>=anss){        if(anss==ans)noww=min(now,noww);        else noww=now;        anss=ans;    }    if(pos>ss[0])return;    fo(i,1,mx){        if(ss[pos]>1.0*n/now+1e-12)return;        now=now*ss[pos];        dfs(pos+1,i,now,ans*(i+1));    }}int main(){    scanf("%d",&t);    fo(cas,1,t){        scanf("%lld",&n);        anss=-1e9;        //double xx=log(2),yy=log((int)n);        dfs(1,log(n)/log(2),1,1);        printf("%lld %d\n",noww,anss);    }    return 0;}
0 0