zoukankan      html  css  js  c++  java
  • P2520 [HAOI2011]向量

    题目描述

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

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

    输入输出格式

    输入格式:

     

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

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

     

    输出格式:

     

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

     

    输入输出样例

    输入样例#1: 
    3
    2 1 3 3
    1 1 0 1
    1 0 -2 3
    输出样例#1: 
    Y
    N
    Y

    说明

    样例解释:

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

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

    Solution:

      首先,我们注意到题目中的向量实际只有4种操作:$$(a,b),(b,a),(a,-b),(b,-a)$$

      于是由题意得方程组:

      $$k(a,b)+q(b,a)+w(a,-b)+c(b,-a)=(x,y) --> (k+w)a+(q+c)b=x,(k-w)b+(q-c)a=y$$

      由裴蜀定理可得:$$a*x+b*y=c$$

      xy有整数解的充要条件是$$gcd(a,b)|c$$

      证明:令$$a=p*gcd(a,b),b=q*gcd(a,b)$$

      则原式=$$(p*x+q*y)*gcd(a,b)=c$$

      显然因为gcd(a,b)为整数,而要使xy为整数,则gcd(a,b)|c

      我们回到开始的方程组$$(k+w)a+(q+c)b=x,(k-w)b+(q-c)a=y$$

      由裴蜀定理易得:(k+w),(q+c),(k-w),(q-c)均为整数的充要条件是$$gcd(a,b)|x且gcd(a,b)|y$$

      但是注意到(k+w),(k-w)有整数解不一定k和w有整数解(q+c)和(q-c)是同理的)。此时不妨设$$(k+w)=f,(k-w)=g$$

      则$$k=(f+g)/2,w=(f-g)/2$$

      因为$$2|(f+g)且2|(f-g)$$

      显然要使$k$和$w$均为整数则$f$和$g$均为偶数或均为奇数($(q+c)$和$(q-c)$同理)。

      于是我们考虑这四种情况:

      1、当$(k+w),(k-w),(q+c),(q-c)$均为偶数时,$(k+w)a+(q+c)b=x$ 提公因数$2$结合 $gcd(a,b)|x  -->gcd(a,b)*2|x$ 同理 $gcd(a,b)*2|y$

      2、当$(k+w),(k-w)$为偶数,$(q+c),(q-c)$为奇数时,$(k+w)a+(q+c)b=x$先左右两边同加$b$,再提公因数$2$结合 $gcd(a,b)|x-->gcd(a,b)*2|x+b$ 同理$gcd(a,b)*2|y+a$

      3、当$(k+w),(k-w)$为奇数,$(q+c),(q-c)$为偶数时,$(k+w)a+(q+c)b=x$先左右两边同加$a$,再提公因数$2$结合$gcd(a,b)|x-->gcd(a,b)*2|x+a$ 同理$gcd(a,b)*2|y+b$

      4、当$(k+w),(k-w),(q+c),(q-c)$均为奇数时,$(k+w)a+(q+c)b=x$先左右两边同加$a+b$,再提公因数$2$结合$gcd(a,b)|x-->gcd(a,b)*2|x+a+b$同理 $gcd(a,b)*2|y+a+b$

      只要满足上述的任意一种情况,则说明本题$k,w,q,c$有整数解,说明可行,否则说明无解。

    代码:

    #include<bits/stdc++.h>
    #define il inline
    #define ll long long
    #define debug printf("%d %s
    ",__LINE__,__FUNCTION__)
    using namespace std;
    ll t,a,b,x,y,k;
    il int gi()
    {
        ll a=0;char x=getchar();bool f=0;
        while((x<'0'||x>'9')&&x!='-')x=getchar();
        if(x=='-')x=getchar(),f=1;
        while(x>='0'&&x<='9')a=a*10+x-48,x=getchar();
        return f?-a:a;
    }
    il ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    il bool check(ll x,ll y){return x%k==0&&y%k==0;}
    int main()
    {
        t=gi();
        while(t--){
            a=gi(),b=gi(),x=gi(),y=gi();
            k=gcd(a,b)*2;
            if(check(x,y)||check(x+a,y+b)||check(x+b,y+a)||check(x+a+b,y+a+b))printf("YE5
    ");
            else printf("N0
    ");
        }
        return 0;
    }
  • 相关阅读:
    一些特殊的矩阵快速幂 hdu5950 hdu3369 hdu 3483
    HDU
    UVA-796 Critical Links 找桥
    HDU 4612 Warm up
    2017 ICPC乌鲁木齐 A Coins 概率dp
    HDU6223 Infinite Fraction Path bfs+剪枝
    Java基础知识学习(一)
    算法(一)
    面试题整理:SQL(二)
    面试题整理:SQL(一)
  • 原文地址:https://www.cnblogs.com/five20/p/8427795.html
Copyright © 2011-2022 走看看