zoukankan      html  css  js  c++  java
  • POJ2429 GCD & LCM Inverse pollard_rho大整数分解

    Given two positive integers a and b, we can easily calculate the greatest common divisor (GCD) and the least common multiple (LCM) of a and b. But what about the inverse? That is: given GCD and LCM, finding a and b.

    Input

    The input contains multiple test cases, each of which contains two positive integers, the GCD and the LCM. You can assume that these two numbers are both less than 2^63.

    Output

    For each test case, output a and b in ascending order. If there are multiple solutions, output the pair with smallest a + b.

    Sample Input

    3 60

    Sample Output

    12 15

    题意:给出两个数的最大公约数和最小公倍数,让你找出满足条件的两个数,使他们的和最小。

    题解:

    对于两个数a,b和他们的最大公约数gcd以及最小公倍数lcm,有lcm=a*b/gcd,进一步变形可以得到:(a/gcd * b/gcd)*gcd=lcm,即(a/gcd * b/gcd)=lcm/gcd,我们令m=a/gcd,n=b/gcd,那么问题就变为了:找出两个互素的整数,使他们的乘积为key=lcm/gcd。我们可以用Pollard_rho算法进行质因素分解的方法找出lcm/gcd的所有素因子,然后dfs找出任意几个素数因子之积(设为x),设y=key/x,找出最小的x+y就行了

    代码:

      1 #include <cstdio>
      2 
      3 #include <iostream>
      4 
      5 #include <cstdlib>
      6 
      7 #include <cmath>
      8 
      9 #include <algorithm>
     10 
     11  
     12 
     13 #define times 10
     14 
     15 #define N 501
     16 
     17 using namespace std;
     18 
     19 typedef unsigned long long LL;
     20 
     21 const LL INF=(LL)1<<61;
     22 
     23 LL key,ct,cnt,gd,lm,resa,resb,mini;
     24 
     25 LL fac[N],num[N];
     26 
     27  
     28 
     29 LL gcd(LL a,LL b)
     30 
     31 {
     32 
     33     return b?gcd(b,a%b):a;
     34 
     35 }
     36 
     37  
     38 
     39 LL multi(LL a,LL b,LL m)
     40 
     41 {
     42 
     43     LL ans=0;
     44 
     45     a%=m;
     46 
     47     while(b)
     48 
     49     {
     50 
     51         if(b&1)
     52 
     53         {
     54 
     55             ans=(ans+a)%m;
     56 
     57             b--;
     58 
     59         }
     60 
     61         b>>=1;
     62 
     63         a=(a+a)%m;
     64 
     65     }
     66 
     67     return ans;
     68 
     69 }
     70 
     71  
     72 
     73 LL quick_mod(LL a,LL b,LL m)
     74 
     75 {
     76 
     77     LL ans=1;
     78 
     79     a%=m;
     80 
     81     while(b)
     82 
     83     {
     84 
     85         if(b&1)
     86 
     87         {
     88 
     89             ans=multi(ans,a,m);
     90 
     91             b--;
     92 
     93         }
     94 
     95         b>>=1;
     96 
     97         a=multi(a,a,m);
     98 
     99     }
    100 
    101     return ans;
    102 
    103 }
    104 
    105  
    106 
    107 bool Miller_Rabin(LL n)
    108 
    109 {
    110 
    111     if(n==2) return true;
    112 
    113     if(n<2||!(n&1)) return false;
    114 
    115     LL m=n-1;
    116 
    117     int k=0;
    118 
    119     while(!(m&1))
    120 
    121     {
    122 
    123         k++;
    124 
    125         m>>=1;
    126 
    127     }
    128 
    129     for(int i=0;i<times;i++)
    130 
    131     {
    132 
    133         LL a=rand()%(n-1)+1;
    134 
    135         LL x=quick_mod(a,m,n);
    136 
    137         LL y=0;
    138 
    139         for(int j=0;j<k;j++)
    140 
    141         {
    142 
    143             y=multi(x,x,n);
    144 
    145             if(y==1&&x!=1&&x!=n-1) return false;
    146 
    147             x=y;
    148 
    149         }
    150 
    151         if(y!=1) return false;
    152 
    153     }
    154 
    155     return true;
    156 
    157 }
    158 
    159  
    160 
    161 LL Pollard_rho(LL n,LL c)
    162 
    163 {
    164 
    165     LL i=1,k=2;
    166 
    167     LL x=rand()%(n-1)+1;
    168 
    169     LL y=x;
    170 
    171     while(true)
    172 
    173     {
    174 
    175         i++;
    176 
    177         x=(multi(x,x,n)+c)%n;
    178 
    179         LL d=gcd((y-x+n)%n,n);
    180 
    181         if(1<d&&d<n) return d;
    182 
    183         if(y==x) return n;
    184 
    185         if(i==k)
    186 
    187         {
    188 
    189             y=x;
    190 
    191             k<<=1;
    192 
    193         }
    194 
    195     }
    196 
    197 }
    198 
    199  
    200 
    201 void Find(LL n,LL c)
    202 
    203 {
    204 
    205     if(n==1) return ;
    206 
    207     if(Miller_Rabin(n))
    208 
    209     {
    210 
    211         fac[ct++]=n;
    212 
    213         return ;
    214 
    215     }
    216 
    217     LL p=n;
    218 
    219     LL k=c;
    220 
    221     while(p>=n) p=Pollard_rho(p,c--);
    222 
    223     Find(p,k);
    224 
    225     Find(n/p,k);
    226 
    227 }
    228 
    229  
    230 
    231 void dfs(LL dept,LL product)
    232 
    233 {//dept为递归深度,product为其中一个因子
    234 
    235     if(dept==cnt)
    236 
    237     {
    238 
    239         LL a=product;
    240 
    241         LL b=key/a;
    242 
    243         if(gcd(a,b)==1)
    244 
    245         {
    246 
    247             a*=gd;
    248 
    249             b*=gd;
    250 
    251             if(a+b<mini)
    252 
    253             {
    254 
    255                 mini=a+b;
    256 
    257                 resa=a;
    258 
    259                 resb=b;
    260 
    261             }
    262 
    263         }
    264 
    265         return ;
    266 
    267     }
    268 
    269     for(int i=0;i<=num[dept];i++)
    270 
    271     {
    272 
    273         if(product>mini) return ;
    274 
    275         dfs(dept+1,product);
    276 
    277         product*=fac[dept];
    278 
    279     }
    280 
    281 }
    282 
    283  
    284 
    285  
    286 
    287 void Solve(LL n)
    288 
    289 {
    290 
    291     ct=0;
    292 
    293     Find(n,120);
    294 
    295     sort(fac,fac+ct);
    296 
    297     num[0]=1;
    298 
    299     int k=1;
    300 
    301     for(int i=1;i<ct;i++)
    302 
    303     {
    304 
    305         if(fac[i]==fac[i-1])
    306 
    307             num[k-1]++;
    308 
    309         else
    310 
    311         {
    312 
    313             num[k]=1;
    314 
    315             fac[k++]=fac[i];
    316 
    317         }
    318 
    319     }
    320 
    321     cnt=k;
    322 
    323     dfs(0,1);
    324 
    325     if(resa>resb) swap(resa,resb);
    326 
    327 }
    328 
    329  
    330 
    331 int main()
    332 
    333 {
    334 
    335     while(cin>>gd>>lm)
    336 
    337     {
    338 
    339         if(gd==lm)
    340 
    341         {
    342 
    343             printf("%llu %llu
    ",gd,lm);
    344 
    345             continue;
    346 
    347         }
    348 
    349         mini=INF;
    350 
    351         key=lm/gd;
    352 
    353         Solve(key);
    354 
    355         printf("%llu %llu
    ",resa,resb);
    356 
    357     }
    358 
    359     return 0;
    360 
    361 }
    View Code
  • 相关阅读:
    记录一次性能优化(转)
    Java线程池使用说明
    Spring AOP: Spring之面向方面编程
    hibernate 联合主键生成机制(组合主键XML配置方式)
    Hibernate配置文件hbm主键的generator可选项
    关于spring-mvc的InitBinder注解的参数
    Quartzs -- Quartz.properties 配置
    开源调度框架Quartz最佳实践
    Windows系统上如何使用SSH
    导入DEM数据到ArcGIS
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/12667940.html
Copyright © 2011-2022 走看看