poj 2115 C Looooops

// 题意: 解同余方程 Cx≡B-A ( mod 2^k ) ,求出x的最小解

#include<iostream>
#include <math.h>
using namespace std;
long long x_0,y_0,q;
void extend_eulid(long long a,long long b) //x_0*a+y_0*b=gcd(a,b)=q
{

if(b==0)
{
x_0=1;y_0=0;q=a;
}
else
{
extend_eulid(b,a%b);
int temp=x_0;
x_0=y_0;y_0=temp-a/b*y_0;
}
}
// 解同余方程 Cx≡B-A ( mod 2^k ) , 相当于ax≡n (mod b),即 a=C , n=B-A , b=2^k
int main()

{
long long A,B,C,k,x;
while(cin>>A>>B>>C>>k&&k)
{
extend_eulid(C,pow(2.0,double(k)));
if( (B-A)%q != 0 )
cout<<"FOREVER\n";
else
{
x = x_0*(B-A)/q;
long long ff=pow(2.0,double(k))/q;
long long X=(x%ff+ff)%ff;
cout<<X<<endl;
}
}
return 0;
}

/*
形如 ax≡n (mod b),可化成 ax + by = n, x有整数解的充分必要条件是 n % (a,b)==0,(a,b)表示gcd(a,b)
方程 a*x+b*y=n;我们可以先用扩展欧几里德算法求出一组x_0,y_0。
也就是 a * x_0 + b * y_0 =(a,b);
然后两边同时除以(a,b),再乘以n。
这样就得到了方程 a * x_0 * n/(a,b)+ b * y_0 * n/(a,b)= n;
方程的一个解: x = x_0 * n/(a,b), y = y_0 * n/(a,b)
其他的解都为 x_1,2...≡x+(b/(a,b))*i , y_1,2...≡y-(a/(a,b))*i (0 <=i<=(a,b)-1)。 i=0 时即为上面的一组解
总共有gcd(a,b)组解

令ff=b/(a,b),则x的最小非负整数解为 x = x_0 * n/(a,b), X = ( x % ff + ff ) % ff ;
*/

posted on 2011-07-18 00:03  sysu_mjc  阅读(176)  评论(0编辑  收藏  举报

导航