給你一對數a,b,你能夠任意使用(a,b), (a,-b), (-a,b), (-a,-b), (b,a), (b,-a), (-b,a), (-b,-a)這些向量,問你能不能拼出另外一個向量(x,y)。
說明:這裏的拼就是使得你選出的向量之和爲(x,y)ios
Input
第一行數組組數t,(t<=50000)
接下來t行每行四個整數a,b,x,y (-2109<=a,b,x,y<=2109)git
Output
t行每行爲Y或者爲N,分別表示能夠拼出來,不能拼出來數組
1.考慮把八種狀況合在一塊兒,發現反向操做能夠合併,那麼操做也就是有四種(a,b),(-a,b),(b,a),(-b,a);spa
2.設四種操做進行的次數分別爲x1,x2,x3,x4,那麼:code
對橫座標的操做爲x1a-x2a+x3b-x4b,即(x1-x2)a+(x3-x4) b=x;ip
對縱座標的操做爲x1b+x2b+x3a+x4a,即(x1+x2)b+(x3+x4)a=y;get
因而咱們驗證兩方程是否有整數解便可。string
3.裴蜀定理告訴咱們:當gcd(a,b)|ans時,方程有整數解。it
考慮四個係數的奇偶性,由於四個係數是四個數的組合,因此gcd應該是原來的二倍。io
好比當x1-x2是奇數時,假設可行解中係數x1+x2爲偶數,那就不成立了,因此咱們分狀況討論以後發現,知足要求時gcd應該爲原來的二倍。
#include<iostream> #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> typedef long long ll; using namespace std; ll g; inline ll rd(){ ll x=0; bool f=0; char c=getchar(); while(!isdigit(c)){ if(c=='-')f=1; c=getchar(); } while(isdigit(c)){ x=(x<<1)+(x<<3)+(c^48); c=getchar(); } return f?-x:x; } ll gcd(ll x,ll y){return y?gcd(y,x%y):x;} bool valid(ll x,ll y){return (!(x%g))&&(!(y%g));} int main(){ ll t=rd(); while(t--){ ll a=rd(),b=rd(); ll x=rd(),y=rd(); g=gcd(a,b)<<1; printf((valid(x,y)||valid(x+a,y+b)||valid(x+b,y+a)||valid(x+a+b,y+a+b))?"Y\n":"N\n"); } return 0; }