http://acm.hust.edu.cn:8080/judge/problem/viewProblem.action?id=24019
根据性质来求解
任何一个合数都可以表示成几个质数的乘积,质数的乘积是本身。
任何一个数都可以表示成几个素数的和,素数是他本身
比如要算 10!可以最大整除除以2 的多少次方
a:10 9 8 7 6 5 4 3 2 1
a列的数除以2 变为(取整)
b:5 4 3 2 1
同理得
c:2 1
那么ans=10/2+5/2+2/2
可以这样考虑 因为是阶乘的,所以 这尼玛说不清了 看图吧 ,看看就明白了
View Code
#include<iostream> #include<string.h> #include<stdio.h> #include<algorithm> #define maxn 1200005 #define ll long long #define inf ~0U>>1 using namespace std; int prime[maxn]; int visit[6000000]; int cnt=0; void init() { memset(visit,0,sizeof(visit)); memset(prime,0,sizeof(prime)); for(int i=2;i<=maxn;i++) { if(!visit[i]) prime[++cnt]=i; for(int j=i+i;j<maxn;j+=i) { visit[j]=1; } } } ll go(ll n,ll k) { ll sum=0; while(n>=1) { n/=k; sum+=n; } return sum; } ll min(ll a, ll b ) { return a<b?a:b; } void solve(ll n,ll k) { ll ans=inf; ans*=inf; ll num=0; int mm=1; for(int i=1;k>1&&k>prime[i]&&i<=cnt;i++) if(k%prime[i]==0) { mm=1; for(k/=prime[i];k%prime[i]==0;k/=prime[i])mm++; ans=min(ans,go(n,prime[i])/mm);//拿每一个算答案 } if(k>1) ans=min(ans,go(n,k));//大于1还要算 cout<<ans<<endl; } int main() { int test; cin>>test; ll n,k; init(); while(test--) { cin>>n>>k; solve(n,k); } return 0; }