测试地址:向量
做法:本题需要用到裴蜀定理。
注意到题目中给的
8
8
个向量,实际上只有对,每对互为相反向量,那么有:
A(a,b)+B(b,a)+C(−a,b)+D(−b,a)=(x,y)
A
(
a
,
b
)
+
B
(
b
,
a
)
+
C
(
−
a
,
b
)
+
D
(
−
b
,
a
)
=
(
x
,
y
)
这个方程当且仅当有一组
A,B,C,D
A
,
B
,
C
,
D
均为整数的解时成立。
把横纵坐标拆开,得到由下面两个方程得到的方程组:
Aa+Bb−Ca−Db=x
A
a
+
B
b
−
C
a
−
D
b
=
x
Ab+Ba+Cb+Da=y
A
b
+
B
a
+
C
b
+
D
a
=
y
尝试消去
A
A
,得到一个方程:
根据裴蜀定理,该方程有一组整数解当且仅当
gcd(a2−b2,a2+b2,2ab)|bx−ay
gcd
(
a
2
−
b
2
,
a
2
+
b
2
,
2
a
b
)
|
b
x
−
a
y
。
用类似的思路消去
B,C,D
B
,
C
,
D
,和上面一个方程合起来得到
4
4
个方程,显然这个方程组成的方程组和原方程组等价,那么新方程组有整数解的条件也就是原方程组有整数解的条件,于是我们就得到了
4
4
<script type="math/tex" id="MathJax-Element-1304">4</script>个条件,当且仅当这四个条件都满足时原方程组有整数解,否则就没有整数解。
(据说这题提高难度……不会做的我是不是废了T_T)
以下是本人代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int T;
ll a,b,x,y;
ll gcd(ll a,ll b)
{
if (a<0) a=-a;
if (b<0) b=-b;
return b?gcd(b,a%b):a;
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%lld%lld%lld%lld",&a,&b,&x,&y);
ll d=gcd(gcd(a*a-b*b,a*a+b*b),2*a*b);
if (abs(a*x-b*y)%d!=0) {printf("N\n");continue;}
if (abs(b*x-a*y)%d!=0) {printf("N\n");continue;}
if (abs(a*x+b*y)%d!=0) {printf("N\n");continue;}
if (abs(b*x+a*y)%d!=0) {printf("N\n");continue;}
printf("Y\n");
}
return 0;
}