时间限制:20000ms
单点时限:1000ms
内存限制:256MB
描述
给定 n, k,求一个最大的整数 m,使得 km 是 n! 的约数
输入
第一行两个正整数 n, k
2 ≤ n,k ≤ 109
输出
输出最大的 m
样例输入
5 2
样例输出
3
http://hihocoder.com/contest/offers69/problem/3
打素数表表打到sqrt(k),求出k的所有质因数。根据n!的性质,求出其中k的质因数的个数。输出约束条件最强的那一组即是答案。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+45;
#define INF 0x3f3f3f3f;
#define ll long long int
#define charmax(x,y) x=max(x,y)
#define charmin(x,y) x=min(x,y)
#define clr(x,p) memset(x,p,sizeof x)
int n,k;int sz=0;int cs=0;
int pri[maxn];
int vis[maxn];
int num[maxn];
int sum[maxn];
void getprime(){
clr(vis,0);
clr(pri,0);
vis[0]=vis[1]=1;
for(int i=2;i<maxn;i++){
if(!vis[i]){
for(int j=2*i;j<maxn;j+=i){
vis[j]=1;
}
}
}
for(int i=2;i<maxn;i++){
if(!vis[i]) pri[++sz]=i;
}
//for(int i=1;i<=10;i++) printf("%d ",pri[i]);
// cout<<1<<endl;
}
void getin(){
clr(num,0);
clr(sum,0);
int pos=1;
for(int i=1;i<=sz;i++){
if(k==0||k==1) break;
if(k%pri[i]==0){
num[++cs]=pri[i];
while(k!=1&&k!=0&&k%pri[i]==0){
k/=pri[i];
sum[cs]++;
}
}
}
if(k>1){
num[++cs]=k;
sum[cs]=1;
}
// for(int i=1;i<=cs;i++){printf("%d ",num[i]); }
}
void getprinum(){
ll ans=1e17;
//cout<<ans<<endl;
for(int i=1;i<=cs;i++){
ll tmp=n;
ll ks=0;
ll cz=num[i];
//cout<<num[i]<<endl;
while(cz<=tmp){
ks+=tmp/cz;
cz=cz*num[i];
}
ks/=1ll*sum[i];
charmin(ans,ks);
//cout<<i<<endl;
}
//cout<<1<<endl;
printf("%lld\n",ans);
}
int main()
{
scanf("%d %d",&n,&k);
getprime();
getin();
getprinum();
return 0;
}