牛客网 n的约数 (唯一分解定理)

链接:https://www.nowcoder.com/acm/contest/82/A
来源:牛客网

n的约数
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

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

输入描述:

第一行一个正整数t
之后t行,每行一个正整数n

输出描述:

输出t行,每行一个整数,表示答案
示例1

输入

5
13
9
1
13
16

输出

6
4
1
6
6

备注:

对于100%的数据,t <= 500 , 1 <= n <= 1000000000000000000


分析:题目前约数最多的个数,根据唯一分解定理有
a=p1^e1*p2^e2*......pk^ek,pi为素数且p1<p2<...<pk
a的总因子个数为(e1+1)*(e2+1)*(e3+1).....(ek+1)
所有一定有e1>=e2>=e3.......>=ek;
所以枚举低位素数因子的个数进行dfs操作,就能限制到高位素因子的个数,进而节约时间。

代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
LL prime[20] = {0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};
int maxx;
 LL n,t;
void  dfs(LL x,int pos,int lim,int num) //pos是素数下标,lim是低位对高位素数的限制,num是目前的因子个数
{
    if(pos>15)return;
      maxx=max(maxx,num);
       for(int i=1;i<=lim;i++)
   {
       if(n/prime[pos]<x)break;//防止越界
        x*=prime[pos];
        dfs(x,pos+1,i,num*(i+1));
   }

}
int main()
{
    ios::sync_with_stdio(false);
    cin>>t;
    while(t--)
    {
        maxx=0;
        cin>>n;
        dfs(1LL,1,64,1);
        cout<<maxx<<endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/a249189046/p/8698179.html