Solutions to equations (extended Euclidean)

Keywords: PHP

Originally thought this question would hang up the result, this question was a little bit watery...

First of all, by the nature of the data and the violence, we get a happy 60.

As for the positive solution QAQ

Then you have to associate a simple but not commonly used knowledge.

*******************************************

Expand Euclidean:

First ax+by=gcd(x,y); this is obvious.

Then the equation is equivalent to bx+(a%b)y=gcd(a,b);

We want to find that if the last a%b==0, x=1, y=0 returns.

We need to find the x,y of that layer in the backtrace.

So let's set x'y back to y'.

B x'+(a%b)y'=gcd(a,b) can be sorted as a y'+b(x'-a/b*y')=gcd(a,b);

Does this resemble the initial pattern?

To find out x and y, we set the number z to prevent the value of x from being modified.

z=x,x=y;y=z-a/b*y;

Code:

 

 1 void exgcd(ll a,ll b,ll &x,ll &y)
 2 {
 3    if(b==0)
 4    {
 5         x=1;y=0;return ;
 6    }
 7    exgcd(b,a%b,x,y);
 8    ll z=x;x=y;y=z-(a/b)*y;
 9    return ;
10 }

******************************************

Positive solution:

1. (I pushed it myself, it's a little troublesome, I suggest you take a look at the next one)

First we can get a general solution, x=c/d*x0+k*b/d; (x0 is the exgcd solution, D is the gcd solution) where k is a variable and can be added or subtracted.

So the corresponding y can also be a value, we know x>0 &&y>0 so we can use this to find inequality relationships

Notice that the inequality relationship is originally four equations, but because of the size relationship between x0 and y0, it shrinks to two.

In this case, the value range of k, that is, the value range of x, y, kmax-kmin is the result.

 

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<string>
  5 #include<algorithm>
  6 #include<cmath>
  7 #include<stack>
  8 #include<vector>
  9 #include<queue>
 10 #include<bits/stdc++.h>
 11 #define MAXN 401
 12 #define ps push_back
 13 #define ll long long
 14 using namespace std;
 15 ll aa,bb,cc;
 16 ll T;
 17 void exgcd(ll a,ll b,ll &x,ll &y)
 18 {
 19    if(b==0)
 20    {
 21         x=1;y=0;return ;
 22    }
 23    exgcd(b,a%b,x,y);
 24    ll z=x;x=y;y=z-(a/b)*y;
 25    return ;
 26 }
 27 ll gcd(ll a,ll b)
 28 {
 29   return (b!=0)?gcd(b,a%b):a;
 30 }
 31 int main()
 32 {
 33    //freopen("text.in","r",stdin);
 34    //freopen("wa.out","w",stdout);
 35    scanf("%lld",&T);
 36    while(T--)
 37    {
 38       scanf("%lld%lld%lld",&aa,&bb,&cc);
 39       if(aa<=0&&bb<=0){aa=-aa;bb=-bb;cc=-cc;}
 40       if(bb==0)
 41       { 
 42           if(cc%aa!=0)
 43           {
 44              printf("0\n");
 45              continue;
 46           }
 47           else if((aa<=0&&cc>=0)||(aa>=0&&cc<=0))
 48           {
 49                 printf("0\n");
 50                 continue;
 51           }
 52           else printf("ZenMeZheMeDuo\n");
 53           continue;
 54       }
 55       if(aa==0)
 56       {
 57           if(cc%bb!=0)
 58           {
 59             printf("0\n");
 60             continue;
 61           }
 62           else if((bb<=0&&cc>=0)||(bb>=0&&cc<=0))
 63           {
 64                 printf("0\n");
 65                 continue;
 66           }
 67           else printf("ZenMeZheMeDuo\n");
 68           continue;
 69       }
 70       ll x1=0,y1=0,x2=0,y2=0;
 71       double k=0,h=0;
 72       ll gcdd=gcd(abs(aa),abs(bb));
 73       ll gg=cc/gcdd;
 74       if(abs(cc)%abs(gcdd)!=0)
 75       {
 76            printf("0\n");
 77            continue;
 78       }
 79       if((aa<0&&bb>0)||(aa>0&&bb<0))
 80       {
 81           printf("ZenMeZheMeDuo\n");
 82           continue;
 83       }
 84       exgcd(aa,bb,x1,y1);
 85       k=(double)(y2-y1)/(x2-x1);
 86       if(k>0)
 87       {
 88           printf("ZenMeZheMeDuo\n");
 89           continue; 
 90       }
 91       ll r1=100000000,r2=100000000,l1=0,l2=0;
 92       ll kx1=(cc/gcdd)*x1;ll kx2=(cc/gcdd)*y1;
 93       ll base1=(bb/gcdd);ll base2=(aa/gcdd);
 94       //printf("kx1+%lld k2=%lld base1=%lld base2=%lld\n",kx1,kx2,base1,base2);
 95       if(x1>0)
 96       {
 97           if(kx1%base1==0)
 98           r1=kx1/base1-1;
 99           else r1=kx1/base1;
100       }
101       if(y1>0)
102       {
103           if(kx2%base2==0)
104           r2=kx2/base2-1;
105           else r2=kx2/base2;
106       }
107       if(x1<=0)l1=(-kx1)/base1+1;
108       if(y1<=0)l2=(-kx2)/base2+1;
109       ll l=max(l1,l2);ll r=min(r1,r2);
110       //printf("l=%lld r=%lld\n",l,r);
111       //printf("l1=%lld l2=%lld r1=%lld r2=%lld\n",l1,l2,r1,r2);
112       if(r-l<0)
113       {
114          printf("0\n");
115          continue;
116       }
117       else 
118       {
119           if(r-l+1>65535)
120           {
121              printf("ZenMeZheMeDuo\n");
122           }
123           else
124             printf("%lld\n",r-l+1);
125       }
126    }
127 }

 

 

 

2. (Referring to zzn's practice, it's essentially similar)

x=c/d*x0+k*b/d; invariant equation

Let's first multiply x0 and Y0 by c/d; that's what x and y are in ax+by=c

It is easy to see that every time x increases b and y decreases an equal amount a, the result is unchanged, so we can have a pleasant deletion of A.

Now x%b (to prevent x from becoming too large) yields ymax when x>=1 y=(c-ax)/b;

Then y%a, the min of y>=1 is obtained.

(If y<0||x<0 corresponds to++ a,++b first)

So we get the range of Y and know that y increases a*k each time

So make (ymax-ymin)/a the result

 

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<string>
  5 #include<algorithm>
  6 #include<cmath>
  7 #include<stack>
  8 #include<vector>
  9 #include<queue>
 10 #include<bits/stdc++.h>
 11 #define MAXN 401
 12 #define ps push_back
 13 #define ll long long
 14 using namespace std;
 15 ll aa,bb,cc;
 16 ll T;
 17 void exgcd(ll a,ll b,ll &x,ll &y)
 18 {
 19    if(b==0)
 20    {
 21         x=1;y=0;return ;
 22    }
 23    exgcd(b,a%b,x,y);
 24    ll z=x;x=y;y=z-(a/b)*y;
 25    return ;
 26 }
 27 ll gcd(ll a,ll b)
 28 {
 29   return (b!=0)?gcd(b,a%b):a;
 30 }
 31 ll work1(ll x,ll y,ll z)
 32 {
 33     if(x!=y)return 0;
 34     if(x!=1)return 0;
 35     if(z<=0)
 36     {
 37         printf("0\n");
 38         return 1;
 39     }
 40     else 
 41     {
 42         if((z-1)>65535)
 43         {
 44             printf("ZenMeZheMeDuo\n");
 45             return 1;
 46         }
 47         else
 48         {
 49             printf("%lld\n",z-1);
 50             return 1;
 51         }
 52     }
 53 }
 54 int main()
 55 {
 56    //freopen("text.in","r",stdin);
 57    //freopen("wa.out","w",stdout);
 58    scanf("%lld",&T);
 59    while(T--)
 60    {
 61       scanf("%lld%lld%lld",&aa,&bb,&cc);
 62       if(aa<0&&bb<0)
 63       {
 64            aa-=2*aa;bb-=2*bb;cc-=2*cc;
 65            if(cc<aa+bb)
 66            {
 67               printf("0\n");
 68               continue;
 69            }
 70       }
 71       if(aa>=0&&bb>=0)
 72       {
 73           if(cc<aa+bb)
 74           {
 75               printf("0\n");
 76               continue;
 77           }
 78       }
 79       if(work1(aa,bb,cc)==1)
 80       {
 81            continue;
 82       }
 83       if(aa+bb==cc&&aa>0&&bb>0)
 84       {
 85          printf("1\n");
 86          continue;
 87       }
 88       if(aa<bb)swap(bb,aa);
 89       if(aa*bb>0)
 90       {
 91          if(cc==0)
 92          {
 93              printf("0\n");
 94              continue;
 95          }
 96       }
 97       if(aa==0&&bb==0&&cc==0)
 98       {
 99            printf("ZenMeZheMeDuo\n");
100            continue;
101       }
102       if(aa==0&&bb==0)
103       {
104          printf("0\n");
105          continue;
106       }
107       if(bb==0)
108       { 
109           if(cc%aa!=0)
110           {
111              printf("0\n");
112              continue;
113           }
114           else if((aa<=0&&cc>=0)||(aa>=0&&cc<=0))
115           {
116                 printf("0\n");
117                 continue;
118           }
119           else printf("ZenMeZheMeDuo\n");
120           continue;
121       }
122       if(aa==0)
123       {
124           if(cc%bb!=0)
125           {
126             printf("0\n");
127             continue;
128           }
129           else if((bb<=0&&cc>=0)||(bb>=0&&cc<=0))
130           {
131                 printf("0\n");
132                 continue;
133           }
134           else printf("ZenMeZheMeDuo\n");
135           continue;
136       }
137       ll gcdd=gcd(abs(aa),abs(bb));
138       ll gg=cc/gcdd;
139       if(abs(cc)%abs(gcdd)!=0)
140       {
141            printf("0\n");
142            continue;
143       }
144       if((aa<0&&bb>0)||(aa>0&&bb<0))
145       {
146           printf("ZenMeZheMeDuo\n");
147           continue;
148       }
149       ll x1=0,y1=0;
150       exgcd(aa,bb,x1,y1);
151       ll ans=0;
152       x1*=cc/gcdd;y1*=cc/gcdd;
153       aa/=gcdd,bb/=gcdd,cc/=gcdd;x1%=bb;
154       while(x1<=0) x1+=bb;
155       y1=(cc-aa*x1)/bb;
156       ll y2=y1%aa;
157       while(y2<=0) y2+=aa;
158       ans=(y1-y2)/aa+1;
159       if(y2>y1) ans=0;
160       if(ans<=65535)
161             printf("%lld\n",ans);
162       else
163             printf("ZenMeZheMeDuo\n");
164    }
165 }
166 /*
167 11
168 -1733561 -7985280 -4117480 
169 1553555 3269642 9835368 
170 */

Posted by NiteCloak on Mon, 22 Jul 2019 15:43:34 -0700