Evanyou Blog 彩带

  题目传送门

  看到数据范围其实就可以确定这是一道结论题。

  首先分析,给定你的向量的两个坐标a,b有八种组合方式可以用,但实际上整理一下可以得出实际上只有五种,x/y ±2a,x/y ±2b,x+a,y+b,x+b,y+a,再就是什么都不做(废话。。。)

  那么要想用a,b组合出x,y,那必须满足一下条件:

  令A=2a,B=2b,d=gcd(A,B),存在i*a+j*b=x,u*a+v*b=y,并且d|x,d|y。

  (根据裴蜀定理{若a,b是整数,且gcd(a,b)=d,那么对于任意的整数x,y,ax+by都一定是d的倍数,特别地,一定存在整数x,y,使ax+by=d成立})

  那么只要下面四种情况的其中一种满足即可:

  (x,y),(x+a,y+b),(x+b,y+a),(x+a+b,y+a+b)

  代码如下:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
ll T,d;
inline ll gcd(ll a,ll b)
{return b==0?a:gcd(b,a%b);}
inline bool check(ll x,ll y)
{return (x%d==0)&&(y%d==0);}
int main()
{
  scanf("%lld",&T);
  while(T--){
    ll a,b,x,y;
    scanf("%lld%lld%lld%lld",&a,&b,&x,&y);
    d=gcd(a,b)<<1;a%=d,b%=d,x%=d,y%=d;
    if(check(x,y)||check(x+a,y+b)||check(x+b,y+a)||check(x+a+b,y+a+b))
      printf("Y
");
    else printf("N
");
  }
  return 0;
}
原文地址:https://www.cnblogs.com/cytus/p/8424267.html