来源:牛客网
题目描述
t次询问,每次给你一个数n,求在[1,n]内约数个数最多的数的约数个数
输入描述:
第一行一个正整数t 之后t行,每行一个正整数n
输出描述:
输出t行,每行一个整数,表示答案
输入
5 13 9 1 13 16
输出
6 4 1 6 6
备注:
对于100%的数据,t <= 500 , 1 <= n <= 1000000000000000000
这里有一个约数个数公式
设ei代表比N小的所有质数;(i=1,2,3,4.......k)
N=(e1^x1)*(e2^x2)........(ek^xk)
则N的约数个数m=(x1+1)*(x2+1)......*(xk+1)
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<string> #include<cmath> using namespace std; typedef long long LL; const int mx = 1e5+10; const LL inf = 1e18; LL ans[mx],num[mx]; LL top=1; vector<int >pri; struct node { LL num,ans; bool operator < (const node A)const { return num<A.num; } }s[mx]; void prim()//求质数 { int n; for(int i=2;i<=60;i++) {n=1; for(int j=2;j*j<=i;j++) { if(i%j==0) { n=0; break; } } if(n) { pri.push_back(i); //cout<<i<<" "; } }//cout<<pri[0]<<endl; } int dfs(LL x,LL nu,LL r,LL ed)//对于每个质数有k次幂 { if(r==13) return 0; LL sum=pri[r]; int i=1; while(i<=ed) { if(x>inf/sum+1) break; s[top].num=x*sum; s[top++].ans=nu*(i+1); dfs(x*sum,nu*(i+1),r+1,i); if(x*sum>inf/pri[r]+1) break; i++;sum=sum*pri[r]; } return 0; } int main() { prim(); s[0].num=1;s[0].ans=1; dfs(1,1,0,100); sort(s,s+top); for(int i=0;i<top;i++) num[i]=s[i].num; ans[0]=s[0].ans; for(int i=1;i<top;i++) ans[i]=max(ans[i-1],s[i].ans);推出每个数下的最多约数 LL t,n; cin>>t; while(t--) { cin>>n; int zz; zz=upper_bound(num,num+top,n)-num-1;二分查找N cout<<ans[zz]<<endl; } return 0; }