洛谷精选 - 数学专题
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(); } } }