zoukankan      html  css  js  c++  java
  • 洛谷 P3927 Factorial

    题目描述

    SOL君很喜欢阶乘。而SOL菌很喜欢研究进制。

    这一天,SOL君跟SOL菌炫技,随口算出了n的阶乘。

    SOL菌表示不服,立刻就要算这个数在k进制表示下末尾0的个数。

    但是SOL菌太菜了于是请你帮忙。

    说明

    对于20%的数据,n <= 1000000, k = 10

    对于另外20%的数据,n <= 20, k <= 36

    对于100%的数据,n <= 10^12,k <= 10^12

      这道题的思路还是挺显然的,0的个数即n!和k共同质因数的数量之比最小的那个。K的质因数很容易在O(√k)的时间内统计出来,问题是N!中与K相同的质因子的个数怎么统计

      我们令G(T,K)表示T中质因子K的个数,显然有:

        G(N!,K)=G(1*2*....*N,K)=G(1*K*2*K*3*K*....*[N/K]*K,K)

      我们对这个式子进一步变形:

        G(1*K*2*K*3*K*....*[N/K]*K,K)=G(K^[N/K]*1*2*....*[N/K],K)=[N/K]+G([N/K],K)

      接下来的问题接下来显然可以递归处理,易证G函数的复杂度是O(log N)

      于是问题就那么1A了。(题目挺简单,但我特么调了半个钟精度。。。垃圾devc++(╯°Д°)╯︵ ┻━┻)

      

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 1000000+10
    typedef long long LL;
    const LL INF=1e13;
    LL n,k,ans=INF,cn[MAXN],ck[MAXN],prime[MAXN],fac[MAXN];
    bool isprime[MAXN];
    int cnt=0,tot=0,had[MAXN];
    void form(){
        memset(isprime,true,sizeof(isprime));
        isprime[1]=false;
        for(int i=2;i<=MAXN-10;i++){
            if(isprime[i])prime[++cnt]=i;
            for(int j=1;j<=cnt&&i*prime[j]<=MAXN-10;j++){
                isprime[i*prime[j]]=false;
                if(i%prime[j]==0)break;
            }
        }    
    }
    void dealk(){
        for(LL i=2;i*i<=k;i++)
            if(isprime[i]&&k%i==0)fac[++tot]=i;
        LL p=k;
        for(int i=1;i<=tot;i++){
            while(p%fac[i]==0){
                had[i]++;
                p/=fac[i];
            }
        }
        if(p!=1)fac[++tot]=p,had[tot]++;
    }
    LL calc(LL p,LL t){
        if(p==0)return 0;
        LL f=(LL)p/t;
        return f+calc(p/t,t);
    }
    int main(){
        form();
        scanf("%lld%lld",&n,&k);
        dealk();
        for(int i=1;i<=tot;i++){
            LL p=calc(n,fac[i]);
            p/=had[i];
            ans=min(ans,p);
        }
        printf("%lld
    ",ans);
        return 0;
    }

       吐槽一波:洛谷的题目相比雅礼集训的简直小清新2333333

  • 相关阅读:
    MATLAB 中sparse函数使用及full函数用法简单介绍(转)
    稀疏矩阵加减,乘除, 逆 (转)
    拟合方法求直线方程系数
    matlab filtfilt 函数
    Typora 精美而强大的Markdown编辑器 转
    MATLAB生成exe脱离matlab运行可执行程序
    matlab 生成.exe文件 转
    C#排序 转
    C# 进制转换(二进制、十六进制、十进制互转) 转载 https://www.cnblogs.com/icebutterfly/p/8884023.html
    一维高斯滤波 转
  • 原文地址:https://www.cnblogs.com/NINGLONG/p/7642785.html
Copyright © 2011-2022 走看看