【HDOJ5974】A Simple Math Problem(构造,解方程)

题意:给定A与B,要求构造出一组X,Y,使得X+Y=A,lcm(X,Y)=B

A<=2e4,B<=1e9

思路:A的范围较小,考虑以A为突破口

枚举A的约数k,复杂度O(sqrt(A))

设X=pk,y=qk,p与q互质

原方程转化:

(p+q)k=a     ——>p+q=a/k

pqk=b   ——>pq=b/k

p,q即为方程x^2-a/k*x+b/k=0的一组正整数解

解得p,q后X=pk,y=qk

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<string>
 4 #include<cmath>
 5 #include<iostream>
 6 #include<algorithm>
 7 #include<map>
 8 #include<set>
 9 #include<queue>
10 #include<vector>
11 using namespace std;
12 typedef long long ll;
13 typedef unsigned int uint;
14 typedef unsigned long long ull;
15 typedef pair<int,int> PII;
16 typedef vector<int> VI;
17 #define fi first
18 #define se second 
19 #define MP make_pair
20 #define N   2100000
21 #define MOD 1000000007
22 #define eps 1e-8 
23 #define pi acos(-1)
24 
25 ll A,B,s1,s2;
26 
27 int read()
28 { 
29    int v=0,f=1;
30    char c=getchar();
31    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
32    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
33    return v*f;
34 }
35 
36 ll gcd(ll x,ll y)
37 {
38     if(y==0) return x;
39     return gcd(y,x%y);
40 }
41 
42 int isok(ll k)
43 { 
44     if(A%k) return 0;
45     if(B%k) return 0;
46     ll a=1;
47     ll b=-A/k;
48     ll c=B/k;
49     ll x=b*b-a*c*4;
50     if(x<0) return 0;
51     ll delta=(long long int)(sqrt(x)+eps);
52     //printf("%lld %lld %lld %lld %lld %lld\n",a,b,c,x,delta,k);
53     if(delta*delta!=x) return 0;
54     ll t=-b+delta;
55     if(t%(a*2)) return 0;
56     ll x1=t/(a*2)*k;
57     t=-b-delta;
58     if(t%(a*2)) return 0;
59     ll x2=t/(a*2)*k;
60     //printf("%lld %lld\n",x1,x2);
61     if(x1&&x2&&gcd(x1,x2)==k)
62     {
63         if(x1>x2) swap(x1,x2);
64         s1=x1;
65         s2=x2;
66         return 1;
67     }
68     return 0;
69 }
70 
71 int main()
72 {
73    //freopen("D.in","r",stdin);
74    //freopen("D.out","w",stdout); 
75    while(scanf("%I64d%I64d",&A,&B)!=EOF)
76    {
77             s1=s2=0;
78            for(ll i=1;i<=sqrt(A+eps);i++)
79             if(A%i==0)
80          {
81              if(isok(i)) break;
82              if(isok(A/i)) break;
83          }
84         //printf("%I64d %I64d\n",s1,s2);
85         if(s1+s2==0) printf("No Solution\n");
86          else
87          {
88              if(s1>s2) swap(s1,s2);
89              printf("%I64d %I64d\n",s1,s2);
90          }
91               
92    }
93      
94 }

猜你喜欢

转载自www.cnblogs.com/myx12345/p/9747687.html