[BZOJ2299] [HAOI2011]向量
2015-10-21 17:05
295 查看
[HAOI2011]向量
Description给你一对数a,b,你可以任意使用(a,b), (a,-b), (-a,b), (-a,-b), (b,a), (b,-a), (-b,a), (-b,-a)这些向量,问你能不能拼出另一个向量(x,y)。
说明:这里的拼就是使得你选出的向量之和为(x,y)
Input
第一行数组组数t,(t<=50000)
接下来t行每行四个整数a,b,x,y (-2*10^9<=a,b,x,y<=2*10^9)
Output
t行每行为Y或者为N,分别表示可以拼出来,不能拼出来
Sample Input
3
2 1 3 3
1 1 0 1
1 0 -2 3
Sample Output
Y
N
Y
HINT
样例解释:
第一组:(2,1)+(1,2)=(3,3)
第三组:(-1,0)+(-1,0)+(0,1)+(0,1)+(0,1)=(-2,3)
Solution:
首先8种向量只有四个本质不同的向量。
我们设有k1(a,b),k2(a,−b),k3(b,a),k4(b,−a)k1(a, b), k2(a, -b), k3(b, a), k4(b, -a),
那么我们有a(k1+k2)+b(k3+k4)=xa(k1+k2)+b(k3+k4)=x,a(k3−k4)+b(k1−k2)=ya(k3-k4)+b(k1-k2)=y,我们记p1=k1+k2,p2=k3+k4,p3=k3−k4,p4=k1−k2p1=k1+k2, p2=k3+k4, p3=k3-k4, p4=k1-k2,那么k1,k2,k3,k4k1,k2,k3,k4有整数解的条件是p1≡p4(mod2),p2≡p3(mod2)p1\equiv p4(mod 2),p2\equiv p3(mod 2),我们用拓展欧几里得接出p1,p2,p3,p4p1, p2, p3, p4的一组解,显然mod2mod2将每一个不定方程分为两类,一共四种情况,一一判断即可
Code :
/************************************************************************* > File Name: bzoj2299.cpp > Author: Archer ************************************************************************/ #include <bits/stdc++.h> using namespace std; typedef long long ll; inline ll read(){ ll x = 0, f = 1; char ch = getchar(); while (!isdigit(ch)) {if (ch == '-') f = -1; ch = getchar();} while (isdigit(ch)) {x = x * 10ll + ch - '0'; ch = getchar(); } return f == 1 ? x : -x; } inline void exgcd(ll a, ll &x, ll b, ll &y){ if (b == 0) {x = 1ll; y = 0ll; return;} ll x1, y1; exgcd(b, x1, a % b, y1); x = y1; y = x1 - a / b * y1; } inline ll gcd(ll a, ll b) {return b == 0 ? a : gcd(b, a % b);} inline bool check(ll p1, ll p2, ll p3, ll p4){ return (((p1-p4)%2 == 0) && ((p2-p3)%2 == 0)); } int main(){ for (ll T = read(); T--;){ ll a = read(), b = read(), x = read(), y = read(); if (a < b) swap(a, b); if (a == 0) {puts(x == 0 && y == 0 ? "Y" : "N"); continue;} ll d = gcd(a, b); ll p1, p2, p3, p4, d1 = b / d, d2 = a / d; if (x % d != 0 || y % d != 0) {puts("N"); continue;} ll t1, t2; exgcd(a / d, t1, b / d, t2); p1 = t1 * x / d; p2 = t2 * x / d; p3 = t1 * y / d; p4 = t2 * y / d; if (check(p1, p2, p3, p4) || check(p1 + d1, p2 - d2, p3, p4) ||check(p1, p2, p3 + d1, p4 - d2) || check(p1 + d1, p2 - d2, p3 + d1, p4 - d2)) puts("Y"); else puts("N"); } return 0; }
相关文章推荐
- iOS中定时器NSTimer的使用
- IO流操作的规律
- 给URL标示特别颜色
- 使用ASP.NET开发的网站,怎么把动态的页面静态化?
- bat programming is easy and powerful
- CentOS6.5中修改yum源
- oracle 中身份证号15位升18位
- 不重启的情况下清除网络共享的密码
- IOS添加计时器的两种方法
- Cpp--sizeof与strlen区别与联系
- U盘无法格式的解决办法
- Qt try catch排错历程——C++的异常对除零不起作用
- C&OC的数据类型分类
- 打印js插件
- Redis数据类型之有序集合类型--Redis系列六
- Linux的automake出现的问题(Makefile.am: C objects in subdir but `AM_PROG_CC_C_O' not in `configure.ac')
- CFileDialog会自动更改程序当前工作目录(解决方案)!
- C语言数组练习
- 使用UITabBarViewCOntroller时隐藏tabbar
- Ubuntu下usb设备读写权限设置