您的位置:首页 > 其它

[BZOJ2299] [HAOI2011]向量

2015-10-21 17:05 295 查看

[HAOI2011]向量

Description

给你一对数a,b,你可以任意使用(a,b), (a,-b), (-a,b), (-a,-b), (b,a), (b,-a), (-b,a), (-b,-a)这些向量,问你能不能拼出另一个向量(x,y)。

说明:这里的拼就是使得你选出的向量之和为(x,y)

Input

第一行数组组数t,(t<=50000)

接下来t行每行四个整数a,b,x,y (-2*10^9<=a,b,x,y<=2*10^9)

Output

t行每行为Y或者为N,分别表示可以拼出来,不能拼出来

Sample Input

3

2 1 3 3

1 1 0 1

1 0 -2 3

Sample Output

Y

N

Y

HINT

样例解释:

第一组:(2,1)+(1,2)=(3,3)

第三组:(-1,0)+(-1,0)+(0,1)+(0,1)+(0,1)=(-2,3)

Solution:

首先8种向量只有四个本质不同的向量。

我们设有k1(a,b),k2(a,−b),k3(b,a),k4(b,−a)k1(a, b), k2(a, -b), k3(b, a), k4(b, -a),

那么我们有a(k1+k2)+b(k3+k4)=xa(k1+k2)+b(k3+k4)=x,a(k3−k4)+b(k1−k2)=ya(k3-k4)+b(k1-k2)=y,我们记p1=k1+k2,p2=k3+k4,p3=k3−k4,p4=k1−k2p1=k1+k2, p2=k3+k4, p3=k3-k4, p4=k1-k2,那么k1,k2,k3,k4k1,k2,k3,k4有整数解的条件是p1≡p4(mod2),p2≡p3(mod2)p1\equiv p4(mod 2),p2\equiv p3(mod 2),我们用拓展欧几里得接出p1,p2,p3,p4p1, p2, p3, p4的一组解,显然mod2mod2将每一个不定方程分为两类,一共四种情况,一一判断即可

Code :

/*************************************************************************
> File Name: bzoj2299.cpp
> Author: Archer
************************************************************************/
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

inline ll read(){
ll x = 0, f = 1; char ch = getchar();
while (!isdigit(ch)) {if (ch == '-') f = -1; ch = getchar();}
while (isdigit(ch))  {x = x * 10ll + ch - '0'; ch = getchar(); }
return f == 1 ? x : -x;
}
inline void exgcd(ll a, ll &x, ll b, ll &y){
if (b == 0) {x = 1ll; y = 0ll; return;}
ll x1, y1; exgcd(b, x1, a % b, y1);
x = y1; y = x1 - a / b * y1;
}
inline ll gcd(ll a, ll b) {return b == 0 ? a : gcd(b, a % b);}
inline bool check(ll p1, ll p2, ll p3, ll p4){
return (((p1-p4)%2 == 0) && ((p2-p3)%2 == 0));
}
int main(){
for (ll T = read(); T--;){
ll a = read(), b = read(), x = read(), y = read();
if (a < b) swap(a, b);
if (a == 0) {puts(x == 0 && y == 0 ? "Y" : "N"); continue;}

ll d = gcd(a, b); ll p1, p2, p3, p4, d1 = b / d, d2 = a / d;
if (x % d != 0 || y % d != 0) {puts("N"); continue;}
ll t1, t2; exgcd(a / d, t1, b / d, t2);
p1 = t1 * x / d; p2 = t2 * x / d;
p3 = t1 * y / d; p4 = t2 * y / d;
if (check(p1, p2, p3, p4) || check(p1 + d1, p2 - d2, p3, p4)
||check(p1, p2, p3 + d1, p4 - d2) || check(p1 + d1, p2 - d2, p3 + d1, p4 - d2)) puts("Y");
else puts("N");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: