题意:
给你一个数,问你有多少种进制对n的表示,存在后导零;
比如30:用3进制表示: 1010
思路:
我们发现,就是一个数的约数就能对n表示最后存在后导零;
计算[2 ,n]之间的n的约数个数。
我们预处理<=sqrt(n)的素数,然后枚举过来,就像筛选素数因子一样,计算一下素约数的个数num,ans*=(num+1)代表取num个的情况或者不取,然后最后出来判断一下n是不是>1,大于1说明存在>sqrt(n)的素数,ans*=2,然后乘法原理最后会有一个情况那就是1,最后ans要减1。
#include <cstdio>
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
typedef long long LL;
/*
问你有多少种进制对n的表示,最后存在后导零;
*/
const long long INF=0x3f3f3f3f;
const int N=1e6+10;
bool IsPrime[N];
LL prime[N];
LL num;
void init()
{
num=0;
for(LL i=2; i<N; i++)
{
if(IsPrime[i]) continue;
prime[++num]=i;
for(LL j=i+i; j<N; j+=i)
IsPrime[j]=true;
}
}
int main()
{
init();
int T,cas=1;
LL n;
scanf("%d",&T);
while(T--)
{
scanf("%lld",&n);
LL cnt = n,tmp,ans=1;
for(int i=1;(prime[i]*prime[i])<=n&&i<=num;i++)
{
if(n%prime[i]==0)
{
tmp=0;
while(n%prime[i]== 0)
{
tmp++;
n/=prime[i];
}
ans*=(tmp+1);
}
}
if(n > 1)
ans*=2;
printf("Case %d: %lld\n",cas++,ans-1);
}
return 0;
}