• Codeforces Round #538 (Div. 2) C Trailing Loves (or L'oeufs?)


    这题明白的意思就是求n!在b进制下的后缀零的个数。

    即最大的n!%(b^k)==0的k的值。我们需要将如果要构成b这个数,肯定是由一个个质因子相乘得到的。我们只需要求出b的质因子,然后分析n!中可以组成一个b的因子由多少个就可以了。

    因为b是10的12次方,所以b的质因子某个因子大于了10的6次方,那肯定是质数了,所以我们只需要筛选出10的6次方以内的质因子就可以了,并且记录下每个质因子的基数。

    最后是记录n!由多少个b的素因子组成并除以它的基数,取其中的最小值。

    n!中有多少个素因子(假设素因子是x),我们只需要算出1到n中所有a*x^b(a<x)的b的总和,我们不必将某个x^b一个个算出来,我们只需要算出(n/x)到(n/x^b)的总和即可。

    附上AC代码(感觉写得不怎么样

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<fstream>
    using namespace std;
    typedef long long ll;
    ll prime[1000005];
    struct node
    {
        ll num;
        ll data;
    } a[1000005];;
    bool vis[10000005];
    ll b;
    ll init()
    {
        memset(vis,false,sizeof(vis));
       ll k=0,i;
        for(i=2; i<=1000000; i++)
        {
            if(!vis[i])
            {
                prime[k++]=i;
                for(ll j=2; i*j<=1000000; j++)
                    vis[i*j]=true;
            }
        }
    
        return k;
    }
    int main()
    {
        ll k,i,j,n,cnt,sum,t=78498,r,mini;
        t=init();//线性筛出质数
        while(scanf("%I64d%I64d",&n,&b)!=EOF)
        {
            cnt=0;
            sum=0;
            r=b;
            for(i=0; i<t&&b!=1; i++)
            {
                if(b%prime[i]==0)
                {
                    a[cnt].data=prime[i];
                    a[cnt].num=0;
                    while(b%prime[i]==0)
                    {
                        a[cnt].num++;
                        b/=prime[i];
                    }
                    cnt++;
                }
            }
            if(b!=1)
                a[cnt].data=b,a[cnt++].num=1;
                b=r;
            for(i=0; i<cnt; i++)
            {
                for(j=a[i].data,sum=0,r=1; j<=n; j*=a[i].data)
                {
                    sum+=(n/j);
                    if(n/j<a[i].data)//为了防止j发生溢出
                        break;
                }
             if(i==0)
                mini=sum/a[i].num;
             else
                mini=min(mini,sum/a[i].num);
    
            }
            printf("%I64d
    ",mini);
    
        }
    
    }

  • 相关阅读:
    【算法】欧几里德算法--求最大公约数
    g++编译器的使用
    How arduino IDE works?
    【算法】反转链表
    判断一个数是否含有相同的数字
    Java集合ArrayList源码解读
    【算法】二分查找
    移动架构-原型模式
    移动架构-单例模式
    移动架构-简单工厂模式
  • 原文地址:https://www.cnblogs.com/Carits/p/10361449.html
Copyright © 2020-2023  润新知