洛谷10月月赛R1·浴谷八连测R1·提高组 一道中档题 Factorial

来源:互联网 发布:精神发育迟缓症状知乎 编辑:程序博客网 时间:2024/05/21 19:28

我们考虑,0是由进位造成的,而只有乘起来正好进位才行,所以我们想到把k分解质因数,统计出个数,除一下,找最小的
比如 40是2,2,2,5解释说三个二一个五组成零
因为n很大,n的阶乘分解质因数有小学奥数公式
while(tmp>=q){
toto+=tmp/q;
q=q*s[i];
}
而这个题要分解大数的质因数,可以用Pollard_Rho点这里
进制数很大

#include<cstdio>#include<cstdlib> #include<algorithm>#include<iostream>#define ll long long using namespace std;ll s[10000009],num,x,y,tot[10000009];ll multi(ll a ,ll k,ll p){    ll ans=0;    while(k){        if(k&1) ans=(ans+a)%p;        a=(a+a)%p;        k>>=1;     }    return ans;}ll qpow(ll a,ll k,ll p){    ll ans=1;    while(k){        if(k&1) ans=multi(ans,a,p);        a=multi(a,a,p);        k>>=1;     }    return ans;}/*ll prepare(){    for(int i=1;i<=5000000;i++){        if(!ip[i])            pr[++cnt]=i;        for(int j=2;j<=cnt,pr[j]*i<=5000000;j++){            ip[pr[i]*j]=1;            if(!(j%pr[i])) break;        }    }}*/bool Miller_Rabin(ll n){    if(n==2) return 1;    ll u=n-1,t=0,s=50;    while(!(u&1ll))        t++,u>>=1;    while(s--){        ll a=rand()%(n-1)+1;        x=qpow(a,u,n);        for(int i=1;i<=t;i++){            y=x,x=multi(x,x,n);            if(x==1&&y!=1&&y!=n-1)return 0;         }if(x!=1) return 0;    }       return 1;}ll gcd(ll a,ll b){     return b?gcd(b,a%b):a;}ll Pollard_Rho(ll n,ll c){    ll i=1,k=2,x=rand()%(n-1)+1,y=x;    while(i++){        x=(multi(x,x,n)+c)%n;        ll p=gcd(y-x,n);        if(p>1&&p<n) return p;        if(x==y) return n;        if(i==k) y=x,k<<=1;    }}void find(ll n,ll c){    if(n==1) return ;    if(Miller_Rabin(n)) {        s[++num]=n;return ;    }    ll p=n,k=c;     while(p==n) p=Pollard_Rho(n,c--);    find(p,k);find(n/p,k);}ll N,K;int main(){    scanf("%lld%lld",&N,&K);    find(K,9999999);    sort(s+1,s+num+1);ll j=0;    for(ll i=1;i<=num;i++){        if(s[i]!=s[i-1]) tot[++j]++;        else tot[j]++;    }    ll t1=unique(s+1,s+num+1)-s-1;//去重    ll ans=199999999999999;    for(ll i=1;i<=t1;i++)    {            ll tmp=N;        ll toto=0;        ll q=s[i];        while(tmp>=q){            toto+=tmp/q;            q=q*s[i];        }        ans=min(toto/tot[i],ans);    }    printf("%lld",ans);} 
阅读全文
1 0
原创粉丝点击