[BZOJ2299]-[HAOI2011]向量-裴蜀定理
2018-03-03 18:56
369 查看
说在前面
并没有什么想说的,但是要保持格式=w=题目
BZOJ2299传送门题面
给你一对数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)
接下来每行一组数据,包含四个整数a,b,x,y
输出格式:
对于每组数据,输出一行:
如果可以输出Y,不行则输出N
解法1
如果只用前四个向量,那么只能凑出来(u1 a,u2 b)(u1 a,u2 b)这样的向量;如果只用后四个,也只能(v1 b,v2 a)(v1 b,v2 a)这样的向量。因此,前四个向量和后四个向量 是独立的,它们互不干扰那么假设前四个的贡献是(u1 a,u2 b)(u1 a,u2 b),后四个的贡献是(v1 b,v2 a)(v1 b,v2 a),那么可以列出方程:{u1a+v1b=xu2b+v2a=y{u1a+v1b=xu2b+v2a=y,其中要求u1,u2u1,u2奇偶一致,v1,v2v1,v2奇偶一致(因为单组内a和b的个数差始终是2的倍数)
那么枚举u和v的奇偶性即可,然后用x和y减去奇数多出来的那一个,那么如果有一组偶数解u,v,那么此题有解。
不妨把x和y都除以二,那么这样限制就没有了,直接用裴蜀定理判定即可。(裴蜀:ax+by=c有解当且仅gcd(a,b)|c)
解法2
可以发现,原来的八种向量,其实可以等价于以下几种操作:对x或y,加上或减去2*a
对x或y,加上或减去2*b
x+a,y+b
x+b,y+a
而且第3,4种操作,最多用一次。(超过两次的部分可以替换成1或2操作)
于是枚举用没有用3,4操作,如果用了就减掉,之后也是裴蜀定理判断
下面是代码
两种方法其实是差不多的,代码也毫无区别#include <cstdio> #include <cstring> #include <algorithm> using namespace std ; int T ; long long a , b , x , y , d ; long long gcd( long long a , long long b ){ return !b ? a : gcd( b , a%b ) ; } bool check( long long x , long long y ){ if( x&1 || y&1 ) return false ; return ( x>>1 )%d == 0 && ( y>>1 )%d == 0 ; } int main(){ scanf( "%d" , &T ) ; while( T -- ){ scanf( "%lld%lld%lld%lld" , &a , &b , &x , &y ) ; d = gcd( a , b ) ; if( check( x-a, y-b ) || check( x-b , y-a ) || check( x , y ) || check( x-a-b , y-a-b ) ) puts( "Y" ) ; else puts( "N" ) ; } }
相关文章推荐
- bzoj 2299 [HAOI2011]向量 裴蜀定理
- [BZOJ 2299][HAOI 2011]向量 题解(裴蜀定理)
- bzoj2299 [HAOI2011]向量 结论 裴蜀定理
- BZOJ2299 [HAOI2011]向量 【裴蜀定理】
- [BZOJ2299][HAOI2011]向量(数论)
- bzoj 2299: [HAOI2011]向量 数学
- [BZOJ2299] [HAOI2011]向量
- bzoj2299 [HAOI2011]向量
- [BZOJ2299] [HAOI2011]向量
- bzoj 2299: [HAOI2011]向量
- [bzoj2299][HAOI2011]向量
- BZOJ2299 [HAOI2011]向量
- bzoj 2299: [HAOI2011]向量 (gcd+裴蜀定理)
- 【BZOJ 2299】 2299: [HAOI2011]向量 (乱搞)
- BZOJ2299: [HAOI2011]向量
- BZOJ 2299: [HAOI2011]向量
- BZOJ2299 HAOI2011向量(数论)
- BZOJ2299: [HAOI2011]向量
- 【HAOI2011】【BZOJ2299】向量
- 【BZOJ-2299】向量 裴蜀定理 + 最大公约数