首页 > 代码库 > fzu 1753 Another Easy Problem
fzu 1753 Another Easy Problem
本题题意为求 t (t<150) 个 c (n,m) (1<=m<=n<=100000)的最大公因子;
本题的难点为优化。主要有两个优化重点。一是每次对单个素因子进行处理,优化每次的数组清零;二是对求阶乘素因子个数的优化
ei=[N/pi^1]+ [N/pi^2]+ …… + [N/pi^n] 其中[]为取整
ei 为数 N!中pi 因子的个数;
#include <iostream>
#include <cstring>
#include <cmath>
#define maxn 100010
using namespace std;
int sign[maxn];
int pri[maxn];
int tot;
int e;
int n[200],k[200];
void getpri (){
memset (sign,0,sizeof sign);
tot=0;
sign[0]=sign[1]=1;
for (int i=2;i*i<maxn;i++){
if (!sign[i]){
for (int j=i*i;j<maxn;j+=i){
sign[j]=1;
}
}
}
for (int i=2;i<maxn;i++){
if (!sign[i]){
pri[tot++]=i;
}
}
}
int main (){
long long ans;
getpri ();
int t;
while (cin>>t){
int minnn=maxn+1;
for (int i=0;i<t;i++){
cin>>n[i]>>k[i];
minnn=min (minnn,n[i]);
k[i]=min (k[i],n[i]-k[i]);
}
ans=1;
for (int i=0;i<tot&&pri[i]<minnn;i++){ //每次处理单个素因子
e=999999;
int temp=0;
for (int j=0;j<t;j++){
temp=0;
int flag=n[j];
while (flag){ //求 n! 中因子 pri(i) 的个数
temp+=flag/pri[i];
flag/=pri[i];
}
flag=k[j];
while (flag){
temp-=flag/pri[i];
flag/=pri[i];
}
flag=n[j]-k[j];
while (flag){
temp-=flag/pri[i];
flag/=pri[i];
}
e=min (e,temp);
}//cout<<e<<pri[i];
while (e--){
ans*=pri[i];
}
}
cout<<ans<<endl;
}
return 0;
}