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<<"FOREVERn";
		else cout<<ans<<endl;
	}
	return 0;
}