题意:
给你一个数,问你有多少种进制对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 ",cas++,ans-1); } return 0; }