約數個數

鏈接:https://www.nowcoder.com/acm/contest/82/A
來源:牛客網

題目描述

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
這裏有一個約數個數公式
設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;
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章