方程的解 扩展欧几里德

  题面加密

  首先看到这道题就能想到用exgcd,但是怎么用,我们知道这种方程一有就是一堆解,那么这个题的限制就是解的个数,我们考虑如果把方程移项化简就能得到$y=\frac{c}{b}-\frac{a}{b}*x$,这时候就用到义务教育的知识了,当a,b异号那么一定同增,如果exgcd有解,一定是无限组,直接判掉。我们考虑ab同号,那么我们可以得到一定是过第一象限的递减直线,我们对方程做如下操作$a(x-b)+b(y+a)=c$,显然也是成立的,此时ab都可以化成正号,那么x减小则y增加,我们可以将x对b取模得到y的最大解,再将y对a取模得到y最小解,然后y的变换一定是一个等差数列,公差为a,则y的范围可以求,命题得解(好装X的话)。

  然后特判一下就A了,快读记得打负号


  

#include<iostream>
#include<cstdio>
#define ll long long
using namespace std;
ll rd()
{
    ll s=0,w=1;
    char cc=getchar();
    while(cc<'0'||cc>'9') {if(cc=='-') w=-1;cc=getchar();}
    while(cc>='0'&&cc<='9') s=(s<<3)+(s<<1)+cc-'0',cc=getchar();
    return s*w;
}
ll exgcd(ll a,ll b,ll &x,ll &y,ll c)
{
    if(b==0){x=c/a;y=0;return a;}
    ll d=exgcd(b,a%b,y,x,c);
    y-=a/b*x;
    return d;
}
int main()
{
//    freopen("data.in","r",stdin);
    //freopen("data.ans","w",stdout);
    ll T=rd(),a,b,c,x,y,g,ans;
    while(T--)
    {
        a=rd(),b=rd(),c=rd();
        //cout<<a<<" "<<b<<endl;
        if(!a&&!b)
        {
            if(!c)printf("ZenMeZheMeDuo\n");
            else printf("0\n");
            continue;
        }
        if(a<0&&b<0) a=-a,b=-b,c=-c;
        g=exgcd(a,b,x,y,c);
        if(c%g){puts("0");continue;}
        if(a==0)
        {
            if((b<=0&&c>=0)||(b>=0&&c<=0))printf("0\n");
            else printf("ZenMeZheMeDuo\n");
            continue;
        }
        if(b==0)
        {
            if((a<=0&&c>=0)||(a>=0&&c<=0))printf("0\n");
            else printf("ZenMeZheMeDuo\n");
            continue;
        }
        if(a*b<0)
        {
            printf("ZenMeZheMeDuo\n");
            continue;
        }
        if(a<0&&b<0)a=-a,b=-b,c=-c;
        a/=g;b/=g;c/=g;x%=b;
        while(x<=0)x+=b;
        y=(c-a*x)/b;
        ll ymin=y%a;while(ymin<=0)ymin+=a;
        if(ymin>y)ans=0;
        else ans=(y-ymin)/a+1;
        if(ans>65535)printf("ZenMeZheMeDuo\n");
        else printf("%lld\n",ans);
    }
}
/*
g++ 6.cpp -o 6
./6
4
1 -1 3
1 1 65536
1 1 65537
2 3 24
*/
View Code

猜你喜欢

转载自www.cnblogs.com/starsing/p/11235533.html