HDU 3988 Harry Potter and the Hide Story【數論】

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=3988
題目大意:給定n,kn,k,找到最大的ii滿足{iki  divides  n!}\{i|k^i \ \ divides \ \ n!\}kk數據範圍1e141e14nn數據範圍1e181e18
思路:
直接對kk素因子分解,然後對於每一個素因子,找出在n!n!中的個數(這步有點像求n!n!末尾零的個數),然後對應相除,找最小的即可。
n!n!中素因子pp的個數一定不會超過long longlong \ long,這個可以由等比公式求和證明,然後直接素因子分解解決。
AC代碼:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,k;
const int maxn=1e7+10;
bool notprime[maxn]={1,1};
ll pri[maxn];
int tot=0;
void Getprime()
{
    for(ll i=2;i<maxn;i++){
        if(!notprime[i]){
            pri[tot++]=i;
            for(ll j=i*i;j<maxn;j+=i){
                notprime[j]=1;
            }
        }
    }
}
map<ll,ll>mp;
int main()
{
    int t;
    scanf("%d",&t);
    int Case=0;
    Getprime();
    while(t--){
        scanf("%lld%lld",&n,&k);
        printf("Case %d: ",++Case);
        if(k==1){
            printf("inf\n");
            continue;
        }
        ll tmpk=k;
        ll ans=2e18;
        for(int i=0;i<tot;i++){
            if(pri[i]>tmpk){
                break;
            }
            while(tmpk%pri[i]==0){
                mp[pri[i]]++;
                tmpk/=pri[i];
            }
        }
        if(tmpk>1){
            mp[tmpk]=1;
        }
        map<ll,ll>::iterator it=mp.begin();
        for(;it!=mp.end();it++){
            ll t=0;
            ll tn=n;
            ll t1=it->first;
            ll t2=it->second;
            while(tn>0){
                t+=tn/t1;
                tn/=t1;
            }
            t/=t2;
            ans=min(ans,t);
        }
        printf("%lld\n",ans);
        mp.clear();
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章