题目描述
题解
由裴蜀定理,若(a,b)=d,那么任何ax+by都是d的倍数
也就是说如果(a,b)|n的话,ax+by=n一定存在一组合法解
这题的瓶颈在于a,b必须配对
设用了k1个向量(a,b),用了k2个向量(b,a),这里的k1和k2是代数和,也就是说,如果用了2个(a,b)和1个(-a,-b),相当于用了1个(a,b)
k1(a,b)+k2(b,a)=(x,y)->k1a+k2b=x,k1b+k2a=y
可以看出,如果(a,b)能整除x和y的话,这两个式子一定分别存在一组合法解,但是如果要求这两个合法解的两个数交换相等就不行了
我们不一定要求两个式子的k1,k2分别是一样的,只要求它们的奇偶性相同。因为只要奇偶性相同,就可以用正负代数和等于0的方法凑出一样的个数来
那么可以将a,b扩大2倍求(a,b),保证2k1,2k2是偶数,然后再手动枚举变成奇数的情况
因为这里有各种0的情况,所以我写了一坨特判
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define LL long long
#define Abs(x) ((x>0)?x:-x)
int T;
LL a,b,x,y,t;
LL gcd(LL a,LL b)
{
if (!b) return a;
else return gcd(b,a%b);
}
int main()
{
scanf("%d",&T);
while (T--)
{
scanf("%lld%lld%lld%lld",&a,&b,&x,&y);
a=Abs(a),b=Abs(b),x=Abs(x),y=Abs(y);
if (!a&&!b)
{
if (!x&&!y) puts("Y");
else puts("N");
continue;
}
if (!a&&b)
{
if (x%b==0&&y%b==0) puts("Y");
else puts("N");
continue;
}
if (!b&&a)
{
if (x%a==0&&y%a==0) puts("Y");
else puts("N");
continue;
}
if (!x&&y||!y&&x)
{
puts("N");
continue;
}
t=gcd(2*a,2*b);
if (x%t==0&&y%t==0||(x+a)%t==0&&(y+b)%t==0||(x+b)%t==0&&(y+a)%t==0||(x+a+b)%t==0&&(y+a+b)%t==0) puts("Y");
else puts("N");
}
}