[haoi2011]向量

Posted Shadow

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[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 Format
第一行数组组数t,(t<=50000)
接下来t行每行四个整数a,b,x,y (-2*10^9<=a,b,x,y<=2*10^9)

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

样例输入 Sample Input
3
2 1 3 3
1 1 0 1
1 0 -2 3

样例输出 Sample Output
Y
N
Y

时间限制 Time Limitation
1s 

注释 Hint
样例解释:
第一组:(2,1)+(1,2)=(3,3)
第三组:(-1,0)+(-1,0)+(0,1)+(0,1)+(0,1)=(-2,3)

来源 Source
haoi2011 

        思路:这个题就是一个真正的数学题哇........题目中说道你可以任意使用(a,b), (a,-b), (-a,b), (-a,-b), (b,a), (b,-a), (-b,a), (-b,-a),看似有很多情况。其实你列下来可以得到一个方程。因为可以设(x,y)=A(a,b)+B(a,-b)+C(b,a)+D(b,-a);A,B,C,D这四个系数的式子就可以表示所有情况了//好好想一下。然后把这个式子拆成两个方程

   ①x=a(A+B)+b(C+D)

   ②y=a(C-D)+b(A+B);//去括号然后合并同类项,相信大家都会吧

   然后要想使这个向量(a,b)变成(x,y)那么一定要满足这两个方程有解吧。所以先特判一下a=0或b=0这两种情况。然后求出gcd(a,b);因为要是这两个方程有解那么就一定要满足x%(gcd(a,b))==0和y%(gcd(a,b))==0这两个情况。然后你保证了方程①和②有解的情况下你并不能保证①+②有解。所以①加②就可以化为

     ③x+y=a(A+B)+b(C+D)+a(C-D)+b(A-B);

      x+y=A(a+b)+B(a-b)+C(a+b)+D(b-a)

              x+y=(A+C)*(a+b)+(B-D)*(a-b)

    //这应该也是很好理解的吧

  然后你只需保证这个方程有解即可,及为(x+y)%(a+b)==0&&(x+y)%(a-b)==0。那么这个向量(a,b),就可以变成(x,y);

  代码如下:

技术分享
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<cstring>
 6 #define ll long long
 7 using namespace std;
 8 inline ll read()
 9 {
10     char ch=getchar();
11     ll x=0,f=1;
12     while(ch>9||ch<0)
13     {
14         if(ch==-)
15             f=-1;
16         ch=getchar();
17     }
18     while(ch>=0&&ch<=9)
19     {
20         x=x*10+ch-0;
21         ch=getchar();
22     }
23     return x*f;
24 }
25 ll gcd(ll a,ll b)
26 {return b==0?a:gcd(b,a%b);}
27 int main()
28 {
29     int t=read();
30     for(int i=1;i<=t;i++)
31     {
32         ll a=read(),b=read(),x=read(),y=read();
33         a=abs(a);b=abs(b);
34         if(!a)
35         {
36             if(x%b==0&&y%b==0)
37                 cout<<Y<<endl;
38             else 
39                 cout<<N<<endl;
40         }
41         else if(!b)
42         {
43             if(x%a==0&&y%a==0)
44                 cout<<Y<<endl;
45             else
46                 cout<<N<<endl;
47         }
48         else
49         {
50             ll h=gcd(a,b);
51             if(x%h==0&&y%h==0)
52             {
53                 ll g=gcd(a-b,a+b);
54                 if(abs(x+y)%g==0)
55                     cout<<Y<<endl;
56                 else
57                     cout<<N<<endl;
58             }
59             else
60                 cout<<N<<endl;
61         }
62     }
63     return 0;
64 }
 ̄へ ̄

 

以上是关于[haoi2011]向量的主要内容,如果未能解决你的问题,请参考以下文章

[haoi2011]向量

裴蜀定理 BZOJ2299[HAOI2011] 向量

[HAOI 2011]向量

[BZOJ 2299][HAOI 2011]向量 题解(裴蜀定理)

[HAOI2011]向量

HAOI2011 向量