开始闲的无聊特判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; }