[HAOI2011 ]向量
只有四个向量有意义,(a,b),(a,-b),(b,a),(b,-a)。
很自然地列出式子。
A(a,b) + B(a,-b) + C(b,a) + D(b,-a) = (P,Q)
(A+B)a + (C+D)b = P
(C -D)a + (A- B)b = Q
上扩欧。
x1 = A + B,y1 = C + D
x2 = C - D,y2 = A - B
当 x1+y2 和 x2 + y1 均为偶数时,有解。
另因为扩欧求得只是一组解,且奇偶性不同仅在相邻解。
因此判断四组即可。
1:原解。
2:P式相邻解和Q式原解。
3:P式原解和Q式相邻解。
4:两式均相邻解。
说明:相邻解一词由我创造,可意会。
// q.c
// 原来我一直学了假的exgcd...原来我一直写了错的exgcd...
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long LL;
void exgcd(LL a,LL b,LL &d,LL &x,LL &y) {
if(!b) d=a,x=1,y=0;
else exgcd(b,a%b,d,y,x),y-=a/b*x; // woc,y-=x*a/b就错了?目测不会溢出啊...至少对于100以内的啊...
}
bool check(int x,int y) {
if(x%2==0&&y%2==0) return true;
return false;
}
int main() {
freopen("vector.in","r",stdin);
freopen("vector.out","w",stdout);
int T; scanf("%d",&T);
LL a,b,x,y,d,x1,y1,x2,y2;
while(T--) {
scanf("%lld%lld%lld%lld",&a,&b,&x,&y);
exgcd(a,b,d,x1,y1);
if(x%d||y%d) printf("N\n");
else {
a/=d,b/=d;
x/=d,y/=d;
x2=y1,y2=x1;
x1*=x,y1*=x;
x2*=y,y2*=y;
if(check(x1+x2,y1+y2)) printf("Y\n");
else if(check(x1+b+x2,y1-a+y2)) printf("Y\n");
else if(check(x1+x2-a,y1+y2+b)) printf("Y\n");
else if(check(x1+b+x2-a,y1-a+y2+b)) printf("Y\n");
else printf("N\n");
}
}
return 0;
}

浙公网安备 33010602011771号