牛客网 n的约数 (唯一分解定理)
链接:https://www.nowcoder.com/acm/contest/82/A
来源:牛客网
n的约数
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
空间限制: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; }