【BZOJ 2299】 2299: [HAOI2011]向量 (乱搞)

时间:2021-08-19 21:39:56

2299: [HAOI2011]向量

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 1255  Solved: 575

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*109<=a,b,x,y<=2*109)

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)

Source

【分析】

  目测是随便mod一下判断一下就好了的。

  看代码吧。。

  就是可以用4个向量表示完全部(2a,0)(2b,0)(a,b)(b,a)

  看出来横纵坐标是可以mod gcd(2a,2b)的。

  然后直接判断最后是不是(0,0)或者(a,b)或者(b,a)或者(a+b,a+b)什么鬼的?

  【对了乘了2记得LL

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define LL long long LL myabs(LL x) {return x>?x:-x;} LL gcd(LL a,LL b)
{
if(b==) return a;
return gcd(b,a%b);
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
LL a,b,x,y;
scanf("%lld%lld%lld%lld",&a,&b,&x,&y);
a=myabs(a);b=myabs(b);
if(a==&&b==)
{
if(x==&&y==) printf("Y\n");
else printf("N\n");
}
else if(a==||b==)
{
if(a==&&(x%b+b)%b==&&(y%b+b)%b==) printf("Y\n");
else if(b==&&(x%a+a)%a==&&(y%a+a)%a==) printf("Y\n");
else printf("N\n");
}
else
{
LL g=gcd(a,b)*;
x=(x%g+g)%g;
y=(y%g+g)%g;
if(x==&&y==) printf("Y\n");
else if(x==a%g&&y==b%g) printf("Y\n");
else if(x==b%g&&y==a%g) printf("Y\n");
else if(x==(a+b)%g&&y==(a+b)%g) printf("Y\n");
else printf("N\n"); }
}
return ;
}

2017-04-05 11:45:22


顺便放一下查到的裴蜀定理

【BZOJ 2299】 2299: [HAOI2011]向量 (乱搞)

也就是exgcd里面那个东西嘛。。没什么特别的。。