求两个超级大数的最大公约数

由于给出的数太大了,所以我们将两个数A,B拆成了N个数相乘和M个数相乘的形式。N,M<=1000,拆成的数<=1000000000。是不是够大?

最终的结果最多保留9位输出。

 

例如:

3
358572 83391967 82
3
50229961 1091444 8863

输出为:

000012028

 

根据欧拉公式,我们可以将任何一个数表示成如下形式:

n=p1^x1*p2^x2*p3^x3.......*pm^xm;

 

如果将A和B分别表示成

A = p1^a1 * p2^a2 * … * pn^an

B = p1^b1 * p2^b2 * … * pn^bn

其中p1,p2....都是素数,a1,a2...都是整数

那么

GCD( A, B ) = p1^min(a1,b1) * p2^min(a2,b2) * … * pn^min(an,bn)。

 

对于任何一个整数,我们可以快速的将它因式分解

scanf("%d",&a);
for(j=2;j*j<=a;j++)
{
    while(a%j==0)
        a/=j,A[j]++;
}
if(a>1)
    A[a]++;

对于这样由N个数乘积组成的数,我们可以将N个数的拆分结果全部保存在同一个A数组中,最终的结果就是超大数自身的拆分。
还有一个需要注意的是,给出的a<=1000000000,直接开数组内存上和时间上都很吃力,所以推荐用map<int,int>容器。

 

View Code
 1 #include<iostream>
 2 #include<string>
 3 #include<map>
 4 using namespace std;
 5 #define mod 1000000000
 6 
 7 map<int,int>A,B;
 8 int n,m,a;
 9 __int64 ans;
10 
11 int min(int a,int b)
12 {
13     return a<b?a:b;
14 }
15 
16 int main()
17 {
18     int i,j;
19     freopen("D:\\in.txt","r",stdin);
20     while(scanf("%d",&n)==1)
21     {
22         A.clear();B.clear();
23         for(i=0;i<n;i++)
24         {
25             scanf("%d",&a);
26             for(j=2;j*j<=a;j++)
27             {
28                 while(a%j==0)
29                     a/=j,A[j]++;
30             }
31             if(a>1)
32                 A[a]++;
33         }
34         scanf("%d",&m);
35         for(i=0;i<m;i++)
36         {
37             scanf("%d",&a);
38             for(j=2;j*j<=a;j++)
39             {
40                 while(a%j==0)
41                     a/=j,B[j]++;
42             }
43             if(a>1)
44                 B[a]++;
45         }
46         ans=1;
47         int flag=0;
48         map<int,int>::iterator it;
49         for(it=A.begin();it!=A.end();it++)
50         {
51             if(B.count(it->first))
52             {
53                 int p=it->first;
54                 int r=min(A[p],B[p]);
55                 for(i=0;i<r;i++)
56                 {
57                     ans*=p;
58                     if(ans>=mod)
59                     {
60                         ans%=mod;
61                         flag=1;
62                     }
63                 }
64             }
65         }
66         if(flag)
67             printf("%09d\n",(int)ans);
68         else
69             printf("%I64d\n",ans);
70     }
71     return 0;
72 }

 

 

posted @ 2012-08-31 14:45  Accept  阅读(3281)  评论(2编辑  收藏  举报