#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
ll a,b,c,k;
ll exgcd(ll a,ll p,ll& x,ll& y){//a*x+p*y=gcd(a,p)
if(!p){
y=0,x=1;return a;
}
ll res= exgcd(p,a%p,x,y);
int temp=y;
y=x-a/p*y;
x=temp;
return res;
}
int main(){
//a*x+p*y=b-a =k(gcd(a,p))就有解,令 a*x+p*y=gcd(a,p)求出特殊解x0后
//x=x*(b-a)/gcd(a,p) ,相当于之前等式两边同除k,k= (b-a)/gcd(a,p)
while(cin>>a>>b>>c>>k){
if(!a&&!b&&!c&&!k)break;
ll p=(ll)1<<k;//ll p=pow(2,k)
ll x,y;//不用初始化,递归是走到递归出口为xy赋了初值再回溯求出
// 上一层的……直到p,a%p->a,p这最后一层的x,y
ll res=exgcd(c,p,x,y); //cx=b-a
ll mod=p/res; //x的最小整数解距离
if((b-a)%res==0)cout<<((x*ll(b-a)/res%mod)+mod)%mod<<endl;//防止负数或者说是求最小正整数解
else cout<<"FOREVER"<<endl;
}
return 0;
}
P1516 青蛙的约会
青蛙的约会
裸exgcd题,但是不要忘记 gcd求最大公因数只对正整数有效噢,提前判断一哈
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
ll exgcd(ll a,ll p,ll& x,ll& y){
if(!p){
x=1;y=0;return a;
}
ll res=exgcd(p,a%p,x,y);
int temp=y;
y=x-a/p*y;
x=temp;
return res;
}
int main(){
ll xx,yy,m,n,L;//(m-n)*x=yy-xx
cin>>xx>>yy>>m>>n>>L;
ll d=yy-xx;
ll x,y;
ll a=m-n;
if(a<0){
a=-a;
d=-d;
}
ll res=exgcd(a,L,x,y);
ll k=d%res;
ll mop=L/res;
if(k==0)cout<<((x*d/res)%mop+mop)%mop;
else cout<<"Impossible";
return 0;
}