【Pollard-rho算法】【DFS】poj2429 GCD & LCM Inverse
2017-10-29 18:48
495 查看
题意:给你一两个数m和n,它们分别是某对数A,B的gcd和lcm,让你求出一对使得A+B最小的A,B。
n/m的所有质因子中,一定有一部分是只在A中的,另一部分是只在B中的。
于是对n/m质因子分解后,dfs枚举在A中的质因子是哪些,在B中的是哪些,然后尝试更新答案即可。(因为相等的质因子只可能同时在A中或者在B中,而long long内的数不同的质因子数不超过14个)
注意特判n==m的情况。
n/m的所有质因子中,一定有一部分是只在A中的,另一部分是只在B中的。
于是对n/m质因子分解后,dfs枚举在A中的质因子是哪些,在B中的是哪些,然后尝试更新答案即可。(因为相等的质因子只可能同时在A中或者在B中,而long long内的数不同的质因子数不超过14个)
注意特判n==m的情况。
#include<algorithm> #include<cstdio> #include<cstdlib> #define N 5500 using namespace std; typedef long long ll; ll ct,cnt; ll fac ,num ,fac2 ; const int BASE[]={2,3,5,7,11,13,17,19,23}; ll Quick_Mul(ll a,ll p,ll MOD) { if(!p){ return 0; } ll ans=Quick_Mul(a,p>>1,MOD); ans=(ans+ans)%MOD; if((p&1ll)==1ll){ ans=ans+a%MOD%MOD; } return ans; } ll Quick_Pow(ll a,ll p,ll MOD) { if(!p){ return 1; } ll ans=Quick_Pow(a,p>>1,MOD); ans=Quick_Mul(ans,ans,MOD); if((p&1ll)==1ll){ ans=a%MOD*ans%MOD; } return ans; } bool test(ll n,ll a,ll d){ if(n==2){ return 1; } if(n==a){ return 0; } if(!(n&1)){ return 0; } while(!(d&1ll)){ d>>=1; } ll t=Quick_Pow(a,d,n); if(t==1){ return 1; } while(d!=n-1ll && t!=n-1ll && t!=1ll){ t=Quick_Mul(t,t,n); d<<=1; } return t==n-1ll; } bool Miller_Rabin(ll n){ if(n==1 || n==3825123056546413051ll){ return 0; } for(int i=0;i<9;++i){ if(n==(ll)BASE[i]){ return 1; } if(!test(n,(ll)BASE[i],n-1ll)){ return 0; } } return 1; } ll pollard_rho(ll n,ll c){ ll i=1,k=2; ll x=rand()%(n-1)+1; ll y=x; while(1){ i++; x=(Quick_Mul(x,x,n)+c)%n; ll d=__gcd((y-x+n)%n,n); if(1ll<d &&d<n){ return d; } if(y==x){ return n; } if(i==k){ y=x; k<<=1; } } } void find(ll n,int c){ if(n==1){ return; } if(Miller_Rabin(n)){ fac[ct++]=n; return; } ll p=n; ll k=c; while(p>=n){ p=pollard_rho(p,c--); } find(p,k); find(n/p,k); } ll n,m,A,B,ans; void dfs(int cur,ll now){ if(now*m+n/now<ans){ ans=now*m+n/now; A=now*m; B=n/now; } for(int i=cur;i<cnt;++i){ dfs(i+1,now*fac2[i]); } } int main(){ srand(233); while(scanf("%lld%lld",&m,&n)!=EOF){ if(m==n){ printf("%lld %lld\n",m,n); continue; } ans=9000000000000000000ll; ct=0; find(n/m,120); sort(fac,fac+ct); num[0]=1; int k=1; for(int i=1;i<ct;++i){ if(fac[i]==fac[i-1]){ ++num[k-1]; } else{ num[k]=1; fac[k++]=fac[i]; } } cnt=k; for(int i=0;i<cnt;++i){ fac2[i]=1; for(int j=0;j<num[i];++j){ fac2[i]*=fac[i]; } } dfs(0,1); printf("%lld %lld\n",min(A,B),max(A,B)); } return 0; }
相关文章推荐
- GCD & LCM Inverse POJ - 2429(Pollard rho整数分解+dfs)
- 【POJ2429】GCD & LCM Inverse-Pollard-rho分解+枚举
- POJ 2429 GCD & LCM Inverse(Pollard_Rho+dfs)
- <模板>(Miller-Rabin和Pollard_rho算法)poj 2429 GCD & LCM Inverse (数论)
- POJ 2429 GCD & LCM Inverse (Pollard rho整数分解+dfs枚举)
- GCD & LCM Inverse POJ - 2429 Pollard_rho大数因子分解
- POJ 2429 GCD & LCM Inverse(素数判定Miller-Rabin+素因子分解Pollard-rho)
- POJ2429_GCD & LCM Inverse【Miller Rabin素数測试】【Pollar Rho整数分解】
- POJ 2429 GCD & LCM Inverse Pollard Rho大数分解法
- POJ 2429 GCD&LCM Inverse [pollard_rho]【数论】
- POJ 2429 GCD & LCM Inverse(Pollard-rho 大整数分解+DFS)
- poj2429 GCD & LCM Inverse 因数分解pollard_rho算法
- POJ 2429 GCD & LCM Inverse(Pollard_rho法质因数分解)
- POJ2429_GCD & LCM Inverse【Miller Rabin素数测试】【Pollar Rho整数分解】
- poj 2429 GCD & LCM Inverse(拉宾米勒测试+大数分解+dfs)
- poj 2429 GCD & LCM Inverse(Miller_rabin 测试+pollard_rho大数分解)
- POJ:2429-GCD & LCM Inverse(素数判断神题)(Millar-Rabin素性判断和Pollard-rho因子分解)
- POJ 2429 GCD & LCM Inverse ★(pollard-ρ && DFS枚举)
- SCU 2016 GCD & LCM Inverse(素性测试+DFS)
- POJ2429 - GCD & LCM Inverse(Miller–Rabin+Pollard's rho)