Input
Output
Sample Input
3 60
Sample Output
12 15
Meaning of the questions: given the greatest common divisor and least common multiple of two numbers, allow you to find out the number two conditions are met, and to make their minimum.
answer:
For two numbers a, b, and their least common multiple and the greatest common divisor gcd lcm, there lcm = a * b / gcd, further modification can be obtained: (a / gcd * b / gcd) * gcd = lcm, i.e., (a / gcd * b / gcd) = lcm / gcd, we set m = a / gcd, n = b / gcd, then the question becomes: two integer prime to identify the product of their key = lcm / gcd. We can use the integer factorization method pollard_rho find out all prime factors of lcm / gcd then dfs find the product of any of several prime factors (set X), set y = key / x, find the minimum of x + y on the line
Code:
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 The Find (n-/ P, K); 226 227 } 228 229 230 231 void DFS (Dept LL, LL Product) 232 233 { // Dept recursive depth, product which is a factor of 234 235 IF (Dept == CNT) 236 237 { 238 239 LL A = Product; 240 241 LL Key = B / 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\n",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\n",resa,resb); 356 357 } 358 359 return 0; 360 361 }