牛客小白月赛 5 水题

题目:https://www.nowcoder.com/acm/contest/135/C

思路: 

把m分解质因数,并存下每个质因数有几个。再看x!里有多少个这些质因数。取最小的倍数就是了。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll inf=1e18;
ll f[11111];
int cnt;
int num;
int ans[15]= {0,1,0,0,2,10,4,40,92,352,724,2680,14200,73712,365596};
ll p[100];
bool pr[100];
ll a[105];
ll x;
ll m;
void init()
{
    f[1]=1;
    f[2]=1;
    for(int i=3;;i++)
    {
        if(f[i-1]>inf-f[i-2])
        {
            cnt=i-1;
            break;
        }
        else
        {
            f[i]=f[i-1]+f[i-2];
        }
    }
    memset(pr,0,sizeof(pr));
    num=1;
    for(ll i=2;i<100;i++)
    {
        if(!pr[i])
        {
          p[num++]=i;
        for(int j=i*2;j<=100;j+=i)
        {
            pr[j]=1;
        }
        }
    }
}
ll findx(ll n)
{
    ll now=n;
    ll ans=0;
    while(x>=now)
    {
        ans+=x/now;
        now*=n;
    }
    return ans;
}
int main()
{
    init();
    scanf("%lld %d",&x,&m);
    int flag=0;
    for(int i=1;i<=cnt;i++)
    {
        if(f[i]>x)
        {
            break;
        }
        if(f[i]==x)
        {
            flag=1;
            break;
        }
    }
    if(!flag)
    {
        if(m>13)m=13;
        x%=m;
        x++;
        printf("%d\n",ans[x]);
    }
    else
    {
        memset(a,0,sizeof(a));
        int k=m;
        for(int i=1;i<num;i++)
        {
            while(k%p[i]==0)
            {
                k/=p[i];
                a[i]++;
            }
        }
        ll minn=1e18;
        //cout<<1<<endl;
        for(int i=1;i<num;i++)
        {
            if(a[i]>0)
            {
                //cout<<p[i]<<' '<<a[i]<<endl;
                minn=min(findx(p[i])/a[i],minn);
            }
        }
        printf("%lld\n",minn);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/imzxww/article/details/81194638