您的位置:首页 > 其它

[BZOJ2299][HAOI2011]向量(数论)

2017-03-02 16:03 337 查看

题目描述

传送门

题解

由裴蜀定理,若(a,b)=d,那么任何ax+by都是d的倍数

也就是说如果(a,b)|n的话,ax+by=n一定存在一组合法解

这题的瓶颈在于a,b必须配对

设用了k1个向量(a,b),用了k2个向量(b,a),这里的k1和k2是代数和,也就是说,如果用了2个(a,b)和1个(-a,-b),相当于用了1个(a,b)

k1(a,b)+k2(b,a)=(x,y)->k1a+k2b=x,k1b+k2a=y

可以看出,如果(a,b)能整除x和y的话,这两个式子一定分别存在一组合法解,但是如果要求这两个合法解的两个数交换相等就不行了

我们不一定要求两个式子的k1,k2分别是一样的,只要求它们的奇偶性相同。因为只要奇偶性相同,就可以用正负代数和等于0的方法凑出一样的个数来

那么可以将a,b扩大2倍求(a,b),保证2k1,2k2是偶数,然后再手动枚举变成奇数的情况

因为这里有各种0的情况,所以我写了一坨特判

代码

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define LL long long
#define Abs(x) ((x>0)?x:-x)

int T;
LL a,b,x,y,t;

LL gcd(LL a,LL b)
{
if (!b) return a;
else return gcd(b,a%b);
}
int main()
{
scanf("%d",&T);
while (T--)
{
scanf("%lld%lld%lld%lld",&a,&b,&x,&y);
a=Abs(a),b=Abs(b),x=Abs(x),y=Abs(y);
if (!a&&!b)
{
if (!x&&!y) puts("Y");
else puts("N");
continue;
}
if (!a&&b)
{
if (x%b==0&&y%b==0) puts("Y");
else puts("N");
continue;
}
if (!b&&a)
{
if (x%a==0&&y%a==0) puts("Y");
else puts("N");
continue;
}
if (!x&&y||!y&&x)
{
puts("N");
continue;
}
t=gcd(2*a,2*b);
if (x%t==0&&y%t==0||(x+a)%t==0&&(y+b)%t==0||(x+b)%t==0&&(y+a)%t==0||(x+a+b)%t==0&&(y+a+b)%t==0) puts("Y");
else puts("N");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: