【BZOJ2299】向量(HAOI2011)-裴蜀定理

测试地址:向量
做法:本题需要用到裴蜀定理。
注意到题目中给的 8 8 个向量,实际上只有4对,每对互为相反向量,那么有:
A(a,b)+B(b,a)+C(a,b)+D(b,a)=(x,y) A ( a , b ) + B ( b , a ) + C ( − a , b ) + D ( − b , a ) = ( x , y )
这个方程当且仅当有一组 A,B,C,D A , B , C , D 均为整数的解时成立。
把横纵坐标拆开,得到由下面两个方程得到的方程组:
Aa+BbCaDb=x A a + B b − C a − D b = x
Ab+Ba+Cb+Da=y A b + B a + C b + D a = y
尝试消去 A A ,得到一个方程:
(b2a2)B2abC(a2+b2)D=bxay
根据裴蜀定理,该方程有一组整数解当且仅当 gcd(a2b2,a2+b2,2ab)|bxay gcd ( a 2 − b 2 , a 2 + b 2 , 2 a b ) | b x − a y
用类似的思路消去 B,C,D B , C , D ,和上面一个方程合起来得到 4 4 个方程,显然这4个方程组成的方程组和原方程组等价,那么新方程组有整数解的条件也就是原方程组有整数解的条件,于是我们就得到了 4 4 <script type="math/tex" id="MathJax-Element-1304">4</script>个条件,当且仅当这四个条件都满足时原方程组有整数解,否则就没有整数解。
(据说这题提高难度……不会做的我是不是废了T_T)
以下是本人代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int T;
ll a,b,x,y;

ll gcd(ll a,ll b)
{
    if (a<0) a=-a;
    if (b<0) b=-b;
    return b?gcd(b,a%b):a;
}

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lld%lld%lld%lld",&a,&b,&x,&y);
        ll d=gcd(gcd(a*a-b*b,a*a+b*b),2*a*b);
        if (abs(a*x-b*y)%d!=0) {printf("N\n");continue;}
        if (abs(b*x-a*y)%d!=0) {printf("N\n");continue;}
        if (abs(a*x+b*y)%d!=0) {printf("N\n");continue;}
        if (abs(b*x+a*y)%d!=0) {printf("N\n");continue;}
        printf("Y\n");
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值