zoukankan      html  css  js  c++  java
  • 【HAOI2011】 向量

    数论好劲啊

    原题:

    给你一对数a,b,你可以任意使用(a,b), (a,-b), (-a,b), (-a,-b), (b,a), (b,-a), (-b,a), (-b,-a)这些向量,问你能不能拼出另一个向量(x,y)。
    说明:这里的拼就是使得你选出的向量之和为(x,y)

    t<=50000,-2*10^9<=a,b,x,y<=2*10^9

    这题我自己想出了思路,但是怎么都WA,最后膜拜lzx的题解才A

    首先其实向量只有四个,比如(a,b)和(-a,-b)是一个东西

    然后就可以列出酱紫的方程:

    a(x1+x2)+b(y1+y2)=x

    b(x1-x2)+b(y1-y2)=y

    如果想要有解,首先要保证两个方程分别有解,这个根据扩展欧几里得的性质判断(c%gcd(a,b)!=0时ax+by=c有解)

    然后还要满足解出来的(x1+x2),(y1+y2),(x1-x2),(y1-y2)能够解出整数解x1,x2,y1,y2

    设x1+x2=e,x1-x2=f,e+f=2*x1,所以当e+f为偶数时有解,y同理

    exgcd搞一下判断即可

    然后有个问题就是exgcd解出来的答案可能满足条件,但是对这个答案进行一些调整依旧满足条件但是奇偶性变了

    调整最多就是x或y加减a或b,总共四种情况,都不能满足偶数条件的时候就无解了

    注意longlong

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<vector>
     7 using namespace std;
     8 #define ll long long
     9 ll rd(){int z=0,mk=1;  char ch=getchar();
    10     while(ch<'0'||ch>'9'){if(ch=='-')mk=-1;  ch=getchar();}
    11     while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0';  ch=getchar();}
    12     return z*mk;
    13 }
    14 ll gcd(ll x,ll y){  return y?gcd(y,x%y):x;}
    15 void exgcd(ll a,ll b,ll &x,ll &y){
    16     if(!b){  x=1,y=0;  return ;}
    17     exgcd(b,a%b,x,y);
    18     ll c=x;  x=y,y=c-a/b*x;
    19 }
    20 int n;
    21 char chck(ll x1,ll y1,ll x2,ll y2,ll a,ll b){
    22     if(!((x1+x2)&1) && !((y1+y2)&1))  return 'Y';
    23     x1+=b,y1-=a;
    24     if(!((x1+x2)&1) && !((y1+y2)&1))  return 'Y';
    25     x2+=a,y2-=b;
    26     if(!((x1+x2)&1) && !((y1+y2)&1))  return 'Y';
    27     x1+=b,y1-=a;
    28     if(!((x1+x2)&1) && !((y1+y2)&1))  return 'Y';
    29     return 'N';
    30 }
    31 int main(){//freopen("ddd.in","r",stdin);
    32     cin>>n;
    33     ll a,b,x,y;
    34     ll x1,x2,y1,y2,ggcd;
    35     while(n--){
    36         a=rd(),b=rd(),x=rd(),y=rd();
    37         exgcd(a,b,x1,y1),exgcd(a,b,y2,x2);
    38         ggcd=gcd(a,b);
    39         if(x%ggcd || y%ggcd)  printf("N
    ");
    40         else  printf("%c
    ",chck(x1*x/ggcd,y1*x/ggcd,x2*y/ggcd,y2*y/ggcd,a/ggcd,b/ggcd));
    41         //if(((x1*x+x2*y)/ggcd)&1 || ((y1*x+y2*y)/ggcd)&1)  printf("N
    ");
    42         //else  printf("Y
    ");
    43     }
    44     return 0;
    45 }
    View Code
  • 相关阅读:
    POJ 1637:Sightseeing tour
    bzoj 3997: [TJOI2015]组合数学
    [CEOI2008]order
    【网络流24题】星际转移问题
    Codeforces Round #460 D. Karen and Cards
    bzoj 3142: [Hnoi2013]数列
    codeforces586B
    codeforces631B
    codeforces548B
    codeforces515B
  • 原文地址:https://www.cnblogs.com/JSL2018/p/6446172.html
Copyright © 2011-2022 走看看