本题题意为求 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 }

 

 

posted on 2014-07-14 16:20  gfc  阅读(172)  评论(0编辑  收藏  举报