1. 程式人生 > >HDU - 5974 A Simple Math Problem (數論 GCD)

HDU - 5974 A Simple Math Problem (數論 GCD)

大於 case simple problem pan nbsp 因子 script not

題目描述:


Given two positive integers a and b,find suitable X and Y to meet the conditions:
X+Y=a
Least Common Multiple (X, Y) =b

Input

Input includes multiple sets of test data.Each test data occupies one line,including two positive integers a(1≤a≤2*10^4),b(1≤b≤10^9),and their meanings are shown in the description.Contains most of the 12W test cases.Output For each set of input data,output a line of two integers,representing X, Y.If you cannot find such X and Y,output one line of "No Solution"(without quotation).

Sample Input

6 8
798 10780

Sample Output

No Solution
308 490

題目大意:給定正整數a,b;求兩個正整數 x,y,使得 x + y == a && LCM(x,y) == b, 如果找不到則輸出No solution.

題解:由於test case 和 a,b規模都很大,不能使用暴力,必然是通過數學方法直接求解。

不妨設x = ki, y = kj; gcd(x,y) = k

易知 i,j互質 (如果不互質則gcd必然大於k)

gcd(a,b) = gcd( k*(i+j) , k*(i*j) )

由於i,j互質,則(i+j)和 (i*j)必然互質,證明如下:

對於i的任意因子p(1除外),i % p = 0, (i*j) % p = 0

(i+j) % p = (i%p + j%p) % p = j%p, 由於i,j互質則p必然不是j的因子,所以 p 不是 (i+j) 的因子

所以對於i的所有因子(1除外)i+j都沒有,但i*j都有;同理對於j的所有因子(1除外),i+j也沒有,但i*j都有

所以i*j的所有因子(1除外),i+j都沒有 即 (i+j) , (i*j) 互質

我們可以得出以下結論:

(1)如果 i,j互質,那麽i 和(i+j) 互質,j和(i+j)互質

(2)如果 i,j互質,那麽(i+j) 和(i*j)互質

對於此題我們推出了gcd(a,b) = gcd(x,y) = k

原方程:LCM(x,y) = x*y / gcd(x,y) = b xy = bk = b*gcd(a,b)

又有x + y = a , a,b已知

可以把y表示成x帶入解一元二次方程;

也可以用(x-y)2 = (x + y)2 - 4xy求出x - y進而求出x和y

#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <cstdio>

using namespace std;

long long gcd(long long a,long long b)
{
    return a == 0 ? b : gcd(b % a, a);
}
int main()
{
    long long a,b;
    ios::sync_with_stdio(false);
    while(cin>>a>>b)
    {
        long long c = gcd(a,b);
        long long xy = c*b;
        long long t = a*a-4*xy;
        long long t1 = sqrt(t);
        long long x = (t1+a)/2;
        long long y = (a-x);
        if((x/gcd(x,y)*y!=b))
        {
            cout<<"No Solution"<<endl;
            continue;
        }
        if(x<y)
        {
            cout<<x<<" "<<y<<endl;
        }
        else
        {
            cout<<y<<" "<<x<<endl;
        }
    }
    return 0;
}

HDU - 5974 A Simple Math Problem (數論 GCD)