【数学】小A进学校

题目链接

http://icpc.upc.edu.cn/problem.php?cid=1882&pid=3


题意:

求n! 在k进制下末尾0的个数

 


题解:

可以知道

一个数N可以转换成a*(k^x)   (k表示进制,x表示末尾0的个数)

即N=a*(k^x) 

例如: 十进制 1300 =13*(10^2)

               二进制 100 = 1*(2^2)

所以

        N=a*(k^x)

        由唯一分解定理得k=(b1^x1)*(b2^x2)*…*(bm^xm)

        ->N=a*((b1^x1)*(b2^x2)*…*(bm^xm))^x

        ->N=a*((b1^(x1*x))*(b2^(x2*x))*…*(bm^(xm*x)))

  这里可以换一种表示形式

 即N=Ai*(bi^Si)   其中 Ai=a*( (b1^(x1*x))*(b2^(x2*x))*(b(i-1)^(x(i-1)*x))*(b(i+1)^(x(i+1)*x))…*(bm^(xm*x))即除了第i项外其他的乘积

 所以要求的x=Si/xi

   这里存在N=A1*(b1^S1) N=A2*(b2^S2)  ……

 找一个最小值即可

 


其中对n! 中存在多少个p的理解,即对上面的式子中Si的求解

比如说8!=1*2*3*4*5*6*7*8 中有多少个2

其中 2,4,6,8 中存在4个具有2的质因子

   2 3 4中存在2个具有2的质因子

   2中存在1个具有2的质因子

   所以总共8! 存在7个2

 

公式:

f(n)=(n/p)+(n/p/p)+(n/p/p/p)+…           

 


 

#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<stdio.h>
#include<string.h>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<unordered_map>
#pragma GCC optimize(2)
#define debug cout<<"*"<<endl;
#define input(x) scanf("%d",&x)
#define output(x) printf("%d\n",x)
#define llinput(x) scanf("%lld",&x)
#define lloutput(x) printf("%lld\n",x)
using namespace std;
typedef long long ll;
typedef __int128 Biginteger;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<string,int> psi;
typedef pair<char,char> pcc;
const int mod=1e9+7;
const int INF=1e9+7;
const int maxn=1e6+7;
const double PI=acos(-1);
const int N=4;
ll prime[1000007];
ll cnt=0;
ll vis[1000007];
void get_pri(ll k)      //唯一分解定理求k的因子和因子数量
{
    for(ll i=2;i*i<=k;i++)
    {
        while(k%i==0)
        {
            prime[cnt]=i;vis[cnt]++;k/=i;
        }
        if(prime[cnt])  cnt++;

    }
    if(k>1) prime[cnt]=k,vis[cnt++]=1;
}
ll get_cot(ll n,ll pri)    //求n! 中存在多少个pri
{
    ll res=0;
    while(n>0)
    {
        res+=n/pri;
        n/=pri;
    }
    return res;
}
int main()
{
    ll n,k;
    ll ans=1e18+7;
    cin>>n>>k;
    get_pri(k);
    for(ll i=0;i<cnt;i++)    //遍历找最小值
    {
        ans=min(ans,get_cot(n,prime[i])/vis[i]);    
    }
    cout<<ans<<endl;
    return 0;
}

 


学习博客:

https://www.e-learn.cn/content/qita/2008269

https://www.jianshu.com/p/ee73fdfaa8e1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值