整除问题,给定n和a,求最大的k,使n!可被ak整除但不能被a(k+1)整除,其实就是素数问题和模运算问题的提升版:比如输入:n=6,a=10,输出:1;因为n!很大,所以不能用普通的int或者long long 去存储,这里介绍一种方法,利用赵公共素因子的方式去解决即可。比如n=6,那么6的阶乘所含有的因子为:2222335;10的因子有:25;所以如果n!要整除10,我们可以看出如果1010,,即为2525=2255,因为n!的2很多,所以10的k次方不受2的个数的影响,而n!中只有一个5,那么10*10就收到5的个数的限制,所以我们可以发现,实际上,k的值就是n!和a的相同素因子中个数最少的那个素因子的个数,代码如下:
//@author:hairu,wu
#include<iostream>
#include<vector>
#include<map>
using namespace std;
const int max_n=1e5;
bool mark[max_n]={false};
int prime[max_n];
int size=0;
//素数打表
void init_fun(){
for(int i=2;i<max_n;i++){
mark[i]=true;
}
for(int i=2;i<max_n;i++){
if(mark[i]){
prime[size++]=i;
for(int j=i+i;j<max_n;j+=i){
mark[j]=false;
}
}
}
}
int main(){
init_fun();
int n,a;
cin >> n>> a;
map<int,int> v1,v2;//v1保存n!的素因子,v2保存a的素因子
//计算n!的素因子
for(int i=2;i<=n;i++){
if(mark[i]){
//如果是素数
v1[i]++;
}else{
//进行分解
int tmp=i;
for(int j=0;j<size;j++){
if(tmp%prime[j]==0){
while(tmp%prime[j]==0){
v1[prime[j]]++;
tmp=tmp/prime[j];
if(tmp==1) break;
}
if(tmp==1) break;
}
}
}
}
//计算a的素因子
for(int i=0;i<max_n;i++){
if(a%prime[i]==0){
while(a%prime[i]==0){
v2[prime[i]]++;
a=a/prime[i];
if(a==1) break;
}
}
if(a==1) break;
}
//找到两者共有的数目最少的那个因子的个数
int Min=max_n;
for(map<int,int>::iterator ite=v2.begin();ite!=v2.end();ite++){
int tmp=ite->first;
if(v1[tmp]>0){
Min=min(Min,v1[tmp]);
}
}
cout<<Min<<endl;
return 0;
}