HDU - 5974 A Simple Math Problem (數論 GCD)
題目描述:
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)