题意:给定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 ",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 ",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 ",s1,s2); 85 if(s1+s2==0) printf("No Solution "); 86 else 87 { 88 if(s1>s2) swap(s1,s2); 89 printf("%I64d %I64d ",s1,s2); 90 } 91 92 } 93 94 }