• 【GDKOI2014】JZOJ2020年8月13日提高组T1 阶乘


    【GDKOI2014】JZOJ2020年8月13日提高组T1 阶乘

    题目

    Description

    在这里插入图片描述

    Input

    第一行有一个正整数T,表示测试数据的组数。
    接下来的T行,每行输入两个十进制整数n和base。

    Output

    对于每组数据,输出一个十进制整数,表示在base进制下,n!结尾的零的个数。

    Sample Input

    2
    10 10
    10 2

    Sample Output

    2
    8

    Data Constraint

    对于20%的数据,n<=20,base<=16
    对于50%的数据,n<=109,base<=105
    对于100%的数据,1<=T<=50,0<=n<=1018,2<=base<=1012

    题解

    题意

    给出(n)(base),求(n)的阶乘在(base)进制下末尾0的个数

    分析

    很显然可以先将(base)质因数分解
    (base)拆成(p1^{k1}*p2^{k2}*……)的形式
    记录底数和指数
    然后对于每个质数
    (n)一直除以(p),把每次的商加起来
    除以指数,取个最小值即为答案

    Code

    #include<bits/stdc++.h>
    #define rg register
    #define MAX 1000000
    #define inf 999999999999999
    using namespace std;
    long long t,n,m,i,x,num,sum,ans,prime[1000005],tot[1000005];
    bool b[1000005];
    int main()
    {
        freopen("test.in","r",stdin);
        freopen("test.out","w",stdout);
        memset(b,true,sizeof(b));
        b[1]=false;
        for (rg long long i=2;i<=MAX;i++)
            for (rg long long j=2;i*j<=MAX;j++)
                b[i*j]=false;
        scanf("%lld",&t);
        while (t--)
        {
            scanf("%lld%lld",&n,&m);
            if (n==0) 
            {
                printf("0
    ");
                continue;
            }
            num=0;
            memset(prime,0,sizeof(prime));
            memset(tot,0,sizeof(tot));
            for (rg long long i=2;i*i<=m;i++)
            {
                if (b[i]==true&&m%i==0)
                {
                    num++;
                    prime[num]=i;
                    while (m%i==0)
                    {
                        tot[num]++;
                        m/=i;
                    }
                }
            }
            if (m>1)
            {
                num++;
                prime[num]=m;
                tot[num]=1;
            }
            ans=inf;
            for (rg long long i=1;i<=num;i++)
            {
                x=n;
                sum=0;
                while (x)
                {
                    sum+=x/prime[i];
                    x/=prime[i];
                }
                sum/=tot[i];
                ans=min(ans,sum);
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    2019.5.1
    拓扑排序(topological sort)
    邻接表+链式前向星
    桶排序+基数排序+计数排序
    奶牛排队
    set
    win10家庭版怎么开启Administrator超级管理员帐户
    Office Online Server 在线编辑Office文档,安装部署
    Centos分区/超过2T的磁盘
    win10照片查看器不能看jpg等格式图片
  • 原文地址:https://www.cnblogs.com/Livingston/p/13497334.html
Copyright © 2020-2023  润新知