POJ 2429 GCD LCM Inverse ★(pollard-ρ DFS枚举)
生活随笔
收集整理的這篇文章主要介紹了
POJ 2429 GCD LCM Inverse ★(pollard-ρ DFS枚举)
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
題目鏈接:http://poj.org/problem?id=2429 題目大意:給定gcd(a,b)和lcm(a,b)(<2^63),求a和b,如果有多種情況,輸出和最小的情況. ? 首先gcd(a,b) * lcm(a,b) = a*b,但是如果我們直接從a*b中分解因子的話,a*b是可能超過(guò)long long的,這樣就不好處理了. 我們可以先把gcd(a,b)都分給a,b,因?yàn)樗麄兊囊蜃又卸家術(shù)cd(a,b).于是現(xiàn)在還剩下lcm(a,b)/gcd(a,b)了,于是我們先用pollard-rho給他分解因子. 那么還有一個(gè)問(wèn)題,能隨便分么?分出來(lái)的a,b雖然能保證a*b,但是能保證他們的gcd和lcm都是給定的么?不一定. 所以我們還需要注意分因數(shù)的過(guò)程中還要保證gcd和lcm的正確性. 但這個(gè)問(wèn)題其實(shí)不難,因?yàn)閍*b一定是不變的,所以我們只要保證gcd和lcm其中一個(gè)不變,另一個(gè)也就自然不變了.顯然保證gcd比較簡(jiǎn)單. 我們知道lcm/gcd = p1^q1 * p2 ^q2 *……* pn^qn,其中p1,p2,……,pn是因子.我們只要保證某個(gè)數(shù)把某個(gè)pi全部取走,這樣他們除了先前取走的gcd外再無(wú)公因數(shù),則可保gcd正確.這樣的話,2^63內(nèi)的數(shù)所有不同的因子個(gè)數(shù)最多也就十幾個(gè),枚舉無(wú)壓力. ?
#include
#include
#include
using namespace std;//return a * b % m
unsigned long long mul_mod(unsigned long long a, unsigned long long b, unsigned long long m){//為了防止long long型a * b溢出,有時(shí)需要把乘法變加法//且因?yàn)楸┝臃〞?huì)超時(shí)要使用二分快速乘法模(模仿二分快速冪模……)unsigned long long res = 0, tmp = a % m;while(b){if (b & 1){res = res + tmp;res = (res >= m ? res - m : res);}b >>= 1;tmp <<= 1;tmp = (tmp >= m ? tmp - m : tmp);}return res;
}//return a ^ b % m
long long exp_mod(long long a, long long b, long long m){long long res = 1 % m, tmp = a % m;while(b){if (b & 1){//如果m在int范圍內(nèi)直接用下一式乘就可以,否則需要用下二式把乘法化加法,用快速乘法模//res = (res * t) % m;res = mul_mod(res, tmp, m);}//同上//t = t * t % m;tmp = mul_mod(tmp, tmp, m);b >>= 1;}return res;
}/*-------------Miller-Rabin 素?cái)?shù)測(cè)試 部分(用到上面mul_mod和exp_mod 素?cái)?shù)return true)--------------*/
bool Miller_Rabin(long long n){int a[5] = {2, 3, 7, 61, 24251};//一般Miller_Rabin素?cái)?shù)測(cè)試是隨機(jī)選擇100個(gè)a,這樣的錯(cuò)誤率為0.25^100//但在OI&&ACM中,可以使用上面一組a,在這組底數(shù)下,10^16內(nèi)唯一的強(qiáng)偽素?cái)?shù)為46,856,248,255,981if (n == 2)return true;if (n == 1 || (n & 1) == 0)return false;long long b = n - 1;for (int i = 0; i < 5; i ++){if (a[i] >= n)break;while((b & 1) == 0) b >>= 1;long long t = exp_mod(a[i], b, n);while(b != n - 1 && t != 1 && t != n - 1){t = mul_mod(t, t, n);b <<= 1;}if (t == n - 1 || (b & 1))continue;elsereturn false;}return true;
}
/*-------------Miller-Rabin 素?cái)?shù)測(cè)試 部分--------------*//*-------------pollard-rho 大整數(shù)n因子分解 部分(用到mul_mod()和Miller-Rabin測(cè)試)--------------*/
long long factor[100]; //存n的素因子
long long nfactor, minfactor;long long gcd(long long a, long long b){return b ? gcd(b, a%b) : a;
}
void Factor(long long n);
void pollard_rho(long long n){if (n <= 1)return ;if (Miller_Rabin(n)){factor[nfactor ++] = n;if (n < minfactor)minfactor = n;return ;}long long x = 2 % n, y = x, k = 2, i = 1;long long d = 1;while(true){i ++;x = (mul_mod(x, x, n) + 1) % n;d = gcd((y - x + n) % n, n);if (d > 1 && d < n){pollard_rho(d);pollard_rho(n/d);return ;}if (y == x){Factor(n);return ;}if (i == k){y = x;k <<= 1;}}
}
void Factor(long long n){//有時(shí)候RP不好 or n太小(比如n==4就試不出來(lái)……)用下面的pollard_rho沒(méi)弄出來(lái),則暴力枚舉特殊處理一下long long d = 2;while(n % d != 0 && d * d <= n)d ++;pollard_rho(d);pollard_rho(n/d);
}
/*-------------pollard-rho 大整數(shù)n因子分解 部分--------------*/vector > vfac;
void find(long long n, long long &a, long long &b){long long sum = (1LL << 62);long long suma;for (int i = 0; i < (1 << vfac.size()); i ++){long long res = 1;for (size_t k = 0; k < vfac.size(); k ++){if (i & (1 << k)){for (int p = 0; p < vfac[k].second; p ++){res *= vfac[k].first;}}}long long remain = n / res;if (res + remain < sum){sum = res + remain;a = suma = res;b = remain;}if (res + remain == sum){if (res < suma){a = suma = res;b = remain;}}}return ;
}
int main(){long long g, l, n;while(cin >> g >> l){n = l / g;vfac.clear();nfactor = 0;pollard_rho(n);long long tmp = n;for(int i = 0; i < nfactor; i ++){int facnum = 0;while(tmp % factor[i] == 0){tmp /= factor[i];facnum ++;}vfac.push_back(make_pair(factor[i], facnum));}long long a, b;find(n, a, b);cout << a * g << " " << b * g << endl;}return 0;
}
?
轉(zhuǎn)載于:https://www.cnblogs.com/AbandonZHANG/archive/2013/01/20/4114201.html
總結(jié)
以上是生活随笔為你收集整理的POJ 2429 GCD LCM Inverse ★(pollard-ρ DFS枚举)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 调用大漠插件5.1423
- 下一篇: Nginx工作原理和优化