【bzoj2299向量】一道数学题。

只有胎教数学水平的数学蒟蒻。  

2299: [HAOI2011]向量

Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 1768  Solved: 837 [Submit][Status][Discuss]

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  (-2109<=a,b,x,y<=2109)

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

通过这样稍微演变一下,发现其实真正有用的只有(a,b) , (a,-b);(b,a),(b,-a)四组向量而已(别的向量再未知数哪里直接乘一个-1就可以了). 而我们发现前两组和后两组是分别独立的不受影响的。而我们若将前两组变化后得到的向量为(ax,by),后两组(bu,av),这样我们得到一个方程组ax + bu =X  by + av =Y  由于一组内的变化是肯定受到约束的。以前两组为例,其可变出(2a,0),(a,-b),(a,b),(0,2b),之后所有的变换都是在这个基础上进行变换。会观察发现,由于初始向量的系数都是1,他们在变换之后他们之间奇偶性是始终相同的。那么我们得到一组约束条件 (x-y)%2 == 0 同理 (u-v)%2 == 0 然而我们很想他们四个未知数之间没有约束条件,那么就可以利用GCD直接判断了。如果我们枚举这四个未知数的奇偶性(0,0,0,0) (1,1,0,0) (0,0,1,1) (1,1,1,1)(0偶1奇).这样就可以消除彼此之间的约束性,就可以一心一意地判断是否有解了。如果我们再转化,将x,u全部变为偶数,那么如果a,b对应的x,u会存在有解,那么一定有2a,2b对应的有解。所以我们判断2a,2b是否有解就行。 例如:我们枚举到x为奇数,u为偶数,那么:ax + bu == X  --&gt; a(x+1) + bu == X+a 由于x+1为偶,u为偶,那么如果原式子有解,那么用(2ax+2by)解的话,也一定有解,且一定对应。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
 
using namespace std;
typedef long long LL;
int gcd(int a,int b) {
    return (!b)?a:gcd(b,a%b);
}
LL d;
bool ok(LL a,LL b) {
    return ( !(a%d) ) && ( !(b%d) );
}
int main() {
    int t; scanf("%d",&t);
    while(t--) {
        LL a,b,x,y; scanf("%lld%lld%lld%lld",&a,&b,&x,&y);
        d = gcd(a*2LL,b*2LL);
        if(ok(x,y)||ok(x+a,y+b)||ok(x+b,y+a)||ok(x+a+b,y+a+b)) puts("Y");
        else puts("N");
    }
}
 
posted @ 2018-10-05 00:55  Newuser233  阅读(5)  评论(0)    收藏  举报