磊哥的密码箱icpc11526

问题 D: 磊哥的密码箱

时间限制: 1 Sec  内存限制: 128 MB
提交: 238  解决: 61
[提交] [状态] [命题人:admin]

题目描述

磊哥有个密码箱,里面装的都是令磊哥羞羞的东西。
箱子的密码是[1,n]里面的约数最多的数的约数数目。
磊哥的女朋友想知道磊哥到底装的是什么东西?她需要你的帮助。

输入

输入一个整数T,表示有T个测试数据
下面T行,每行输入一个正整数n。

输出

对每个n,输出对应一行一个正整数表示[1,n]里最多约数的数的约数个数。

样例输入

2
13
9

样例输出

6
4

提示

100%的数据满足:1 ≤ n ≤ 1,000,000,000,000,000,000.

解决这道题,涉及一点点数论的知识,点击查看。看完在看这道题(大佬随意QAQ)

 具体的思路呢其实就是贪心。

根据唯一分解定理和约数个数定理,我们知道对于每一个数,写成标准分解式(n = p1^a1*p2^a2...pk^ak),约数的个数为(a1+1)*(a2+1)...*(ak+1),为了使的约数的个数尽量多,p应该尽量选小的。

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,ans;
int p[30]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61};
ll qpow(ll a,ll b) //快速幂
{
    ll ret=1;
    while(b)
    {
        if (b&1) ret=ret*a;
        a=a*a;
        b>>=1;
    }
    return ret;
}
void dfs(ll poi,ll num,ll val,ll len) //枚举第几个质数poi,现在有几个约数,现在的值,ai的最大值
{
    if (val>n) return;
    if (val<=n) ans=max(ans,num);
    for (int i=1; i<=len; i++) //相当于枚举这位质数对应的a
    {
        ll t=qpow(p[poi],i);
        if (t>n/val) return;
        dfs(poi+1,num*(i+1),val*t,i);
    }
    return;
}
 
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        ans=0;
        scanf("%lld",&n);
        dfs(1,1,1,18);
        printf("%lld\n",ans);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/ztdf123/p/10931785.html