POJ2429 GCD & LCM Inverse (大整数分解)

来源:互联网 发布:个人知识管理系统java 编辑:程序博客网 时间:2024/06/05 22:57

题目点我点我点我


题目大意:给你两个数a,b的最大公约数和最小公倍数,求a+b最小的组合a,b。


解题思路:直接套大整数分解模版。然后DFS即可。



/* ***********************************************┆  ┏┓   ┏┓ ┆┆┏┛┻━━━┛┻┓ ┆┆┃       ┃ ┆┆┃   ━   ┃ ┆┆┃ ┳┛ ┗┳ ┃ ┆┆┃       ┃ ┆┆┃   ┻   ┃ ┆┆┗━┓ 马 ┏━┛ ┆┆  ┃ 勒 ┃  ┆      ┆  ┃ 戈 ┗━━━┓ ┆┆  ┃ 壁     ┣┓┆┆  ┃ 的草泥马  ┏┛┆┆  ┗┓┓┏━┳┓┏┛ ┆┆   ┃┫┫ ┃┫┫ ┆┆   ┗┻┛ ┗┻┛ ┆************************************************ */#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <stack>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>#include <bitset>using namespace std;#define rep(i,a,b) for (int i=(a),_ed=(b);i<=_ed;i++)#define per(i,a,b) for (int i=(b),_ed=(a);i>=_ed;i--)#define pb push_back#define mp make_pairconst int inf_int = 2e9;const long long inf_ll = 2e18;#define inf_add 0x3f3f3f3f#define mod 1000000007#define LL long long#define ULL unsigned long long#define MS0(X) memset((X), 0, sizeof((X)))#define SelfType intSelfType Gcd(SelfType p,SelfType q){return q==0?p:Gcd(q,p%q);}SelfType Pow(SelfType p,SelfType q){SelfType ans=1;while(q){if(q&1)ans=ans*p;p=p*p;q>>=1;}return ans;}#define Sd(X) int (X); scanf("%d", &X)#define Sdd(X, Y) int X, Y; scanf("%d%d", &X, &Y)#define Sddd(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)#define reunique(v) v.resize(std::unique(v.begin(), v.end()) - v.begin())#define all(a) a.begin(), a.end()typedef pair<int, int> pii;typedef pair<long long, long long> pll;typedef vector<int> vi;typedef vector<long long> vll;inline int read(){int ra,fh;char rx;rx=getchar(),ra=0,fh=1;while((rx<'0'||rx>'9')&&rx!='-')rx=getchar();if(rx=='-')fh=-1,rx=getchar();while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra*fh;}//#pragma comment(linker, "/STACK:102400000,102400000")const int Times = 10;const LL INF = (LL)1<<61;const int N = 550;LL n, m, ct, cnt;LL mini, mina,minb,ans;LL fac[N], num[N];LL gcd(LL a, LL b){    return b? gcd(b, a % b) : a;}LL multi(LL a, LL b, LL m){    LL ans = 0;    a %= m;    while(b)    {        if(b & 1)        {            ans = (ans + a) % m;            b--;        }        b >>= 1;        a = (a + a) % m;    }    return ans;}LL quick_mod(LL a, LL b, LL m){    LL ans = 1;    a %= m;    while(b)    {        if(b & 1)        {            ans = multi(ans, a, m);            b--;        }        b >>= 1;        a = multi(a, a, m);    }    return ans;}bool Miller_Rabin(LL n){    if(n == 2) return true;    if(n < 2 || !(n & 1)) return false;    LL m = n - 1;    int k = 0;    while((m & 1) == 0)    {        k++;        m >>= 1;    }    for(int i=0; i<Times; i++)    {        LL a = rand() % (n - 1) + 1;        LL x = quick_mod(a, m, n);        LL y = 0;        for(int j=0; j<k; j++)        {            y = multi(x, x, n);            if(y == 1 && x != 1 && x != n - 1) return false;            x = y;        }        if(y != 1) return false;    }    return true;}LL pollard_rho(LL n, LL c){    LL i = 1, k = 2;    LL x = rand() % (n - 1) + 1;    LL y = x;    while(true)    {        i++;        x = (multi(x, x, n) + c) % n;        LL d = gcd((y - x + n) % n, n);        if(1 < 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);}void dfs(LL dept, LL val){    if(dept == cnt)    {        LL a = val;        LL b = ans / val;        if(gcd(a,b)==1)        {            a *= n;            b *= n;            if(a+b<mini)            {                mini = a+b;                mina = a;                minb = b;            }        }        return ;    }    for(int i=0;i<=num[dept];i++)    {        if(val>mini)return;        dfs(dept + 1, val);        val *= fac[dept];    }}int main(){    while(~scanf("%I64d%I64d", &n, &m))    {        if(n == m)        {            printf("%I64d %I64d\n",n,m);            continue;        }        mini = INF;        ct = cnt = 0;        ans = m / n;        find(ans, 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;        dfs(0, 1);        if(mina>minb)swap(mina,minb);        printf("%I64d %I64d\n",mina,minb);    }    return 0;}


0 0
原创粉丝点击