POJ 2115(线性同余方程)

怎样求解线性同余方程可看下方


本题要求(b-a)%(2^k)=(cx)%(2^k)   -2^k< b-a<2^k   的x的最小正整数解


解方程 ax=b (mod n)



#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
long long a,b,c,k,x,y; // (b-a)%(2^k)=(cx)%(2^k) -2^k<b-a<2^k
long long shl(long long p,long long k)
{
	k--;
	while (k)
	{
		p*=2;
		k--;
	}
	return p;
	
}
long long exgcd(long long a,long long b)
{
	if (b==0) 
	{
		x=1;
		y=0;
		return a;
	}

	long long ans=exgcd(b,a%b);
	long long x1=y;
	long long y1=x-(a/b)*y;
	x=x1;
	y=y1;
	return ans;
	
}
long long modular(long long a,long long b,long long n)
{
	
	long long d=exgcd(a,n);
	if (b%d) return -1;
	long long x0=x*(b/d) % n;
	/*
		d=ax(mod n)
		d*(b/d)=ax(b/d) (mod n)
		设x(b/d)=x0
		则 b=a*x0 (mod n) 
		因 b=a*(x0+t*(n/d) )=a*x0+ a*n/d =[a*x0+(a/d)*n] (mod n)=a*x0 (mod n)
		-> 求 [x0+t*(n/d)]min>0
		 t==d -> (x0+n) mod n -> 正数解
				 (x0+n) mod n -k(n/d)>0   k->max 
				 (x0+n) mod n mod (n/d) =(x0+n) mod (n/d)
	*/		
//	cout<<x0<<' '<<n/d<<endl;
	return (x0+n)%(n/d);
}
//long long 

int main()
{
	while (scanf("%d%d%d%d",&a,&b,&c,&k)!=EOF )
	{
		/// << -> long long's case 
		 /*
		long long p=1LL<<32;
		long long m=((long long)1<<32);
		cout<<p<<' '<<m<<endl;
		*/
		if (a==0&&b==0&&c==0&&k==0) break;   //(b-a)%(2^k)=(cx)%(2^k) b-a<2^k
		long long p2_k=shl(2,k);
		long long ans=modular(c,(b-a+p2_k)%(p2_k),p2_k);
		if (ans==-1) cout<<"FOREVER\n";
		else cout<<ans<<endl;
	}
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值