扩展欧几里德 HNOI2011向量

来源:互联网 发布:跨平台网络库 编辑:程序博客网 时间:2024/06/03 18:59

很早学的知识了,完全忘了,看到道题HNOI2011向量,拿纸推了半天才发现自己太二了,完全小学生水品。 :(

想起比较简单就是造两个方程,AX0+BY0=X,AX1+BY1=Y。判断哈gcd(A,B)能不能被X,Y整除,不能就N,能就继续,因为建立的方程组的关系X0-Y1与Y0-X1必须存在一组解为偶数,而X0,X1,Y0,Y1的奇偶只与t的奇偶有关:

X=X0+b0*t,Y=Y0-a0*t;所以判断哈成功了。

#include <cstdio>#include <cmath>#include <iostream>#include <cstring>#include <cstdlib>using namespace std;typedef int LL;int T;LL a,b,x,y;LL ocgcd(LL a0,LL b0,LL &x0,LL &y0){   if (!b0){      x0=1;      y0=0;      return a0;      }   int k=ocgcd(b0,a0%b0,x0,y0),t=x0;   x0=y0;   y0=t-(a0/b0)*y0;   return k;}bool check(LL gcd,LL x1,LL x2,LL y1,LL y2){     for (int i=1;i<=2;i++)         for (int j=1;j<=2;j++){             LL s1=x1+b/gcd*i,s2=x2+b/gcd*j;             LL s3=y1-a/gcd*i,s4=y2-a/gcd*j;             if (abs(s1-s4)%2==0&&abs(s3-s2)%2==0)                return true;             }     return false;}int main(){//    freopen("2299.in","r",stdin);//    freopen("2299.out","w",stdout);    scanf("%d",&T);    while (T--){          scanf("%d%d%d%d",&a,&b,&x,&y);          a=abs(a);b=abs(b);x=abs(x);y=abs(y);          LL x0,y0;          LL gcd=ocgcd(a,b,x0,y0);          if ((x%gcd)||(y%gcd)){             printf("N\n");             continue;             }          LL x1=(x/gcd)*x0,y1=(x/gcd)*y0;          LL x2=(y/gcd)*x0,y2=(y/gcd)*y0;          if (check(gcd,x1,x2,y1,y2)) printf("Y\n");             else printf("N\n");          }     return 0;}


原创粉丝点击