本题题意为求 t (t<150) 个 c (n,m) (1<=m<=n<=100000)的最大公因子;
本题的难点为优化。主要有两个优化重点。一是每次对单个素因子进行处理,优化每次的数组清零;二是对求阶乘素因子个数的优化
ei=[N/pi^1]+ [N/pi^2]+ …… + [N/pi^n] 其中[]为取整
ei 为数 N!中pi 因子的个数;
1 #include <iostream> 2 #include <cstring> 3 #include <cmath> 4 5 #define maxn 100010 6 7 using namespace std; 8 9 int sign[maxn]; 10 int pri[maxn]; 11 int tot; 12 int e; 13 int n[200],k[200]; 14 15 void getpri (){ 16 memset (sign,0,sizeof sign); 17 tot=0; 18 sign[0]=sign[1]=1; 19 for (int i=2;i*i<maxn;i++){ 20 if (!sign[i]){ 21 for (int j=i*i;j<maxn;j+=i){ 22 sign[j]=1; 23 } 24 } 25 } 26 for (int i=2;i<maxn;i++){ 27 if (!sign[i]){ 28 pri[tot++]=i; 29 } 30 } 31 } 32 33 int main (){ 34 long long ans; 35 getpri (); 36 int t; 37 while (cin>>t){ 38 int minnn=maxn+1; 39 for (int i=0;i<t;i++){ 40 cin>>n[i]>>k[i]; 41 minnn=min (minnn,n[i]); 42 k[i]=min (k[i],n[i]-k[i]); 43 } 44 ans=1; 45 for (int i=0;i<tot&&pri[i]<minnn;i++){ //每次处理单个素因子 46 e=999999; 47 int temp=0; 48 for (int j=0;j<t;j++){ 49 temp=0; 50 int flag=n[j]; 51 while (flag){ //求 n! 中因子 pri(i) 的个数 52 temp+=flag/pri[i]; 53 flag/=pri[i]; 54 } 55 flag=k[j]; 56 while (flag){ 57 temp-=flag/pri[i]; 58 flag/=pri[i]; 59 } 60 flag=n[j]-k[j]; 61 while (flag){ 62 temp-=flag/pri[i]; 63 flag/=pri[i]; 64 } 65 e=min (e,temp); 66 }//cout<<e<<pri[i]; 67 while (e--){ 68 ans*=pri[i]; 69 } 70 } 71 cout<<ans<<endl; 72 } 73 return 0; 74 }