开始闲的无聊特判gcd=1的情况 特判错了 真是呵呵诶、
我的做法 比较挫、、首先肯定对gcd 还有 lcm进行质因数Poll分解。
我是用map记录每个因子和出现次数。然后合并两个map所有质数,就是用merge、然后DFS下、、去得到的value里面 使得 value^<=gcd *lcm的最大value赋值给a即可。。b= gcd * lcm /a;
#include <cstdio>
#include <cstring>
#include <map>
#include <iterator>
#include <ctime>
#include <cstdlib>
using namespace std;
#define S 5
typedef long long LL;
map<LL, int>mp[2];
LL gcd, lcm, ans, tot;
LL factor[3000];
LL mods(LL x, LL y, LL n){
x %= n;
y %= n;
LL tmp = 0;
while(y){
if(y & 1)
tmp = (tmp + x) % n;
x = (x << 1) % n;
y >>= 1;
}
return tmp;
}
LL pow(LL x, LL y, LL n){
x %= n;
LL tmp = 1;
while(y){
if(y & 1)tmp = mods(tmp, x, n);
x = mods(x, x, n);
y >>= 1;
}
return tmp;
}
LL pow(LL x, LL y){
LL tmp = 1;
while(y){
if(y & 1)tmp *= x;
x *= x;
y >>=1;
}
return tmp;
}
int judge(LL tmp, LL n, LL m, LL cnt){
LL v = pow(tmp, m, n);
LL last = v;
for(LL i = 1; i <= cnt; i++){
v = mods(v, v, n);
if(v == 1){
if(last != 1 && last != n-1)
return 0;
}
last = v;
}
if(v == 1)return 1;
return 0;
}
int miller_rubin(LL n){
LL m = n - 1;
LL cnt = 0;
while(!(m & 1)) cnt++, m >>= 1;
for(int i = 0; i < S; i++){
LL tmp = (rand() % (n-1)) +1;
if(!judge(tmp, n, m, cnt))
return 0;
}
return 1;
}
LL f(LL x, LL n, LL c){
return (mods(x, x, n) + c)%n;
}
LL Gcd(LL x, LL y){
return y == 0?x: Gcd(y, x % y);
}
LL poll(LL n, LL c){
if(!(n & 1))return 2;
LL x = rand() % n;
LL y = x;
LL i = 1;
LL k = 2;
while(1){
x = f(x, n, c);
LL d = Gcd(y - x + n, n);
if(d != 1 && d != n)
return d;
if(y == x)
return n;
i++;
if(i == k){
y = x;
k += k;
}
}
}
void find(LL n, int f){
if(miller_rubin(n)){
mp[f][n]++;
return;
}
LL p = n;
while(p >= n) p = poll(p, rand()%(n-1) + 1);
find(p, f);
find(n / p, f);
}
void dfs(int i, LL sum){
if(i >= tot){
if(lcm / sum >= sum / gcd)
if(sum > ans)
ans = sum;
return;
}
for(int j = 0; j < 2; j++){
dfs(i+1, sum * pow(factor[i], mp[j][factor[i]]));
}
}
int main(){
srand(time(NULL));
while(scanf("%lld%lld", &gcd, &lcm)!=EOF){
mp[0].clear();
mp[1].clear();
if( gcd == lcm){
printf("%lld %lld\n",gcd,lcm);
continue;
}
ans = 0;
tot = 0;
if(gcd != 1)
find(gcd,0);
if(lcm != 1)
find(lcm,1);
map<LL,int>::iterator it1 = mp[0].begin(), it2 = mp[1].begin();
while(it1 != mp[0].end() && it2 != mp[1].end()){
if(it1->first == it2->first){
factor[tot++] = it1->first;
++it1;
++it2;
}
else
if(it1->first > it2->first){
factor[tot++] = it2->first;
++it2;
}
else{
factor[tot++] = it1->first;
++it1;
}
}
while(it1 != mp[0].end()){
factor[tot++]=it1->first;
++it1;
}
while(it2 != mp[1].end()){
factor[tot++]=it2->first;
++it2;
}
dfs(0, 1);
printf("%lld %lld\n", ans,lcm / ans * gcd);
}
return 0;
}