洛谷精选 - 数学专题

https://www.luogu.org/problemnew/lists?name=&orderitem=difficulty&tag=5&content=0&select=1&type=

布丁酱又来开新坑。


P2520 向量

这里的证明要用到裴蜀定理:对任意整数 $a,b$ , $ax+by=m$ 有整数解当且仅当 $m=k*gcd(a,b)$ 。

其中一个推论: $a,b$ 互质当且仅当存在 $x,y$ 使得 $ax+by=1$ ,这里好像没啥用。

每个向量和他的相反向量取其中之一就可以了,剩下的交给整系数去调节。

设 $k(a,b)+l(a,-b)+m(b,a)+n(b,-a)=(x,y)$ ,变形得 $(k+l)a+(m+n)b=x$ 且 $(k-l)b+(m-n)a=y$ 。

 

由裴蜀定理,得 $(k+l),(m+n),(k-l),(m-n)$均有整数解的充要条件是 $x=k_1*gcd(a,b)$ 且 $y=k_2*gcd(a,b)$ 。

现在要使 $k,l,m,n$ 有整数解,设 $(k+l)=z_1,(k-l)=z_2$ ,所以可以反解出 $k=\frac{z_1+z_2}{2}$ 和 $l=\frac{z_1-z_2}{2}$ 。

 

换言之, $z_1,z_2$ 要奇偶性相同才能使 $k,l$ 为整数解。同理另外两个(设为 $z_3,z_4$ )也要奇偶性才行。

上面的明显是充要条件,但是怎么求解呢?

分情况讨论:

当 $z_1,z_2,z_3,z_4$ 都是偶数时,有 $z_1a+z_3b=x,z_2a+z_4b=y$ ,再由裴蜀定理得 $x|2gcd(a,b),y|2gcd(a,b)$ 。

当 $z_1,z_2$ 都是奇数, $z_3,z_4$ 都是偶数时,有 $(z_1+1)a+z_3b=x+a,(z_2+1)b+z_4a=y+b$ ,再由裴蜀定理得 $(x+a)|2gcd(a,b),(y+b)|2gcd(a,b)$ 。

 

最后小心爆int!

#include<bits/stdc++.h>
using namespace std;
#define ll long long

void init() {
#ifdef Yinku
    freopen("Yinku.in", "r", stdin);
    freopen("Yinku.out","w",stdout);
#endif // Yinku
}

/*--------------------------------*/



void solve() {
    ll a,b,x,y;
    scanf("%lld%lld%lld%lld",&a,&b,&x,&y);
    if(a==0&&b==0) {
        if(x==0&&y==0){
            puts("Y");
            return;
        }
        else{
            puts("N");
            return;
        }
    }


    ll g2=2ll*__gcd(a,b);
    //cout<<g2<<endl;

    if((x%g2==0&&y%g2==0)||((x+a)%g2==0&&(y+b)%g2==0)||((x+b)%g2==0&&(y+a)%g2==0)||((x+a+b)%g2==0&&(y+a+b)%g2==0)){
        puts("Y");
        return;
    }
    else{
        puts("N");
        return;
    }
}
int t;
int main() {
    init();
    while(~scanf("%d",&t)) {
        while(t--) {
            solve();
        }
    }
}
View Code

 

posted @ 2019-03-10 23:10  韵意  阅读(187)  评论(0编辑  收藏  举报