Lightoj1028 【数学-乘法原理】

题意:

给你一个数,问你有多少种进制对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;
}



原文地址:https://www.cnblogs.com/keyboarder-zsq/p/6216764.html