牛客 - n的约数

原题:n的约数 (nowcoder.com)

题意:t次询问,每次给你一个数n,求在[1,n]内约数个数最多的数的约数个数。

分析:根据算数基本定理,正整数N一定能被分解成质数的次方的乘积的形式。相较于较大的质数,较小的质数如果次方数更高,则约数个数越多,因为约数个数只与指数有关,所以从最小的质数2开始,枚举每一个指数,递归下一个质数时,使指数递减,则能使约数个数最多。

题解:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll ans=0,n;
int prime[20]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,51};//记录1到n范围内用到的质数
ll qpow(ll a,ll b)
{
    ll ans=1;
    while(b)
    {
        if(b&1) ans*=a;
        a*=a;
        b>>=1;
    }
    return ans;
}
void dfs(int pos,ll cnt,ll sum,int len)
{//分别表示:记录到哪一个质数,目前约数个数,用质数乘出来的数,这个约数的指数范围
    if(sum>n) return;
    ans=max(ans,cnt);
    
    for(int i=1;i<=len;i++)
    {
        ll tmp=qpow(prime[pos],i);
        if(sum>n/tmp) break;//剪枝,不能变成sum*tmp>n,因为sum*tmp可能太大而越界
        dfs(pos+1,cnt*(i+1),sum*tmp,i);
    }
    return;
}

int main()
{
    int t;
    cin>>t;
    
    while(t--)
    {
        scanf("%lld",&n);
        
        ans=0;
        dfs(1,1,1,60);
        
        cout<<ans<<endl;
    }
    return 0;
}
posted @ 2021-08-26 10:49  AtomsH  阅读(205)  评论(0)    收藏  举报