题意:求一个数n,有多少种进制表示方法,使得末尾为0.例子:9=(30)三进制
题解:我们知道二进制(1101)=1*2^0+0*2^1+1*2^2+1*2^3=13。转换成n进制之后,若末尾为0。则原十进制数必定被n整除。相对应的当一个数是n的倍数的时候,必定能转换成末尾为0的n进制。所以该题就是求输入数的约数个数。求下欧拉函数就好。
注意:由于输入的数很大n=10^12,且测试数据很多T=10000。因而不能直接枚举sqrt(n)。需要找出10^6以内的素数,然后枚举素数。除此之外还要用prime[i]*prime[i]<=n限制。
#include <cstdio>
#include <cmath>
#include <cstring>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
const LL maxn=1e6+10;
LL prime[maxn],t,vis[maxn];
void init()
{
LL i,j,k;
t=0;
memset(vis,0,sizeof(vis));
for(i=2;i<maxn;i++)
{
if(!vis[i])
{
for(j=i*i;j<maxn;j+=i)
vis[j]=1;
prime[t++]=i;
}
}
}
int main()
{
init();
LL T,tt=0;
scanf("%lld",&T);
while(T--)
{
LL i,j,k,m,ans=1,s;
LL num,n;
scanf("%lld",&n);
num=n;
for(i=0;i<t&&prime[i]*prime[i]<=num;i++)//欧拉函数,注意要用prime[i]*prime[i]<=num限制
{
if(num%prime[i]==0)
{
s=0;
while(num%prime[i]==0){s++;num/=prime[i];}
ans*=(s+1);
}
}
if(num>1)ans*=2;
printf("Case %lld: %lld\n",++tt,ans-1);
}
return 0;
}