拓展欧几里得和裴蜀定理

        裴蜀定理(或贝祖定理)说明了对任何整数a、b和它们的最大公约数d,关于未知数x和y的线性不定方程(称为裴蜀等式):若a,b是整数,且gcd(a,b)=d,那么对于任意的整数x,y,ax+by都一定是d的倍数,特别地,一定存在整数x,y,使ax+by=d成立。

        也就是说a和b能凑出来的最小正整数就是它们的最大公约数,它的一个重要推论是:a,b互质充分必要条件是存在整数x,y使ax+by=1,只有a和b互质的时候才能取到等于1.

        如果从0开始每次走a步,超过b位置就模b,可能到的位置p就是ax+by=p,p是gcd(a,b)的倍数。

        ax + by = m,有解当且仅当m是d的倍数。裴蜀等式有解时必然有无穷多个整数解。

        推导:

        ax+by=gcd(a,b),在exgcd的结束条件中b等于0,此时ax+0*y=gcd(a,0)=a,所以x=1,此时的y可以取任意值,我们可以取为0.

        

int exgcd(int a,int b,int &x,int &y){
	if(b==0){
		x=1,y=0;
		return a;
	}
	int d=exgcd(b,a%b,y,x);//此时的y就是下一层的x’,x就是下一层的y’
	y-=a/b*x;//x已经是y’,y=x’(就是现在的y)-a/b*y’(就是现在的x)
	return d;
}

//求a在mod下的逆元x
ll getInv(ll a, ll mod){
	ll x, y;
	ll d = exgcd(a, mod, x, y);//只有a和mod互质才有逆元,逆元就是x
	//标记4
	return d == 1 ? (x + mod) % mod : -1;
}

上面只是求了一组ax+by=gcd(a,b)的特解,怎么求其他解:

(x0,y0)是一组特解,由于gcd(a,b)相等,其他解等于这组特解

a’于b’原来有的gcd已经被除掉了,所以gcd只剩1了

结论:ax+by=d的一组特解是(x0,y0),那么通解就是(x0+kb’,y0-ka’),其中a’=a/gcd(a,b),b’=b/gcd(a,b)。

容易知道x0+kb’可以一直加减任意倍的b’,也就是说((x0+kb’)%b’+b’)%b’就是第一次x大于等于0的时候,也就是说最小非负整数解x就是((x0+kb’)%b’+b’)%b’

题目链接

思路:

        题目等价于求cx+py+a=b(p=2^k)的最小正整数解,即cx+py=b-a的最小正整数解

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int inf=0x3f3f3f3f;
const int N=1e5+10;
const int mod=1e9+7;
#define fi first
#define se second
#define int ll
int exgcd(int a,int b,int &x,int &y){
	if(b==0){
		x=1,y=0;
		return a;
	}
	int d=exgcd(b,a%b,y,x);
	y-=a/b*x;
	return d;
}
int qpow(int a,int b){
	int res=1;
	while(b){
		if(b&1) res=res*a;
		b>>=1;
		a=a*a;
	}
	return res;
}
void solve(){
	int a,b,c,k;
	while(cin>>a>>b>>c>>k,a||b||c||k){
		int x0,y0;
		int n=qpow(2,k);
		int d=exgcd(c,n,x0,y0);
		if((b-a)%d){
			cout<<"FOREVER"<<endl;
			continue;
		}
		int t=n/d;
		int x1=x0*(b-a)/d;
		cout<<(x1%t+t)%t<<endl;
	}
}
signed main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t=1;
	//cin>>t;
	while(t--){
		solve();
	}
	return 0;
}

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值