Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 12952 | Accepted: 2399 |
Description
Input
Output
Sample Input
3 60
Sample Output
12 15
Source
题意:
给出两个数的gcd 和lcm,让你求满足和最小的一对解
题解:
最直接的思路就肯定是进行素因子分解了,用到了pollard rho 算法(个人不懂),然后在这个算法的运行中,需要使用miller rabin 算法辅助........
使用这两个概率算法其实只是为了分解质因子,随后,进行dfs 枚举,求解满足条件的一对解
其实个人只是思路比较清楚一点,但是这两个算法还没有理解透彻,就不发表看法了....
直接使用的大神的模板...膜拜膜拜~~
这几天一直卡在这个算法的研究中,结果还是没理解清楚,不过还算是学到了点东西,比如:
1,大数的取模,为了防止中间过程溢出,可以用加法和移位来代替乘法,这一点在计算机组成原理里面刚好有涉及
2, 递归式的gcd 函数,不得不吐槽了,一般情况下确实很快,但是像这种数据比较大的情况下,竟然卡在了求gcd 的时间上(亲测递归TLE,迭代110MS AC)
一位学长说过:递归为人,迭代为神!
至于这两个概率算法,个人觉得如果如果不是专门搞研究方面的,倒不用太过于纠结,毕竟有概率失败的,如果你用去搞程序设计,在大数据的情况下,再小概率的事件都会发生,必定造成很多错误,一般来说,最主要的还应该是思维的锻炼和知识面的扩充,至少不至于对一些比较著名的方法和结论都不知道吧
好吧好吧,不扯了,个人的思想不是很成熟,大致发表一下自己的看法,需要学的东西还有很多,慢慢学吧!加油!
/* http://blog.csdn.net/liuke19950717 */ #include<stdio.h> #include<string.h> #include<stdlib.h> #include<time.h> #include<iostream> #include<cmath> #include<algorithm> using namespace std; typedef long long ll; const int S=20; ll mult_mod(ll a,ll b,ll c) { a%=c;b%=c; ll ret=0; while(b) { if(b&1) { ret+=a;ret%=c; } a<<=1; if(a>=c) a%=c; b>>=1; } return ret; } ll pow_mod(ll x,ll n,ll mod) { if(n==1)return x%mod; x%=mod; ll tmp=x; ll ret=1; while(n) { if(n&1) ret=mult_mod(ret,tmp,mod); tmp=mult_mod(tmp,tmp,mod); n>>=1; } return ret; } bool check(ll a,ll n,ll x,ll t) { ll ret=pow_mod(a,x,n); ll last=ret; for(int i=1;i<=t;i++) { ret=mult_mod(ret,ret,n); if(ret==1&&last!=1&&last!=n-1) return true; last=ret; } if(ret!=1) return true; return false; } bool Miller_Rabin(ll n) { if(n<2) return false; if(n==2) return true; if((n&1)==0) return false; ll x=n-1; ll t=0; while((x&1)==0) { x>>=1;t++; } for(int i=0;i<S;i++) { ll a=rand()%(n-1)+1; if(check(a,n,x,t)) return false; } return true; } ll factor[100]; int tol; ll gcd(ll a,ll b) { if(a==0) return 1; if(a<0) return gcd(-a,b); while(b) { ll t=a%b; a=b;b=t; } return a; } /* // 递归 TLE!!!! ll gcd(l a,ll b) { if(!b) { return a; } return gcd(b,a%b); } */ ll Pollard_rho(ll x,ll c) { ll i=1,k=2; ll x0=rand()%x; ll y=x0; while(1) { i++; x0=(mult_mod(x0,x0,x)+c)%x; ll d=gcd(y-x0,x); if(d!=1&&d!=x) return d; if(y==x0) return x; if(i==k) { y=x0;k+=k; } } } void findfac(ll n) { if(Miller_Rabin(n)) { factor[tol++]=n; return; } ll p=n; while(p>=n) { p=Pollard_rho(p,rand()%(n-1)+1); } findfac(p); findfac(n/p); } ll r[100]; int num; ll k; void dfs(ll now,int x,ll n) { if(now>sqrt(n)) { return; } k=max(k,now); for(int i=x;i<=num;i++) { dfs(now*r[i],i+1,n); } } int main() { ll gcd,lcm,n; while(scanf("%lld%lld",&gcd,&lcm)!=EOF) { if(gcd==lcm) { printf("%lld %lld\n",gcd,lcm); continue; } tol=0; n=lcm/gcd; findfac(n); sort(factor,factor+tol); num=0; for(int i=0;i<=50;i++) { r[i]=1; } r[num]=factor[0]; for(int i=1;i<tol;i++) { if(factor[i]==factor[i-1]) { r[num]=r[num]*factor[i]; } else { num++; r[num]=factor[i]; } } k=1; dfs(1,0,n); printf("%lld %lld\n",gcd*k,gcd*(n/k)); } return 0; }